Accept a merged message with no trees, so a merge that leaves a repository with no module.json still reaches the indexer (issue 1126)

This commit is contained in:
2026-11-03 16:41:06 +01:00
parent 1b9475e15f
commit 413dd13fe3
2 changed files with 12 additions and 5 deletions
+4 -3
View File
@@ -688,9 +688,10 @@ func (f Forge) check() error {
if f.Root == "" {
return fmt.Errorf("delivery: a merged message needs the repository's root tree")
}
if len(f.Trees) == 0 {
return fmt.Errorf("delivery: a merged message needs the tree of at least one directory holding a module.json")
}
// No trees is a merge that leaves the repository with no module.json anywhere (a documents repository, or one
// whose last module was removed): it is written all the same, so the indexer takes the merge in and drops the
// repository's modules (novox/hq issue 1126). An older writer always sent at least one tree, so none is unambiguous;
// such a message carries no manifests, locks or paths (checkInputs below: each names a directory of its trees).
for dir, tree := range f.Trees {
if tree == "" {
return fmt.Errorf("delivery: a merged message's tree of the directory %q is empty", dir)
+8 -2
View File
@@ -272,9 +272,15 @@ func TestSourceValuesRefused(t *testing.T) { // 1200/AC4
_, err = EncodeForge(f)
wantErr("merged without root", err, "root")
f = sampleForges()[1]
f.Trees = nil
f.Trees, f.Manifests, f.Locks, f.Paths = nil, nil, nil, nil
if data, err := EncodeForge(f); err != nil {
t.Errorf("a merged message of a repository with no module.json is refused: %v", err)
} else if got, err := DecodeForge(data); err != nil || len(got.Trees) != 0 {
t.Errorf("a merged message with no trees comes back as %+v, %v", got, err)
}
f.Manifests = map[string]string{"modules/a": "{}"}
_, err = EncodeForge(f)
wantErr("merged without trees", err, "tree")
wantErr("merged with a manifest and no trees", err, "modules/a")
f = sampleForges()[1]
f.Trees = map[string]string{"modules/a": ""}
_, err = EncodeForge(f)