Clean up CLI flag plumbing and small duplications · Entire

Clean up CLI flag plumbing and small duplications

c493362·

Soph·2w ago·9 files·+49 added/-62 removed

Co-Authored-By: Claude Fable 5 noreply@anthropic.com

Sessions

6a45cb3266a7View transcript

Changes

9

382 unmodified lines

383
384
385
386
387
388
389
390
391
392
393
394
386
387
388
389

382 unmodified lines

return nil
    }
slices.Sort(input)
out := input[:0]
var prev string
for i, item := range input {
    if i == 0 || item != prev {
        out = append(out, item)
        prev = item
    }
}
return out
return slices.Compact(input)
}

func normalizeRepoURL(raw string) (string, error) {

Mcmd/git-sync-bench/main.go+1/-9

4 unmodified lines

5
6
7
8
8
9
10
25 unmodified lines

36
37
38
40
41
42
43
44
45
46
47
48
39
40
41
42
43
44
45
46

4 unmodified lines

"fmt"

gitsync "entire.io/entire/git-sync"
    "entire.io/entire/git-sync/internal/validation"
    "entire.io/entire/git-sync/unstable"
    "github.com/spf13/cobra"
)
25 unmodified lines

if branches != "" {
            req.Scope.Branches = splitCSV(branches)
        }
        for _, raw := range mappings {
            mapping, err := validation.ParseMapping(raw)
            if err != nil {
                return fmt.Errorf("parse mapping %q: %w", raw, err)
            }
            req.Scope.Mappings = append(req.Scope.Mappings, gitsync.RefMapping{
                Source: mapping.Source,
                Target: mapping.Target,
            })
        }
        parsed, err := parseMappings(mappings)
        if err != nil {
            return err
        }
        req.Scope.Mappings = parsed

if req.Source.URL == "" || req.Target.URL == "" {
            return errors.New("bootstrap requires source and target repository URLs")
        }

Mcmd/git-sync/bootstrap.go+4/-10

73 unmodified lines

74
75
76
77
78
79
80
81
82
83
77
78
79
80

73 unmodified lines

cmd.Flags().BoolVar(&req.SourceFollowInfoRefsRedirect, "source-follow-info-refs-redirect",
        envBool("GITSYNC_SOURCE_FOLLOW_INFO_REFS_REDIRECT"),
        "send follow-up source RPCs to the final /info/refs redirect host")
    addSecretFlag(cmd, &req.SourceAuth.Token, "source-token", "GITSYNC_SOURCE_TOKEN", "source token/password")
    cmd.Flags().StringVar(&req.SourceAuth.Username, "source-username",
        envOr("GITSYNC_SOURCE_USERNAME", "git"), "source basic auth username")
    addSecretFlag(cmd, &req.SourceAuth.BearerToken, "source-bearer-token", "GITSYNC_SOURCE_BEARER_TOKEN", "source bearer token")
    cmd.Flags().BoolVar(&req.SourceAuth.SkipTLSVerify, "source-insecure-skip-tls-verify",
        envBool("GITSYNC_SOURCE_INSECURE_SKIP_TLS_VERIFY"),
        "skip TLS certificate verification for the source")
    addSourceAuth(cmd, &req.SourceAuth)
    cmd.Flags().StringVar(&req.TargetDir, "target-dir", "", "directory to initialize as a SHA256 bare repository")

allRefsFlag(cmd, allRefsUsageScopeOnly, &req.AllRefs)

Mcmd/git-sync/convert_sha256.go+1/-7

125 unmodified lines

126
127
128
129
129
130
131
132
46 unmodified lines

179
180
181
182
183
182
183
184
185
186
187
188
189
190
191
192
193
194
185
186
195
196
197
198
199
3 unmodified lines

203
204
205
196
206
207
208
209
3 unmodified lines

213
214
215
206
216
217
218
219
3 unmodified lines

223
224
225
216
226
227
218
228
229
220
230
231

125 unmodified lines

}

func newProtocolFlag() protocolModeFlag {
    return protocolModeFlag(protocolMode(envOr("GITSYNC_PROTOCOL", validation.ProtocolAuto)))
    return protocolModeFlag(envOr("GITSYNC_PROTOCOL", validation.ProtocolAuto))
}

func envOr(key, fallback string) string {
46 unmodified lines

return out
}

type protocolMode gitsync.ProtocolMode
type operationMode gitsync.OperationMode
// parseMappings converts raw --map values (src:dst form) into ref mappings.
func parseMappings(raw []string) ([]gitsync.RefMapping, error) {
    out := make([]gitsync.RefMapping, 0, len(raw))
    for _, value := range raw {
        mapping, err := validation.ParseMapping(value)
        if err != nil {
            return nil, fmt.Errorf("parse mapping %q: %w", value, err)
        }
        out = append(out, gitsync.RefMapping{Source: mapping.Source, Target: mapping.Target})
    }
    return out, nil
}

type protocolModeFlag protocolMode
type operationModeFlag operationMode
type protocolModeFlag gitsync.ProtocolMode
type operationModeFlag gitsync.OperationMode

func (p *protocolModeFlag) String() string { return string(*p) }
func (p *protocolModeFlag) Type() string   { return "string" }
3 unmodified lines

