feat(trail): require explicit branch/selector when --repo is set · Entire
feat(trail): require explicit branch/selector when --repo is set
f713c2f·
toothbrush·3w ago·5 files·+53 added/-1 removed
With --repo targeting a repo other than the local clone, the branch-defaulting commands (show, update, delete, watch, finding) fell back to the local checkout's current branch, which could silently resolve the wrong trail when a branch name is shared. Require an explicit --branch or trail selector alongside --repo and fail clearly otherwise.
Also restores a //nolint:ireturn directive in agentimport.go that a prior
local mise run lint --fix pass had stripped (CI lints without --fix).
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com
Sessions
53294056bf83View transcript
Changes
5
cmd/entire/cli
agentimport
Magentimport.go+1/-1
Mtrail_cmd.go+21
Mtrail_repo_flag_test.go+25
Mtrail_review_cmd.go+3
Mtrail_watch_cmd.go+3
69 unmodified lines
// Get returns the importer registered under name.
//
//nolint:ireturn // Importer is the intended polymorphic seam returned to callers.
func Get(name string) (Importer, bool) {
for _, imp := range importers {
if imp.Name() == name {
Mcmd/entire/cli/agentimport/agentimport.go+1/-1
107 unmodified lines
return nil
}
// ensureTrailRepoHasTarget requires an explicit branch or trail selector when
// --repo targets a repository other than the local clone. Without one, the
// branch-defaulting commands fall back to the local checkout's current branch,
// which would silently resolve the wrong trail (a shared branch name) in the
// overridden repo. hint names the acceptable targets for the command.
func ensureTrailRepoHasTarget(cmd *cobra.Command, hasTarget bool, hint string) error {
if trailRepoFlag(cmd) != "" && !hasTarget {
return fmt.Errorf("--repo requires an explicit target: %s", hint)
}
return nil
}
// trailListOptions are the inputs to runTrailListAll. Keeping them on a
// struct avoids a long positional argument list at the two call sites.
type trailListOptions struct {
}
// --repo must not silently fall back to the local checkout's branch: the
// branch-defaulting commands require an explicit branch or selector alongside it.
func TestTrailRepoRequiresExplicitTarget(t *testing.T) {
t.Parallel()
tests := []struct {
name string
args []string
}{
{name: "show", args: []string{"show", "--repo", "gh/acme/app"}},
{name: "watch", args: []string{"watch", "--repo", "gh/acme/app"}},
{name: "update", args: []string{"update", "--repo", "gh/acme/app"}},
{name: "delete", args: []string{"delete", "--repo", "gh/acme/app"}},
{name: "finding list", args: []string{"finding", "list", "--repo", "gh/acme/app"}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
err := execTrailCmdExpectErr(t, tt.args...)
if err == nil || !strings.Contains(err.Error(), "--repo requires an explicit target") {
t.Fatalf("err = %v, want '--repo requires an explicit target'", err)
}
})
}
}
// Sanity: the persistent --repo flag is registered on the trail root and shows
// up in help, so every read subcommand inherits it.
func TestTrailRepoFlagRegisteredOnRoot(t *testing.T) {
}