Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion branch_restack.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,5 @@ func (cmd *branchRestackCmd) AfterApply(ctx context.Context, wt *git.Worktree) e
}

func (cmd *branchRestackCmd) Run(ctx context.Context, handler RestackHandler) error {
return handler.RestackBranch(ctx, cmd.Branch)
return handler.RestackBranch(ctx, cmd.Branch, nil)
}
2 changes: 1 addition & 1 deletion downstack_restack.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,5 @@ func (cmd *downstackRestackCmd) Run(
return errors.New("nothing to restack below trunk")
}

return handler.RestackDownstack(ctx, cmd.Branch)
return handler.RestackDownstack(ctx, cmd.Branch, nil)
}
5 changes: 3 additions & 2 deletions internal/handler/merge/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"strings"
"time"

"go.abhg.dev/gs/internal/handler/restack"
"go.abhg.dev/gs/internal/handler/submit"
"go.abhg.dev/gs/internal/handler/sync"

Expand All @@ -36,7 +37,7 @@ type Service interface {

// RestackHandler restacks branches after their bases are merged.
type RestackHandler interface {
RestackBranch(context.Context, string) error
RestackBranch(ctx context.Context, branch string, opts *restack.Options) error
}

// SubmitHandler updates change requests after branch restacks.
Expand Down Expand Up @@ -599,7 +600,7 @@ func (e *mergePlanExecutor) prepareForMerge(
return fmt.Errorf("verify restacked: %w", err)
}

if err := e.Restack.RestackBranch(ctx, item.branch); err != nil {
if err := e.Restack.RestackBranch(ctx, item.branch, nil); err != nil {
return fmt.Errorf("restack branch: %w", err)
}

Expand Down
6 changes: 3 additions & 3 deletions internal/handler/merge/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -317,10 +317,10 @@ func TestExecutePlan_retargets(t *testing.T) {

mockRestack := NewMockRestackHandler(ctrl)
mockRestack.EXPECT().
RestackBranch(gomock.Any(), "feat2").
RestackBranch(gomock.Any(), "feat2", gomock.Nil()).
Return(nil)
mockRestack.EXPECT().
RestackBranch(gomock.Any(), "feat3").
RestackBranch(gomock.Any(), "feat3", gomock.Nil()).
Return(nil)

mockSubmit := NewMockSubmitHandler(ctrl)
Expand Down Expand Up @@ -396,7 +396,7 @@ func TestExecutePlan_waitsForPreparedChangeHeadBeforeChecks(t *testing.T) {

mockRestack := NewMockRestackHandler(ctrl)
mockRestack.EXPECT().
RestackBranch(gomock.Any(), "feat2").
RestackBranch(gomock.Any(), "feat2", gomock.Nil()).
Return(nil)

mockSubmit := NewMockSubmitHandler(ctrl)
Expand Down
13 changes: 7 additions & 6 deletions internal/handler/merge/mocks_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion internal/handler/restack/branch.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ package restack
import "context"

// RestackBranch restacks the given branch onto its base.
func (h *Handler) RestackBranch(ctx context.Context, branch string) error {
func (h *Handler) RestackBranch(
ctx context.Context, branch string, opts *Options,
) error {
_, err := h.Restack(ctx, &Request{
Branch: branch,
ContinueCommand: []string{"branch", "restack"},
AutoResolve: opts.autoResolvePtr(),
})
return err
}
10 changes: 5 additions & 5 deletions internal/handler/restack/branch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func TestHandler_RestackBranch(t *testing.T) {
Store: statetest.NewMemoryStore(t, "main", "", log),
Service: mockService,
}
require.NoError(t, handler.RestackBranch(t.Context(), "feature"))
require.NoError(t, handler.RestackBranch(t.Context(), "feature", nil))
assert.Contains(t, logBuffer.String(), "feature: restacked on main")
})

Expand Down Expand Up @@ -82,7 +82,7 @@ func TestHandler_RestackBranch(t *testing.T) {
Service: mockService,
}

require.NoError(t, handler.RestackBranch(t.Context(), "feature"))
require.NoError(t, handler.RestackBranch(t.Context(), "feature", nil))
})

t.Run("UntrackedBranch", func(t *testing.T) {
Expand Down Expand Up @@ -113,7 +113,7 @@ func TestHandler_RestackBranch(t *testing.T) {
Service: mockService,
}

err := handler.RestackBranch(t.Context(), "untracked")
err := handler.RestackBranch(t.Context(), "untracked", nil)
require.Error(t, err)
assert.ErrorContains(t, err, "untracked branch")
assert.Contains(t, logBuffer.String(), "untracked: branch not tracked: run '"+cli.Name()+" branch track")
Expand Down Expand Up @@ -146,7 +146,7 @@ func TestHandler_RestackBranch(t *testing.T) {
Store: statetest.NewMemoryStore(t, "main", "", log),
Service: mockService,
}
require.NoError(t, handler.RestackBranch(t.Context(), "already-restacked"))
require.NoError(t, handler.RestackBranch(t.Context(), "already-restacked", nil))
assert.Contains(t, logBuffer.String(), "already-restacked: branch does not need to be restacked.")
})

Expand Down Expand Up @@ -177,7 +177,7 @@ func TestHandler_RestackBranch(t *testing.T) {
Store: statetest.NewMemoryStore(t, "main", "", log),
Service: mockService,
}
err := handler.RestackBranch(t.Context(), "feature")
err := handler.RestackBranch(t.Context(), "feature", nil)
require.Error(t, err)
assert.ErrorContains(t, err, "restack branch")
assert.ErrorIs(t, err, unexpectedErr)
Expand Down
5 changes: 4 additions & 1 deletion internal/handler/restack/downstack.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@ import "context"

// RestackDownstack restacks the downstack of the given branch.
// This includes the branch itself.
func (h *Handler) RestackDownstack(ctx context.Context, branch string) error {
func (h *Handler) RestackDownstack(
ctx context.Context, branch string, opts *Options,
) error {
_, err := h.Restack(ctx, &Request{
Branch: branch,
Scope: ScopeDownstack,
ContinueCommand: []string{"downstack", "restack"},
AutoResolve: opts.autoResolvePtr(),
})
return err
}
4 changes: 2 additions & 2 deletions internal/handler/restack/downstack_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func TestHandler_RestackDownstack(t *testing.T) {
Service: mockService,
}

require.NoError(t, handler.RestackDownstack(t.Context(), "feature3"))
require.NoError(t, handler.RestackDownstack(t.Context(), "feature3", nil))
assert.Contains(t, logBuffer.String(), "feature1: restacked on main")
assert.Contains(t, logBuffer.String(), "feature2: restacked on feature1")
assert.Contains(t, logBuffer.String(), "feature3: restacked on feature2")
Expand Down Expand Up @@ -99,6 +99,6 @@ func TestHandler_RestackDownstack(t *testing.T) {
Service: mockService,
}

require.NoError(t, handler.RestackDownstack(t.Context(), "feature2"))
require.NoError(t, handler.RestackDownstack(t.Context(), "feature2", nil))
})
}
27 changes: 27 additions & 0 deletions internal/handler/restack/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,33 @@ type Request struct {
//
// Defaults to ScopeBranch.
Scope Scope

// AutoResolve, if non-nil, overrides
// [Handler.DefaultAutoResolve] for this invocation. A true
// value enables the configured resolver; a false value disables
// it even when configured.
AutoResolve *bool
}