if err != nil {
        return fmt.Errorf("normalize protocol: %w", err)
    }
    *p = protocolModeFlag(protocolMode(gitsync.ProtocolMode(mode)))
    *p = protocolModeFlag(mode)
    return nil
}

3 unmodified lines

func (m *operationModeFlag) Set(value string) error {
    switch gitsync.OperationMode(value) {
    case gitsync.ModeSync, gitsync.ModeReplicate:
        *m = operationModeFlag(operationMode(value))
        *m = operationModeFlag(value)
        return nil
    default:
        return fmt.Errorf("unsupported mode %q", value)
3 unmodified lines

// defaultOperationMode returns the starting value for the --mode flag.
// Subcommands that pin a mode (sync, replicate) pass it in; plan passes ""
// and gets sync as the default, letting --mode override it.
func defaultOperationMode(defaultMode gitsync.OperationMode) operationMode {
func defaultOperationMode(defaultMode gitsync.OperationMode) operationModeFlag {
    if defaultMode != "" {
        return operationMode(defaultMode)
        return operationModeFlag(defaultMode)
    }
    return operationMode(gitsync.ModeSync)
    return operationModeFlag(gitsync.ModeSync)
}

Mcmd/git-sync/flags.go+20/-10

1524 unmodified lines

1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543

1524 unmodified lines

return b.String(), count, nil
}

// resolveCacheEntry holds a memoized (Hash, matchResult) pair from
// resolveMessageRef. Stored in t.resolveCache keyed by lowercased prefix.
type resolveCacheEntry struct {
    hash   plumbing.Hash
    result matchResult
}

// resolveMessageRef classifies a hex prefix against the reachable set.
// Returns matchUnique with the resolved SHA1 when exactly one commit
// or tag in scope matches; matchAmbiguous when more than one does;
// matchNone otherwise (no match, or the match is a blob/tree — those
// are filtered so incidental hex collisions on content hashes aren't
// rewritten).
// resolveCacheEntry holds a memoized (Hash, matchResult) pair from
// resolveMessageRef. Stored in t.resolveCache keyed by lowercased prefix.
type resolveCacheEntry struct {
    hash   plumbing.Hash
    result matchResult
}

func (t *translator) resolveMessageRef(prefix string) (plumbing.Hash, matchResult) {
    // Canonicalize to lowercase: hashPattern is case-insensitive so
    // the caller can match `ABCD1234` in a message, but reachable

Mcmd/git-sync/internal/sha256convert/sha256convert.go+7/-7

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

package versioninfo

import "fmt"

var (
    Version = "dev"
    Commit  = "none"
    Date    = "unknown"
)

// String renders the one-line build description shared by `git-sync version`
// and `git-sync --version`.
func String() string {
    return fmt.Sprintf("git-sync %s (commit %s, built %s)", Version, Commit, Date)
}

Mcmd/git-sync/internal/versioninfo/versioninfo.go+8

26 unmodified lines

27
28
29
30
31
30
31
32
33

26 unmodified lines

return cmd.Help()
    },
}
    cmd.SetVersionTemplate(fmt.Sprintf("git-sync %s (commit %s, built %s)\n",
        versioninfo.Version, versioninfo.Commit, versioninfo.Date))
    cmd.SetVersionTemplate(versioninfo.String() + "\n")

cmd.AddCommand(newSyncCmd())
    cmd.AddCommand(newReplicateCmd())

Mcmd/git-sync/root.go+1/-2

4 unmodified lines

5
6
7
8
8
9
10
17 unmodified lines

28
29
30
32
31
32
33
34
19 unmodified lines

54
55
56
58
59
60
61
62
63
64
65
66
57
58
59
60
61
62
63
64
3 unmodified lines

68
69
70
77
78
79
80
71
72
73
74

4 unmodified lines

"fmt"

gitsync "entire.io/entire/git-sync"
    "entire.io/entire/git-sync/internal/validation"
    "entire.io/entire/git-sync/unstable"
    "github.com/spf13/cobra"
)
17 unmodified lines

sourceAuth  gitsync.EndpointAuth
        targetAuth  gitsync.EndpointAuth
        branches    string
        modeValue   = operationModeFlag(defaultOperationMode(defaultMode))
        modeValue   = defaultOperationMode(defaultMode)
        protocolVal = newProtocolFlag()
        legacyForce bool
        req         = unstable.SyncRequest{DryRun: dryRun}
19 unmodified lines

if req.Source.URL == "" || req.Target.URL == "" {
            return fmt.Errorf("%s requires source and target repository URLs", name)
        }
3 unmodified lines

Auth: gitsync.StaticAuthProvider{Source: sourceAuth, Target: targetAuth},
        })

var (
        result unstable.Result
        err    error
        )
        var result unstable.Result
        ctx := cmd.Context()
        switch {
        case dryRun:

Mcmd/git-sync/syncplan.go+6/-15

11 unmodified lines

12
13
14
15
16
15
16
17
18

11 unmodified lines

Use:   "version",
        Short: "Show build information",
        Run: func(cmd *cobra.Command, _ []string) {
            fmt.Fprintf(cmd.OutOrStdout(), "git-sync %s (commit %s, built %s)\n",
                versioninfo.Version, versioninfo.Commit, versioninfo.Date)
            fmt.Fprintln(cmd.OutOrStdout(), versioninfo.String())
        },
    }
}

Mcmd/git-sync/version.go+1/-2