move checkpoint policy command · Entire
move checkpoint policy command
f3c10b3→main·
pfleidi·3w ago·8 files·+278 added/-301 removed
Nest the checkpoint policy command under the checkpoint group and remove the hidden top-level policy group.
This makes the development command path entire checkpoint policy while preserving the existing hidden status.
Sessions
21cc4b97e773View transcript
[?
Checkpoint Policy Command and Feature ImprovementsCodex·GPT-5.5·2 steps](/content/gh/entireio/cli/session/019ef6e7-b75d-7050-920a-93eed6d34c27#timeline-21cc4b97e773/index.html)
Changes
8
cmd/entire/cli
Mcheckpoint_group.go+1
Acheckpoint_policy.go+90
Acheckpoint_policy_test.go+176
Dpolicy_checkpoint.go-89
Dpolicy_checkpoint_test.go-176
Dpolicy_group.go-24
Mroot.go-1
Mroot_test.go+11/-11
37 unmodified lines
38
39
40
41
42
43
44
37 unmodified lines
cmd.AddCommand(newCheckpointListCmd())
cmd.AddCommand(newExplainCmd())
cmd.AddCommand(newCheckpointTokensCmd())
cmd.AddCommand(newCheckpointPolicyCmd())
cmd.AddCommand(newRewindCmd())
cmd.AddCommand(newCheckpointSearchCmd())
Mcmd/entire/cli/checkpoint_group.go+1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package cli
import (
"context"
"errors"
"fmt"
"github.com/entireio/cli/cmd/entire/cli/checkpointpolicy"
"github.com/entireio/cli/cmd/entire/cli/gitrepo"
"github.com/spf13/cobra"
)
type checkpointPolicyOptions struct {
version string
minVersion string
force bool
}
func newCheckpointPolicyCmd() *cobra.Command {
var opts checkpointPolicyOptions
cmd := &cobra.Command{
Use: "policy",
Short: "Inspect and update checkpoint policy",
Hidden: true,
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, _ []string) error {
return runCheckpointPolicy(cmd, opts)
},
}
cmd.Flags().StringVar(&opts.version, "checkpoint-version", "", "Set the checkpoint version written by this repository")
cmd.Flags().StringVar(&opts.minVersion, "checkpoint-min-version", "", "Set the minimum checkpoint version required by this repository")
cmd.Flags().BoolVar(&opts.force, "force", false, "Allow checkpoint policy version downgrades")
return cmd
}
func runCheckpointPolicy(cmd *cobra.Command, opts checkpointPolicyOptions) error {
ctx := cmd.Context()
if err := ctx.Err(); err != nil {
return NewSilentError(err)
}
repo, err := gitrepo.OpenCurrent(ctx)
if err != nil {
return checkpointPolicyError("open repository", err)
}
defer repo.Close()
target, err := checkpointpolicy.ResolveTarget(ctx)
if err != nil {
return checkpointPolicyError("resolve checkpoint policy remote", err)
}
var state checkpointpolicy.State
if hasCheckpointPolicyUpdate(opts) {
state, err = checkpointpolicy.Update(ctx, repo, target, checkpointpolicy.UpdateOptions{
CheckpointVersion: opts.version,
CheckpointMinVersion: opts.minVersion,
Force: opts.force,
})
if err != nil {
return checkpointPolicyError("update checkpoint policy", err)
}
if err := checkpointpolicy.Push(ctx, target); err != nil {
return checkpointPolicyError("push checkpoint policy", err)
}
state.Source = checkpointpolicy.SourceRemote
} else {
state, err = checkpointpolicy.Sync(ctx, repo, target)
if err != nil {
return checkpointPolicyError("sync checkpoint policy", err)
}
}
fmt.Fprintf(cmd.OutOrStdout(), "checkpoint_version: %s\n", state.Policy.CheckpointVersion)
fmt.Fprintf(cmd.OutOrStdout(), "checkpoint_min_version: %s\n", state.Policy.CheckpointMinVersion)
fmt.Fprintf(cmd.OutOrStdout(), "source: %s\n", state.Source)
return nil
}
func hasCheckpointPolicyUpdate(opts checkpointPolicyOptions) bool {
return opts.version != "" || opts.minVersion != ""
}
func checkpointPolicyError(message string, err error) error {
wrapped := fmt.Errorf("%s: %w", message, err)
if errors.Is(wrapped, context.Canceled) {
return NewSilentError(wrapped)
}
return wrapped
}
Acmd/entire/cli/checkpoint_policy.go+90
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
package cli
import (
"bytes"
"context"
"fmt"
"os/exec"
"path/filepath"
"strings"
"testing"
"github.com/entireio/cli/cmd/entire/cli/checkpointpolicy"
"github.com/entireio/cli/cmd/entire/cli/testutil"
"github.com/go-git/go-git/v6"
"github.com/go-git/go-git/v6/plumbing"
"github.com/spf13/cobra"
"github.com/stretchr/testify/require"
)
func TestCheckpointPolicyCmd_PrintsDefaults(t *testing.T) {
_, _ = setupCheckpointPolicyRepo(t)
stdout, err := executeCheckpointPolicyCmd(t)
require.NoError(t, err)
require.Contains(t, stdout, "checkpoint_version: branch-v1")
require.Contains(t, stdout, "checkpoint_min_version: branch-v1")
require.Contains(t, stdout, "source: defaults")
}
func TestCheckpointPolicyCmd_RejectsUnsupportedVersion(t *testing.T) {
tests := []struct {
name string
args []string
wantErr string
}{
{name: "checkpoint version", args: []string{"--checkpoint-version", "refs-v1"}, wantErr: "not write-supported"},
{name: "minimum version", args: []string{"--checkpoint-min-version", "refs-v1"}, wantErr: "not read-supported"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_, _ = setupCheckpointPolicyRepo(t)
_, err := executeCheckpointPolicyCmd(t, tt.args...)
require.ErrorContains(t, err, tt.wantErr)
})
}
}
func TestCheckpointPolicyCmd_RejectsDowngradeWithoutForce(t *testing.T) {
dir, bareDir := setupCheckpointPolicyRepo(t)
seedCheckpointPolicyForCommand(t, dir, checkpointpolicy.Policy{
CheckpointVersion: "refs-v1",
CheckpointMinVersion: "refs-v1",
})
pushCheckpointPolicyRefForCommandTest(t, dir, bareDir)
_, err := executeCheckpointPolicyCmd(t, "--checkpoint-version", "branch-v1", "--checkpoint-min-version", "branch-v1")
require.ErrorContains(t, err, "would downgrade checkpoint_version")
}
func TestCheckpointPolicyCmd_UpdatesAndPushesOnlyPolicyRef(t *testing.T) {
dir, bareDir := setupCheckpointPolicyRepo(t)
testutil.WriteFile(t, dir, "README.md", "hello\n")
testutil.GitAdd(t, dir, "README.md")
testutil.GitCommit(t, dir, "init")
stdout, err := executeCheckpointPolicyCmd(t, "--checkpoint-version", "branch-v1", "--checkpoint-min-version", "branch-v1")
require.NoError(t, err)
require.Contains(t, stdout, "checkpoint_version: branch-v1")
require.Contains(t, stdout, "checkpoint_min_version: branch-v1")
require.Contains(t, stdout, "source: remote")
remoteHash := checkpointPolicyRemoteHashForCommandTest(t, dir, bareDir)
require.False(t, remoteHash.IsZero())
repo := openCheckpointPolicyRepoForCommandTest(t, dir)
localState, err := checkpointpolicy.ReadLocal(t.Context(), repo)
require.NoError(t, err)
require.Equal(t, remoteHash, localState.Hash)
branches := runCheckpointPolicyGit(t, dir, "ls-remote", bareDir, "refs/heads/*")
require.Empty(t, strings.TrimSpace(branches))
}
func TestCheckpointPolicyCmd_SilencesContextCanceled(t *testing.T) {
cmd := &cobra.Command{}
var stdout, stderr bytes.Buffer
cmd.SetOut(&stdout)
cmd.SetErr(&stderr)
ctx, cancel := context.WithCancel(context.Background())
cancel()
cmd.SetContext(ctx)
err := runCheckpointPolicy(cmd, checkpointPolicyOptions{})
require.ErrorIs(t, err, context.Canceled)
var silent *SilentError
require.ErrorAs(t, err, &silent, "error = %T %v, want SilentError", err, err)
require.Empty(t, stderr.String())
}
func TestCheckpointPolicyErrorSilencesWrappedContextCanceled(t *testing.T) {
err := checkpointPolicyError("sync checkpoint policy", fmt.Errorf("remote: %w", context.Canceled))
require.ErrorIs(t, err, context.Canceled)
var silent *SilentError
require.ErrorAs(t, err, &silent, "error = %T %v, want SilentError", err, err)
}
func setupCheckpointPolicyRepo(t *testing.T) (string, string) {
t.Helper()
testutil.IsolateGitConfigEnv(t)
dir := setupTestDir(t)
testutil.InitRepo(t, dir)
bareDir := filepath.Join(t.TempDir(), "remote.git")
_, err := git.PlainInit(bareDir, true)
require.NoError(t, err)
runCheckpointPolicyGit(t, dir, "remote", "add", "origin", bareDir)
return dir, bareDir
}
func executeCheckpointPolicyCmd(t *testing.T, args ...string) (string, error) {
t.Helper()
cmd := newCheckpointGroupCmd()
var stdout, stderr bytes.Buffer
cmd.SetOut(&stdout)
cmd.SetErr(&stderr)
cmd.SetArgs(append([]string{"policy"}, args...))
cmd.SetContext(t.Context())
cmd.SilenceErrors = true
cmd.SilenceUsage = true
err := cmd.Execute()
return stdout.String(), err
}
func seedCheckpointPolicyForCommand(t *testing.T, dir string, policy checkpointpolicy.Policy) plumbing.Hash {
t.Helper()
repo := openCheckpointPolicyRepoForCommandTest(t, dir)
hash, err := checkpointpolicy.WriteLocal(t.Context(), repo, plumbing.ZeroHash, policy)
require.NoError(t, err)
return hash
}
func openCheckpointPolicyRepoForCommandTest(t *testing.T, dir string) *git.Repository {
t.Helper()
repo, err := git.PlainOpen(dir)
require.NoError(t, err)
cleanup(func() {
_ = repo.Close()
})
return repo
}
func pushCheckpointPolicyRefForCommandTest(t *testing.T, dir, remote string) {
t.Helper()
refspec := checkpointpolicy.RefName.String() + ":" + checkpointpolicy.RefName.String()
runCheckpointPolicyGit(t, dir, "push", remote, refspec)
}
func checkpointPolicyRemoteHashForCommandTest(t *testing.T, dir, remote string) plumbing.Hash {
t.Helper()
output := runCheckpointPolicyGit(t, dir, "ls-remote", remote, checkpointpolicy.RefName.String())
fields := strings.Fields(output)
require.NotEmpty(t, fields, "missing remote checkpoint policy ref")
return plumbing.NewHash(fields[0])
}
func runCheckpointPolicyGit(t *testing.T, dir string, args ...string) string {
t.Helper()
cmd := exec.CommandContext(context.Background(), "git", args...)
cmd.Dir = dir
cmd.Env = testutil.GitIsolatedEnv()
output, err := cmd.CombinedOutput()
require.NoError(t, err, string(output))
return string(output)
}
Dcmd/entire/cli/policy_checkpoint.go-89
package cli
import ( "bytes" "context" "fmt" "os/exec" "path/filepath" "strings" "testing"
func TestPolicyCheckpointCmd_PrintsDefaults(t *testing.T) { _, _ = setupPolicyCheckpointRepo(t)
stdout, err := executePolicyCheckpointCmd(t) require.NoError(t, err) require.Contains(t, stdout, "checkpoint_version: branch-v1") require.Contains(t, stdout, "checkpoint_min_version: branch-v1") require.Contains(t, stdout, "source: defaults") }
func TestPolicyCheckpointCmd_RejectsUnsupportedVersion(t *testing.T) { tests := []struct { name string args []string wantErr string }{ {name: "checkpoint version", args: []string{"--checkpoint-version", "refs-v1"}, wantErr: "not write-supported"}, {name: "minimum version", args: []string{"--checkpoint-min-version", "refs-v1"}, wantErr: "not read-supported"}, }
for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { _, _ = setupPolicyCheckpointRepo(t)
_, err := executePolicyCheckpointCmd(t, tt.args...) require.ErrorContains(t, err, tt.wantErr) }) } }
func TestPolicyCheckpointCmd_RejectsDowngradeWithoutForce(t *testing.T) { dir, bareDir := setupPolicyCheckpointRepo(t) seedPolicyForCheckpointCommand(t, dir, checkpointpolicy.Policy{ CheckpointVersion: "refs-v1", CheckpointMinVersion: "refs-v1", }) pushCheckpointPolicyRefForCommandTest(t, dir, bareDir)
_, err := executePolicyCheckpointCmd(t, "--checkpoint-version", "branch-v1", "--checkpoint-min-version", "branch-v1") require.ErrorContains(t, err, "would downgrade checkpoint_version") }
func TestPolicyCheckpointCmd_UpdatesAndPushesOnlyPolicyRef(t *testing.T) { dir, bareDir := setupPolicyCheckpointRepo(t) testutil.WriteFile(t, dir, "README.md", "hello\n") testutil.GitAdd(t, dir, "README.md") testutil.GitCommit(t, dir, "init")
stdout, err := executePolicyCheckpointCmd(t, "--checkpoint-version", "branch-v1", "--checkpoint-min-version", "branch-v1") require.NoError(t, err) require.Contains(t, stdout, "checkpoint_version: branch-v1") require.Contains(t, stdout, "checkpoint_min_version: branch-v1") require.Contains(t, stdout, "source: remote")
remoteHash := checkpointPolicyRemoteHashForCommandTest(t, dir, bareDir) require.False(t, remoteHash.IsZero())
repo := openPolicyCheckpointRepoForCommandTest(t, dir) localState, err := checkpointpolicy.ReadLocal(t.Context(), repo) require.NoError(t, err) require.Equal(t, remoteHash, localState.Hash)
branches := runPolicyCheckpointGit(t, dir, "ls-remote", bareDir, "refs/heads/*") require.Empty(t, strings.TrimSpace(branches)) }
func TestPolicyCheckpointCmd_SilencesContextCanceled(t *testing.T) { cmd := &cobra.Command{} var stdout, stderr bytes.Buffer cmd.SetOut(&stdout) cmd.SetErr(&stderr) ctx, cancel := context.WithCancel(context.Background()) cancel() cmd.SetContext(ctx)
err := runPolicyCheckpoint(cmd, policyCheckpointOptions{}) require.ErrorIs(t, err, context.Canceled) var silent *SilentError require.ErrorAs(t, err, &silent, "error = %T %v, want SilentError", err, err) require.Empty(t, stderr.String()) }
func TestPolicyCheckpointErrorSilencesWrappedContextCanceled(t *testing.T) { err := policyCheckpointError("sync checkpoint policy", fmt.Errorf("remote: %w", context.Canceled)) require.ErrorIs(t, err, context.Canceled) var silent *SilentError require.ErrorAs(t, err, &silent, "error = %T %v, want SilentError", err, err) }
func setupPolicyCheckpointRepo(t *testing.T) (string, string) { t.Helper() testutil.IsolateGitConfigEnv(t) dir := setupTestDir(t) testutil.InitRepo(t, dir)
bareDir := filepath.Join(t.TempDir(), "remote.git") _, err := git.PlainInit(bareDir, true) require.NoError(t, err) runPolicyCheckpointGit(t, dir, "remote", "add", "origin", bareDir) return dir, bareDir }
func executePolicyCheckpointCmd(t *testing.T, args ...string) (string, error) { t.Helper() cmd := newPolicyCmd() var stdout, stderr bytes.Buffer cmd.SetOut(&stdout) cmd.SetErr(&stderr) cmd.SetArgs(append([]string{"checkpoint"}, args...)) cmd.SetContext(t.Context()) cmd.SilenceErrors = true cmd.SilenceUsage = true err := cmd.Execute() return stdout.String(), err }
func seedPolicyForCheckpointCommand(t *testing.T, dir string, policy checkpointpolicy.Policy) plumbing.Hash { t.Helper() repo := openPolicyCheckpointRepoForCommandTest(t, dir) hash, err := checkpointpolicy.WriteLocal(t.Context(), repo, plumbing.ZeroHash, policy) require.NoError(t, err) return hash }
func openPolicyCheckpointRepoForCommandTest(t *testing.T, dir string) *git.Repository { t.Helper() repo, err := git.PlainOpen(dir) require.NoError(t, err) cleanup(func() { _ = repo.Close() }) return repo }
func pushCheckpointPolicyRefForCommandTest(t *testing.T, dir, remote string) { t.Helper() refspec := checkpointpolicy.RefName.String() + ":" + checkpointpolicy.RefName.String() runPolicyCheckpointGit(t, dir, "push", remote, refspec) }
func checkpointPolicyRemoteHashForCommandTest(t *testing.T, dir, remote string) plumbing.Hash { t.Helper() output := runPolicyCheckpointGit(t, dir, "ls-remote", remote, checkpointpolicy.RefName.String()) fields := strings.Fields(output) require.NotEmpty(t, fields, "missing remote checkpoint policy ref") return plumbing.NewHash(fields[0]) }
func runPolicyCheckpointGit(t *testing.T, dir string, args ...string) string { t.Helper() cmd := exec.CommandContext(context.Background(), "git", args...) cmd.Dir = dir cmd.Env = testutil.GitIsolatedEnv() output, err := cmd.CombinedOutput() require.NoError(t, err, string(output)) return string(output) }
Dcmd/entire/cli/policy_checkpoint_test.go-176
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
package cli
import ( "errors"
"github.com/entireio/cli/cmd/entire/cli/paths" "github.com/spf13/cobra" )
func newPolicyCmd() *cobra.Command { cmd := &cobra.Command{ Use: "policy", Short: "Manage repo-wide Entire policies", Hidden: true, PersistentPreRunE: func(cmd *cobra.Command, _ []string) error { if _, err := paths.WorktreeRoot(cmd.Context()); err != nil { return errors.New("not a git repository") } return nil }, } cmd.AddCommand(newPolicyCheckpointCmd()) return cmd }
Dcmd/entire/cli/policy_group.go-24
83 unmodified lines
84 85 86 87 87 88 89
83 unmodified lines
// Noun groups (canonical homes for subcommands). cmd.AddCommand(newSessionsCmd()) // 'session' (with 'sessions' as Cobra alias) cmd.AddCommand(newCheckpointGroupCmd()) // 'checkpoint' / 'cp' / 'checkpoints' cmd.AddCommand(newPolicyCmd()) // 'policy' cmd.AddCommand(newTokensGroupCmd()) // 'tokens' cmd.AddCommand(newAgentGroupCmd()) // 'agent' cmd.AddCommand(newAuthCmd()) // 'auth'
Mcmd/entire/cli/root.go-1
233 unmodified lines
234 235 236 237 237 238 239 240 241 242 242 243 244 244 245 246 247 246 247 248 249 250 251 252 249 250 251 254 255 252 253 254 255 256 257 258
233 unmodified lines
} }
func TestPolicyCommandIsHiddenDuringDevelopment(t *testing.T) { func TestCheckpointPolicyCommandIsHiddenDuringDevelopment(t *testing.T) { t.Parallel()
root := NewRootCmd()
policy, _, err := root.Find([]string{"policy"}) checkpointPolicy, remaining, err := root.Find([]string{"checkpoint", "policy"}) if err != nil { t.Fatalf("find policy command: %v", err) } if !policy.Hidden { t.Fatal("policy command should be hidden while it is in active development") } if len(remaining) != 0 || checkpointPolicy.Use != "policy" { t.Fatalf("checkpoint policy resolved to %q with remaining args %v", checkpointPolicy.Use, remaining) } } checkpointPolicy, _, err := root.Find([]string{"policy", "checkpoint"}) if err != nil { t.Fatalf("find policy checkpoint command: %v", err) } if !checkpointPolicy.Hidden { t.Fatal("checkpoint policy should be hidden while it is in active development") } if checkpointPolicy.Hidden { t.Fatal("policy checkpoint should remain invokable through the hidden policy group") }
topLevelPolicy, remaining, err := root.Find([]string{"policy"}) if err == nil && len(remaining) == 0 && topLevelPolicy.Use == "policy" { t.Fatal("top-level policy command should not remain after moving policy under checkpoint") } }