// Options are optional parameters shared by the high-level restack
// entry points ([Handler.RestackBranch], [Handler.RestackStack],
// [Handler.RestackDownstack]).
type Options struct {
// AutoResolve, if non-nil, overrides
// [Handler.DefaultAutoResolve] for this invocation. A true
// value enables the configured resolver; a false value disables
// it even when configured.
AutoResolve *bool
}

// autoResolvePtr returns the AutoResolve pointer if opts is
// non-nil, or nil. Callers pass the result through to
// [Request.AutoResolve].
func (o *Options) autoResolvePtr() *bool {
if o == nil {
return nil
}
return o.AutoResolve
}

// Restack restacks one or more branches according to the request.
Expand Down
5 changes: 4 additions & 1 deletion internal/handler/restack/stack.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@ import "context"
// RestackStack restacks the stack of the given branch.
// This includes all upstack and downtrack branches,
// as well as the branch itself.
func (h *Handler) RestackStack(ctx context.Context, branch string) error {
func (h *Handler) RestackStack(
ctx context.Context, branch string, opts *Options,
) error {
_, err := h.Restack(ctx, &Request{
Branch: branch,
Scope: ScopeStack,
ContinueCommand: []string{"stack", "restack"},
AutoResolve: opts.autoResolvePtr(),
})
return err
}
4 changes: 2 additions & 2 deletions internal/handler/sync/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ type DeleteHandler interface {
// RestackHandler allows restacking branches after sync
// has removed their downstack branches.
type RestackHandler interface {
RestackBranch(ctx context.Context, branch string) error
RestackBranch(ctx context.Context, branch string, opts *restack.Options) error
RestackUpstack(ctx context.Context, branch string, opts *restack.UpstackOptions) error
}

Expand Down Expand Up @@ -983,7 +983,7 @@ func (h *Handler) restackDeletedBranchUpstack(
return fmt.Errorf("restack upstack %q: %w", target, err)
}
case mode.Includes(spice.RestackAboves):
if err := h.Restack.RestackBranch(ctx, target); err != nil {
if err := h.Restack.RestackBranch(ctx, target, nil); err != nil {
return fmt.Errorf("restack branch %q: %w", target, err)
}
case mode.Includes(spice.RestackNone):
Expand Down
2 changes: 1 addition & 1 deletion internal/handler/sync/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ func TestHandler_SyncTrunk_restackDeletedUpstacks(t *testing.T) {

mockRestack := NewMockRestackHandler(ctrl)
mockRestack.EXPECT().
RestackBranch(gomock.Any(), "child").
RestackBranch(gomock.Any(), "child", gomock.Nil()).
Return(nil)

mockAutostash := NewMockAutostashHandler(ctrl)
Expand Down
12 changes: 6 additions & 6 deletions internal/handler/sync/mocks_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion stack_restack.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,5 +88,5 @@ func (cmd *stackRestackCmd) Run(
return err
}

return handler.RestackStack(ctx, cmd.Branch)
return handler.RestackStack(ctx, cmd.Branch, nil)
}
6 changes: 3 additions & 3 deletions upstack_restack.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ func (*upstackRestackCmd) Help() string {
// RestackHandler implements high level restack operations.
type RestackHandler interface {
RestackUpstack(ctx context.Context, branch string, opts *restack.UpstackOptions) error
RestackDownstack(ctx context.Context, branch string) error
RestackDownstack(ctx context.Context, branch string, opts *restack.Options) error
Restack(context.Context, *restack.Request) (int, error)
RestackStack(ctx context.Context, branch string) error
RestackBranch(ctx context.Context, branch string) error
RestackStack(ctx context.Context, branch string, opts *restack.Options) error
RestackBranch(ctx context.Context, branch string, opts *restack.Options) error
}

func (cmd *upstackRestackCmd) AfterApply(ctx context.Context, wt *git.Worktree) error {
Expand Down
Loading