diff --git a/cmd/branch.go b/cmd/branch.go index 511fdf6..0824ae5 100644 --- a/cmd/branch.go +++ b/cmd/branch.go @@ -5,6 +5,7 @@ import ( "errors" "flag" "fmt" + "os" "path/filepath" "strings" @@ -17,6 +18,8 @@ func (h *Handler) Branch() *ffcli.Command { fs.BoolVar(noFetchFlag, "nf", *noFetchFlag, "--no-fetch") baseFlag := fs.String("base", "main", "Ref to base from") fs.StringVar(baseFlag, "b", *baseFlag, "--base") + listFlag := fs.Bool("list", false, "List branches available") + fs.BoolVar(listFlag, "l", *listFlag, "--list") return &ffcli.Command{ Name: "branch", FlagSet: fs, @@ -27,13 +30,27 @@ func (h *Handler) Branch() *ffcli.Command { return err } + if *listFlag { + dirs, err := os.ReadDir(h.Config.Workspace()) + if err != nil { + return err + } + for _, dir := range dirs { + if !dir.IsDir() { + continue + } + fmt.Println(dir.Name()) + } + return nil + } + if len(args) < 1 { return errors.New("branch requires a name") } name := args[0] base := *baseFlag - if !strings.HasPrefix(base, "upstream") { + if !strings.HasPrefix(base, "upstream") && !strings.HasPrefix(base, "pr-") { base = fmt.Sprintf("upstream/%s", base) } diff --git a/cmd/cleanup.go b/cmd/cleanup.go index dc91a78..f581950 100644 --- a/cmd/cleanup.go +++ b/cmd/cleanup.go @@ -4,7 +4,6 @@ import ( "context" "errors" "flag" - "os" "github.com/AlecAivazis/survey/v2" "github.com/peterbourgon/ff/v3/ffcli" @@ -31,19 +30,11 @@ func (h *Handler) Cleanup() *ffcli.Command { return nil } - dirs, err := os.ReadDir(h.Config.Workspace()) + opts, err := h.Config.Branches() if err != nil { return err } - opts := make([]string, 0, len(dirs)) - for _, dir := range dirs { - if !dir.IsDir() { - continue - } - opts = append(opts, dir.Name()) - } - if len(opts) == 0 { return errors.New("no worktrees currently exist") } diff --git a/cmd/cmd.go b/cmd/cmd.go index 1dcbac7..23dd52d 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -48,7 +48,9 @@ func New() (*ffcli.Command, error) { handler.Backport(), handler.Branch(), handler.Frontport(), + handler.IDE(), handler.Init(), + handler.PR(), }, Exec: func(_ context.Context, _ []string) error { if *versionFlag { diff --git a/cmd/ide.go b/cmd/ide.go new file mode 100644 index 0000000..72e55e8 --- /dev/null +++ b/cmd/ide.go @@ -0,0 +1,44 @@ +package cmd + +import ( + "context" + "flag" + "os/exec" + + "github.com/AlecAivazis/survey/v2" + "github.com/peterbourgon/ff/v3/ffcli" +) + +func (h *Handler) IDE() *ffcli.Command { + fs := flag.NewFlagSet("ide", flag.ContinueOnError) + return &ffcli.Command{ + Name: "ide", + FlagSet: fs, + ShortUsage: "ide ", + ShortHelp: "ide starts an IDE for `branch`", + Exec: func(ctx context.Context, args []string) error { + if err := h.checkInit(); err != nil { + return err + } + + var branch string + if len(args) > 0 { + branch = args[0] + } else { + opts, err := h.Config.Branches() + if err != nil { + return err + } + if err := survey.AskOne(&survey.Select{ + Message: "Branch to open", + Options: opts, + }, &branch); err != nil { + return err + } + } + + path := h.Config.WorkspaceBranch(branch) + return exec.Command("goland", path).Start() + }, + } +} diff --git a/cmd/pr.go b/cmd/pr.go new file mode 100644 index 0000000..2e1f092 --- /dev/null +++ b/cmd/pr.go @@ -0,0 +1,47 @@ +package cmd + +import ( + "context" + "errors" + "flag" + "fmt" + + "github.com/peterbourgon/ff/v3/ffcli" +) + +func (h *Handler) PR() *ffcli.Command { + fs := flag.NewFlagSet("pr", flag.ContinueOnError) + ideFlag := fs.Bool("ide", false, "Start an IDE for this PR") + fs.BoolVar(ideFlag, "i", *ideFlag, "--ide") + return &ffcli.Command{ + Name: "pr", + FlagSet: fs, + ShortUsage: "pr ", + ShortHelp: "pr pulls down a pull request for testing", + Exec: func(ctx context.Context, args []string) error { + if err := h.checkInit(); err != nil { + return err + } + + if len(args) == 0 { + return errors.New("pr requires an index") + } + + idx := args[0] + branch := fmt.Sprintf("pr-%s", idx) + if err := h.run(ctx, "git", "fetch", "upstream", fmt.Sprintf("pull/%s/head:%s", idx, branch)); err != nil { + return err + } + + if err := h.Branch().ParseAndRun(ctx, []string{"--base", branch, branch}); err != nil { + return err + } + + if *ideFlag { + return h.IDE().ParseAndRun(ctx, []string{branch}) + } + + return nil + }, + } +} diff --git a/config/config.go b/config/config.go index 80f303c..76d65c4 100644 --- a/config/config.go +++ b/config/config.go @@ -24,6 +24,21 @@ func (c *Config) IsInit() bool { return c.Base != "" } +func (c *Config) Branches() ([]string, error) { + dirs, err := os.ReadDir(c.Workspace()) + if err != nil { + return nil, err + } + branches := make([]string, 0, len(dirs)) + for _, dir := range dirs { + if !dir.IsDir() { + continue + } + branches = append(branches, dir.Name()) + } + return branches, nil +} + func path() (string, error) { userCfgDir, err := os.UserConfigDir() if err != nil {