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
5 changes: 4 additions & 1 deletion internal/schemas/manager/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,10 +231,13 @@ func (m *Manager) updateLock(l *lock) error {
return errors.Wrap(err, "failed to ensure schema directory exists")
}

bs, err := json.Marshal(l)
bs, err := json.MarshalIndent(l, "", " ")
if err != nil {
return errors.Wrap(err, "failed to serialize schema lock")
}
// Append a trailing newline so the file ends cleanly and edits to the last
// entry produce minimal diffs.
bs = append(bs, '\n')

if err := afero.WriteFile(m.fs, lockFileName, bs, 0o600); err != nil {
return errors.Wrap(err, "failed to write schema lock file")
Expand Down
32 changes: 32 additions & 0 deletions internal/schemas/manager/manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,38 @@ func TestManager_Add(t *testing.T) {
}
}

func TestUpdateLockIsIndented(t *testing.T) {
// The lock file must be written with one entry per line (indented) so it is
// human-readable and avoids spurious merge conflicts. See issue #168.
fs := afero.NewMemMapFs()
m := New(fs, nil, nil)

l := newLock()
l.Packages["xpkg://pkg.example/bar:v1.0.0"] = "sha256:bbb"
l.Packages["xpkg://pkg.example/foo:v0.5.2"] = "sha256:aaa"

if err := m.updateLock(l); err != nil {
t.Fatalf("updateLock: %v", err)
}

got, err := afero.ReadFile(fs, lockFileName)
if err != nil {
t.Fatalf("read lock: %v", err)
}

// Map keys are marshalled in sorted order, so this golden is deterministic.
want := `{
"packages": {
"xpkg://pkg.example/bar:v1.0.0": "sha256:bbb",
"xpkg://pkg.example/foo:v0.5.2": "sha256:aaa"
}
}
`
if diff := cmp.Diff(want, string(got)); diff != "" {
t.Errorf("lock file is not indented as expected (-want +got):\n%s", diff)
}
}

type mockGenerator struct {
files map[string]string
}
Expand Down