package cmd import ( "fmt" "io/ioutil" "os" "os/exec" "strings" "github.com/fatih/color" "github.com/spf13/cobra" "git.ctrlz.es/mgdelacroix/campaigner/app" ) const defaultEditor = "vim" func ListLabelCmd() *cobra.Command { return &cobra.Command{ Use: "list", Short: "List the local campaign labels", Args: cobra.NoArgs, Run: withApp(listLabelCmdF), } } func RemoteLabelCmd() *cobra.Command { return &cobra.Command{ Use: "remote", Short: "List all the GitHub repository labels", Args: cobra.NoArgs, Run: withApp(remoteLabelCmdF), } } func UpdateLabelCmd() *cobra.Command { cmd := &cobra.Command{ Use: "update", Short: "Updates the campaign's GitHub labels", Args: cobra.NoArgs, Run: withApp(updateLabelCmdF), } cmd.Flags().BoolP("skip-check", "s", false, "do not check if the labels exist in the remote repository") return cmd } func LabelCmd() *cobra.Command { cmd := &cobra.Command{ Use: "label", Short: "Commands to manage GitHub labels", } cmd.AddCommand( ListLabelCmd(), RemoteLabelCmd(), UpdateLabelCmd(), ) return cmd } func listLabelCmdF(a *app.App, cmd *cobra.Command, _ []string) { for _, label := range a.Campaign.Github.Labels { fmt.Println(label) } } func remoteLabelCmdF(a *app.App, cmd *cobra.Command, _ []string) { labels, err := a.ListLabels() if err != nil { ErrorAndExit(cmd, fmt.Errorf("cannot retrieve labels list: %w", err)) } fmt.Printf("Labels for repository %s:\n\n", color.GreenString(a.Campaign.Github.Repo)) for _, label := range labels { fmt.Println(label) } } func updateLabelCmdF(a *app.App, cmd *cobra.Command, _ []string) { skipCheck, _ := cmd.Flags().GetBool("skip-check") file, err := ioutil.TempFile(os.TempDir(), "campaigner-") if err != nil { ErrorAndExit(cmd, fmt.Errorf("cannot create temp file: %w", err)) } defer func() { file.Close() os.Remove(file.Name()) }() labelBytes := []byte(strings.Join(a.Campaign.Github.Labels, "\n")) if _, err := file.Write(labelBytes); err != nil { ErrorAndExit(cmd, fmt.Errorf("cannot write labels to temp file: %w", err)) } editor := os.Getenv("EDITOR") if editor == "" { editor = defaultEditor } editorCmd := exec.Command(editor, file.Name()) editorCmd.Stdout = cmd.OutOrStdout() editorCmd.Stdin = cmd.InOrStdin() editorCmd.Stderr = cmd.ErrOrStderr() if err := editorCmd.Run(); err != nil { ErrorAndExit(cmd, fmt.Errorf("cannot run editor command: %w", err)) } newLabelBytes, err := ioutil.ReadFile(file.Name()) if err != nil { ErrorAndExit(cmd, fmt.Errorf("cannot read file: %w", err)) } newLabels := []string{} for _, label := range strings.Split(string(newLabelBytes), "\n") { if label != "" { newLabels = append(newLabels, strings.TrimSpace(label)) } } if !skipCheck { ok, badLabels, err := a.CheckLabels(newLabels) if err != nil { ErrorAndExit(cmd, fmt.Errorf("cannot check new labels list: %w", err)) } if !ok { ErrorAndExit(cmd, fmt.Errorf("these labels doesn't exist in the repository:\n\n%s", strings.Join(badLabels, "\n"))) } } a.Campaign.Github.Labels = newLabels if err := a.Save(); err != nil { ErrorAndExit(cmd, fmt.Errorf("cannot save campaign: %w", err)) } cmd.Println("Labels successfully updated") }