From 86ccbdfad1801bb7e643d3d81c1d68c9b994d6b9 Mon Sep 17 00:00:00 2001 From: jonnii Date: Thu, 4 Jun 2026 23:10:52 -0400 Subject: [PATCH] refactor(actions): take rename's prompt off the TUI; drop tui from restack Two small, self-contained steps toward keeping interactive/TUI concerns out of the action layer: - rename: RenameAction took the new branch name by calling tui.PromptTextInput directly. Introduce a RenameHandler interface (PromptNewName) that the action calls when no name is given; the CLI command supplies a TUI-backed implementation that also owns the non-interactive guard. The action no longer imports internal/tui. - restack: the only tui use was tui.IsTTY(), which is a pure re-export of utils.IsTTY(). Call utils.IsTTY() directly and drop the tui import. Both are behavior-preserving (verified by lint, cli, and integration suites). These were the only two action files whose tui use was trivially extractable; the rest drive real select/editor/bubbletea UIs and need per-action prompter interfaces. --- internal/actions/rename.go | 19 ++++++++++++------- internal/actions/restack.go | 3 +-- internal/cli/branch/rename.go | 18 +++++++++++++++++- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/internal/actions/rename.go b/internal/actions/rename.go index 5e28f7d81..b62bca66e 100644 --- a/internal/actions/rename.go +++ b/internal/actions/rename.go @@ -6,7 +6,6 @@ import ( "github.com/getstackit/stackit/internal/actions/validation" "github.com/getstackit/stackit/internal/app" "github.com/getstackit/stackit/internal/output" - "github.com/getstackit/stackit/internal/tui" "github.com/getstackit/stackit/internal/utils" ) @@ -16,8 +15,18 @@ type RenameOptions struct { Force bool } +// RenameHandler supplies a new branch name interactively when one is not given +// on the command line. The CLI adapter implements it; the action layer does not +// import the TUI. +type RenameHandler interface { + // PromptNewName asks the user for a new branch name, given the current one. + // Implementations should return an error when prompting is not possible + // (e.g. non-interactive mode). + PromptNewName(currentName string) (string, error) +} + // RenameAction renames the current branch and updates metadata -func RenameAction(ctx *app.Context, opts RenameOptions) error { +func RenameAction(ctx *app.Context, opts RenameOptions, handler RenameHandler) error { eng := ctx.Engine out := ctx.Output @@ -29,12 +38,8 @@ func RenameAction(ctx *app.Context, opts RenameOptions) error { newName := opts.NewName if newName == "" { - if !utils.IsInteractive() { - return fmt.Errorf("branch name is required in non-interactive mode") - } - var err error - newName, err = tui.PromptTextInput("Enter new branch name:", currentBranch) + newName, err = handler.PromptNewName(currentBranch) if err != nil { return err } diff --git a/internal/actions/restack.go b/internal/actions/restack.go index 0e30fb528..f9e85bbb0 100644 --- a/internal/actions/restack.go +++ b/internal/actions/restack.go @@ -11,7 +11,6 @@ import ( "github.com/getstackit/stackit/internal/engine" "github.com/getstackit/stackit/internal/handlers" "github.com/getstackit/stackit/internal/rerere" - "github.com/getstackit/stackit/internal/tui" "github.com/getstackit/stackit/internal/utils" ) @@ -154,7 +153,7 @@ func RestackAction(ctx *app.Context, plan *RestackPlan, handler handlers.Restack handler = &handlers.NullRestackHandler{} } - interactiveRererePrompt := ctx.Interactive && !ctx.Quiet && tui.IsTTY() + interactiveRererePrompt := ctx.Interactive && !ctx.Quiet && utils.IsTTY() if _, jsonOutput := handler.(*handlers.JSONRestackHandler); jsonOutput { interactiveRererePrompt = false } diff --git a/internal/cli/branch/rename.go b/internal/cli/branch/rename.go index 7b86beacb..db9f9d49b 100644 --- a/internal/cli/branch/rename.go +++ b/internal/cli/branch/rename.go @@ -1,13 +1,29 @@ package branch import ( + "fmt" + "github.com/spf13/cobra" "github.com/getstackit/stackit/internal/actions" "github.com/getstackit/stackit/internal/app" "github.com/getstackit/stackit/internal/cli/common" + "github.com/getstackit/stackit/internal/tui" + "github.com/getstackit/stackit/internal/utils" ) +// renameHandler prompts for a new branch name via the TUI when running +// interactively, and reports that a name is required otherwise. It keeps the +// TUI dependency in the CLI adapter, out of the action layer. +type renameHandler struct{} + +func (renameHandler) PromptNewName(currentName string) (string, error) { + if !utils.IsInteractive() { + return "", fmt.Errorf("branch name is required in non-interactive mode") + } + return tui.PromptTextInput("Enter new branch name:", currentName) +} + // NewRenameCmd creates the rename command func NewRenameCmd() *cobra.Command { var ( @@ -35,7 +51,7 @@ Note that this removes any association to a pull request, as GitHub pull request Force: force, } - return actions.RenameAction(ctx, opts) + return actions.RenameAction(ctx, opts, renameHandler{}) }) }, }

AltStyle によって変換されたページ (->オリジナル) /