// Main entry point for running fixr subcommand. func runFixr(cmd *cobra.Command, args []string) { if len(args) < 1 { log.Fatalf("Must provide at least one directory argument to fixr.") } var files []fileInfo for _, dir := range args { fl, err := ioutil.ReadDir(dir) if err != nil { log.Fatalf("Failed to read directory '%v' with error %v\n", dir, err) } for _, f := range fl { if match, _ := regexp.MatchString("\\.json$", f.Name()); match && !f.IsDir() { files = append(files, fileInfo{d: dir, f: f}) } } } if cmd.Flags().Lookup("prompt").Changed { runFixrInteractive(cmd, files) } else { runFixrBatch(cmd, files) } }
func githubIngestor(c client, cmd *cobra.Command) http.HandlerFunc { gho := cmd.Flags().Lookup("github-oauth").Value.String() return func(w http.ResponseWriter, r *http.Request) { defer r.Body.Close() // TODO this is all pretty sloppy bod, err := ioutil.ReadAll(r.Body) if err != nil { // Too long, or otherwise malformed request body w.WriteHeader(400) w.Write([]byte(err.Error())) return } gpe := githubPushEvent{} err = json.Unmarshal(bod, &gpe) if err != nil { w.WriteHeader(400) w.Write([]byte(err.Error())) return } err = c.send(gpe.ToMessage(gho)) if err != nil { w.WriteHeader(502) // 502, bad gateway } else { // tell github it's all OK w.WriteHeader(202) } } }
func runDotDumper(cmd *cobra.Command, args []string) { g := represent.NewGraph() raw, err := schema.Master() if err != nil { panic(fmt.Sprint("Failed to open master schema file, test must abort. message:", err.Error())) } schemaMaster, err := gjs.NewSchema(gjs.NewStringLoader(string(raw))) if err != nil { panic("bad schema...?") } if len(args) < 1 { log.Fatalf("Must provide at least one directory argument to dotdumper.") } var k uint64 = 0 for _, dir := range args { fl, err := ioutil.ReadDir(dir) if err != nil { erro.Printf("Failed to read directory '%v' with error %v\n", dir, err) } for _, f := range fl { if match, _ := regexp.MatchString("\\.json$", f.Name()); match && !f.IsDir() { src, err := ioutil.ReadFile(dir + "/" + f.Name()) if err != nil { erro.Printf("Failed to read fixture file %v/%v\n", dir, f.Name()) continue } result, err := schemaMaster.Validate(gjs.NewStringLoader(string(src))) if err != nil { erro.Printf("Validation process terminated with errors for %v/%v. Error: \n%v\n", dir, f.Name(), err.Error()) continue } if !result.Valid() { for _, desc := range result.Errors() { erro.Printf("\t%s\n", desc) } } else { k++ m := ingest.Message{} json.Unmarshal(src, &m) g = g.Merge(k, m.UnificationForm()) fmt.Printf("Merged message %v/%v into graph\n", dir, f.Name()) } } } } pathflag := cmd.Flags().Lookup("output") if pathflag.Changed { ioutil.WriteFile(pathflag.Value.String(), GenerateDot(g), 0644) } else { fmt.Println(string(GenerateDot(g))) } }
// Performs the fixr run with user interaction, confirming for each message. func runFixrInteractive(cmd *cobra.Command, files []fileInfo) { client := http.Client{Timeout: 5 * time.Second} FileLoop: for k, f := range files { src, err := ioutil.ReadFile(f.d + "/" + f.f.Name()) if err != nil { erro.Printf("Failed to read file '%v/%v' with error %v\n", f.d, f.f.Name(), err) continue } fmt.Printf("\nMessage #%v (%v/%v) contents:\n%s", k+1, f.d, f.f.Name(), src) for { fmt.Printf("Message #%v: (S)end, s(k)ip, or (q)uit? ", k+1) reader := bufio.NewReader(os.Stdin) raw, err := reader.ReadString('\n') if err != nil { erro.Fatalf("Bad input, terminating fixr\n") } input := strings.Split(strings.Trim(raw, " \n"), " ") if len(input) < 1 { erro.Fatalf("TODO huh how would this happen\n") } switch input[0] { case "k", "skip": continue FileLoop case "", "s", "send": resp, err := client.Post(cmd.Flags().Lookup("target").Value.String(), "application/json", bytes.NewReader(src)) fmt.Printf("Sending %v/%v...", f.d, f.f.Name()) if err != nil { log.Fatalf(err.Error()) } bod, err := ioutil.ReadAll(resp.Body) if err != nil { erro.Println(err) } resp.Body.Close() fmt.Printf("%v, msgid %v\n", resp.StatusCode, string(bod)) continue FileLoop case "q", "quit": fmt.Printf("Quitting...\n") os.Exit(1) } } } }
// Performs the fixr run in a batch, sending all fixtures found immediately and without confirmation. func runFixrBatch(cmd *cobra.Command, files []fileInfo) { client := http.Client{Timeout: 5 * time.Second} for _, f := range files { src, err := ioutil.ReadFile(f.d + "/" + f.f.Name()) if err != nil { erro.Printf("Failed to read file '%v/%v' with error %v\n", f.d, f.f.Name(), err) continue } resp, err := client.Post(cmd.Flags().Lookup("target").Value.String(), "application/json", bytes.NewReader(src)) fmt.Printf("Sending %v/%v...", f.d, f.f.Name()) if err != nil { log.Fatalln(err) } bod, err := ioutil.ReadAll(resp.Body) if err != nil { erro.Println(err) } resp.Body.Close() fmt.Printf("%v, msgid %v\n", resp.StatusCode, string(bod)) } }
// runGenLS is the main entry point for running the logic state-generating // ls subcommand. func (lsc lsCmd) runGenLS(cmd *cobra.Command, args []string) { ls := &semantic.LogicState{} if !cmd.Flags().Lookup("no-detect").Changed { *ls = lsc.detectDefaults() } // Write directly to stdout, at least for now w := os.Stdout // Prep schema to validate the messages as we go raw, err := schema.Master() if err != nil { fmt.Fprintln(w, "WARNING: Failed to open master schema file; pvc cannot validate outgoing messages.") } schemaMaster, err = gjs.NewSchema(gjs.NewStringLoader(string(raw))) if err != nil { panic("bad schema...?") } client := http.Client{Timeout: 5 * time.Second} fmt.Fprintln(w, "Generating a logic state message...") reader := bufio.NewReader(os.Stdin) MenuLoop: for { fmt.Fprintf(w, "\n") lsc.printCurrentState(w, *ls) var input string for { fmt.Fprintf(w, "\nSelect a value to edit by number, (p)rint current JSON message, (s)end, or (q)uit: ") l, err := fmt.Fscanln(reader, &input) if l > 1 || err != nil { continue } switch input { case "q", "quit": fmt.Fprintf(w, "\nQuitting; message was not sent\n") os.Exit(1) case "s", "send": msg, err := toJSONBytes(*ls) if err != nil { log.Fatalf("\nFailed to marshal JSON of logic state object, no message sent\n") } resp, err := client.Post(cmd.Flags().Lookup("target").Value.String(), "application/json", bytes.NewReader(msg)) if err != nil { log.Fatalf(err.Error()) } bod, err := ioutil.ReadAll(resp.Body) resp.Body.Close() if err != nil { log.Fatalf(err.Error()) } if resp.StatusCode >= 200 && resp.StatusCode <= 300 { fmt.Printf("Message accepted (HTTP code %v), msgid %v\n", resp.StatusCode, string(bod)) } else { fmt.Printf("Message was rejected with HTTP code %v and message %v\n", resp.StatusCode, string(bod)) } break MenuLoop case "p", "print": byts, err := toJSONBytes(*ls) if err != nil { fmt.Fprintf(w, "Error while generating JSON for printing: %q", err.Error()) continue MenuLoop } var prettied bytes.Buffer err = json.Indent(&prettied, byts, "", " ") if err != nil { fmt.Fprintf(w, "Error while generating JSON for printing: %q", err.Error()) continue MenuLoop } fmt.Fprintf(w, "\nMessage that will be sent to %s:\n", cmd.Flags().Lookup("target").Value) prettied.WriteTo(w) w.WriteString("\n") default: num, interr := strconv.Atoi(input) if interr != nil { continue } else if 0 < num && num < 10 { switch num { case 1: lsc.collectPath(w, reader, ls) case 2: lsc.collectHostFQDN(w, reader, ls) case 3: lsc.collectHostNick(w, reader, ls) case 4: lsc.collectCommit(w, reader, ls) case 5: lsc.collectVersion(w, reader, ls) case 6: lsc.collectSemver(w, reader, ls) case 7: lsc.collectLgroup(w, reader, ls) case 8: lsc.collectNick(w, reader, ls) case 9: lsc.collectType(w, reader, ls) } continue MenuLoop } else { continue } } } } }