simplify checkpoint policy state · Entire
simplify checkpoint policy state
0d5ec03·
pfleidi·3w ago·7 files·+40 added/-63 removed
Share remote baseline loading between policy sync and update.
Keep checkpoint policy state focused on data by removing test-only format knowledge, target labels, and preformatted warning text.
Sessions
0e1a4e82890cView transcript
Changes
7
cmd/entire/cli
checkpointpolicy
Mformat.go+2/-13
Mformat_test.go-2
Mremote.go+30/-25
Mremote_test.go-1
Mstore.go-1
Mupdate.go+2/-20
52 unmodified lines
53
54
55
56
57
58
59
60
56
57
58
18 unmodified lines
77
78
79
80
81
82
86
87
88
89
90
91
92
93
83
84
85
52 unmodified lines
return compareInt(a.Major, b.Major)
}
func KnowsFormat(format CheckpointFormat) bool {
_, ok := knownFormats[format]
return ok
}
func CanRead(format CheckpointFormat) bool {
return readFormats[format]
}
18 unmodified lines
CheckpointFamilyRefs: 1,
}
var branchV1Format = CheckpointFormat{Family: CheckpointFamilyBranch, Major: 1}
var (
branchV1Format = CheckpointFormat{Family: CheckpointFamilyBranch, Major: 1}
refsV1Format = CheckpointFormat{Family: CheckpointFamilyRefs, Major: 1}
knownFormats = map[CheckpointFormat]struct{}{
branchV1Format: {},
refsV1Format: {},
}
readFormats = map[CheckpointFormat]bool{
branchV1Format: true,
}
Mcmd/entire/cli/checkpointpolicy/format.go+2/-13
44 unmodified lines
45
46
47
48
48
49
50
51
53
52
53
54
44 unmodified lines
refsV1, err := checkpointpolicy.ParseFormat("refs-v1")
require.NoError(t, err)
require.True(t, checkpointpolicy.KnowsFormat(branchV1))
require.True(t, checkpointpolicy.CanRead(branchV1))
require.True(t, checkpointpolicy.CanWrite(branchV1))
require.Equal(t, checkpoint.CheckpointVersionBranchV1, branchV1.String())
require.True(t, checkpointpolicy.KnowsFormat(refsV1))
require.False(t, checkpointpolicy.CanRead(refsV1))
require.False(t, checkpointpolicy.CanWrite(refsV1))
require.Negative(t, checkpointpolicy.Compare(branchV1, refsV1))
Mcmd/entire/cli/checkpointpolicy/format_test.go-2
20 unmodified lines
21
22
23
24
24
25
26
13 unmodified lines
40
41
42
44
43
44
46
45
46
47
48
50
51
52
53
54
49
50
51
52
17 unmodified lines
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
80
97
98
99
83
100
101
102
103
104
88
105
106
107
108
109
93
110
111
112
113
97
98
99
100
101
102
103
104
105
106
107
108
109
114
115
116
117
20 unmodified lines
type Target struct {
Remote string
Label string
Dir string
}
13 unmodified lines
if target, dedicated, err := remote.ConfiguredURL(ctx, baseRemote, dir); err != nil {
return Target{}, fmt.Errorf("resolve checkpoint remote URL: %w", err)
} else if dedicated {
return Target{Remote: target, Label: "checkpoint remote", Dir: dir}, nil
}
target, dedicated, err := remote.PushURL(ctx, baseRemote)
target, _, err := remote.PushURL(ctx, baseRemote)
if err != nil {
return Target{}, fmt.Errorf("resolve checkpoint push URL: %w", err)
}
label := baseRemote
if dedicated {
label = "checkpoint remote"
}
return Target{Remote: target, Label: label, Dir: dir}, nil
return Target{Remote: target, Dir: dir}, nil
}
func CheckRemote(ctx context.Context, target Target) (RemoteState, error) {
17 unmodified lines
return State{}, err
}
baseline, remoteFound, err := remoteBaseline(ctx, repo, target, local)
if err != nil {
return State{}, err
}
if !remoteFound || local.Hash == baseline.Hash {
if err := SetRef(repo, RefName, baseline.Hash); err != nil {
return State{}, err
}
baseline.Source = SourceRemote
return baseline, nil
}
if local.Hash.IsZero() || isAncestorOf(ctx, repo, local.Hash, baseline.Hash) {
if err := SetRef(repo, RefName, baseline.Hash); err != nil {
return State{}, err
}
baseline.Source = SourceRemote
return baseline, nil
}
local.Source = SourceLocalDiverged
local.RemoteHash = baseline.RemoteHash
return local, nil
}
func remoteBaseline(ctx context.Context, repo *git.Repository, target Target, local State) (State, bool, error) {
remoteState, err := CheckRemote(ctx, target)
if err != nil {
return State{}, err
return State{}, false, err
}
if !remoteState.Exists {
return local, nil
return local, false, nil
}
if local.Hash == remoteState.Hash {
local.Source = SourceRemote
local.RemoteHash = remoteState.Hash
return local, nil
return local, true, nil
}
fetched, err := fetchRemotePolicy(ctx, repo, target)
if err != nil {
return State{}, err
return State{}, false, err
}
fetched.RemoteHash = remoteState.Hash
defer removeFetchRef(repo)
if local.Hash.IsZero() || isAncestorOf(ctx, repo, local.Hash, fetched.Hash) {
if err := SetRef(repo, RefName, fetched.Hash); err != nil {
return State{}, err
}
fetched.Source = SourceRemote
return fetched, nil
}
local.Source = SourceLocalDiverged
local.RemoteHash = remoteState.Hash
local.Warning = fmt.Sprintf("local checkpoint policy %s diverges from remote %s", local.Hash, remoteState.Hash)
return local, nil
return fetched, true, nil
}
func Push(ctx context.Context, target Target) error {
Mcmd/entire/cli/checkpointpolicy/remote.go+30/-25
130 unmodified lines
131
132
133
134
134
135
136
130 unmodified lines
target, err := checkpointpolicy.ResolveTarget(t.Context(), "origin")
require.NoError(t, err)
require.Equal(t, "git@github.com:org/checkpoints.git", target.Remote)
require.Equal(t, "checkpoint remote", target.Label)
wantDir, err := filepath.EvalSymlinks(localDir)
require.NoError(t, err)
gotDir, err := filepath.EvalSymlinks(target.Dir)
Mcmd/entire/cli/checkpointpolicy/remote_test.go-1
31 unmodified lines
32
33
34
35
35
36
37
31 unmodified lines
Source Source
Hash plumbing.Hash
RemoteHash plumbing.Hash
Warning string
}
func ReadLocal(ctx context.Context, repo *git.Repository) (State, error) {
Mcmd/entire/cli/checkpointpolicy/store.go-1
51 unmodified lines
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
55
56
57
58
59
51 unmodified lines
return State{}, err
}
remoteState, err := CheckRemote(ctx, target)
if err != nil {
return State{}, err
}
if !remoteState.Exists {
return local, nil
}
if local.Hash == remoteState.Hash {
local.Source = SourceRemote
local.RemoteHash = remoteState.Hash
return local, nil
}
fetched, err := fetchRemotePolicy(ctx, repo, target)
if err != nil {
return State{}, err
}
fetched.RemoteHash = remoteState.Hash
defer removeFetchRef(repo)
return fetched, nil
baseline, _, err := remoteBaseline(ctx, repo, target, local)
return baseline, err
}
func rejectDowngrades(before, after Policy, opts UpdateOptions) error {
Mcmd/entire/cli/checkpointpolicy/update.go+2/-20
72 unmodified lines
73
74
75
76
76
77
78
79
80
81
82
83
84
72 unmodified lines
func warnOrLogCheckpointPolicyDiverged(ctx context.Context, state checkpointpolicy.State) {
if interactive.CanPromptInteractively() {
fmt.Fprintf(stderrWriter, "[entire] Could not reconcile checkpoint policy: %s\n", state.Warning)
fmt.Fprintf(
stderrWriter,
"[entire] Could not reconcile checkpoint policy: local checkpoint policy %s diverges from remote %s\n",
state.Hash,
state.RemoteHash,
)
return
}
logging.Warn(ctx, "checkpoint policy diverged; skipping checkpoint push",
Mcmd/entire/cli/strategy/checkpoint_policy.go+6/-1