Resolve committed module identity from Git objects

This commit is contained in:
2026-10-10 14:20:09 +00:00
parent 7eebbbbfc3
commit 54cc6baf95
13 changed files with 478 additions and 158 deletions

View File

@@ -2,6 +2,7 @@ package releaseidentity
import (
"context"
"errors"
"os"
"os/exec"
"path/filepath"
@@ -134,6 +135,85 @@ func TestCommittedAndWorkingTreeDeclarationsUseTheirOwnSources(t *testing.T) {
}
}
func TestCommittedIdentityFollowsCapturedDeclarationAndDirectoryLinks(t *testing.T) {
repository := t.TempDir()
gitIdentityRun(t, repository, "init", "-q")
gitIdentityRun(t, repository, "config", "user.name", "ReleaseKit test")
gitIdentityRun(t, repository, "config", "user.email", "releasekit@example.invalid")
moduleDir := filepath.Join(repository, "nested")
if err := os.Mkdir(moduleDir, 0o755); err != nil {
t.Fatal(err)
}
declaration := filepath.Join(repository, "module.txt")
if err := os.WriteFile(declaration, []byte("module example.com/committed\n"), 0o644); err != nil {
t.Fatal(err)
}
if err := os.Symlink("../module.txt", filepath.Join(moduleDir, "go.mod")); err != nil {
t.Fatal(err)
}
if err := os.Symlink("nested", filepath.Join(repository, "selected")); err != nil {
t.Fatal(err)
}
gitIdentityRun(t, repository, "add", ".")
gitIdentityRun(t, repository, "commit", "-qm", "Add linked declaration")
commit := strings.TrimSpace(gitIdentityOutput(t, repository, "rev-parse", "HEAD"))
if err := os.WriteFile(declaration, []byte("module example.com/working\n"), 0o644); err != nil {
t.Fatal(err)
}
committed, err := FromCommitted(t.Context(), repository, "selected", "v1.2.3", commit)
if err != nil || committed.ModulePath != "example.com/committed" || committed.ModuleDir != moduleDir || committed.Tag != "nested/v1.2.3" {
t.Fatalf("committed linked identity = %#v, error = %v", committed, err)
}
working, err := FromWorkingTree(t.Context(), repository, "selected", "v1.2.3")
if err != nil || working.ModulePath != "example.com/working" || working.ModuleDir != moduleDir {
t.Fatalf("working linked identity = %#v, error = %v", working, err)
}
ctx, cancel := context.WithCancel(t.Context())
cancel()
if _, err := FromCommitted(ctx, repository, "selected", "v1.2.3", commit); !errors.Is(err, context.Canceled) {
t.Fatalf("canceled committed identity error = %v", err)
}
}
func TestCommittedIdentityPreservesReferenceFailures(t *testing.T) {
for _, mode := range []string{"cycle", "outside", "missing", "unavailable blob"} {
t.Run(mode, func(t *testing.T) {
repository := t.TempDir()
gitIdentityRun(t, repository, "init", "-q")
gitIdentityRun(t, repository, "config", "user.name", "ReleaseKit test")
gitIdentityRun(t, repository, "config", "user.email", "releasekit@example.invalid")
target, wantCause := "go.mod", "symlink-cycle"
switch mode {
case "outside":
target, wantCause = "../module.txt", "outside-checkout"
case "missing":
target, wantCause = "missing.mod", "missing"
case "unavailable blob":
target, wantCause = "module.txt", "read selected module declaration"
if err := os.WriteFile(filepath.Join(repository, target), []byte("module example.com/linked\n"), 0o644); err != nil {
t.Fatal(err)
}
}
if err := os.Symlink(target, filepath.Join(repository, "go.mod")); err != nil {
t.Fatal(err)
}
gitIdentityRun(t, repository, "add", ".")
gitIdentityRun(t, repository, "commit", "-qm", "Add reference fixture")
commit := strings.TrimSpace(gitIdentityOutput(t, repository, "rev-parse", "HEAD"))
if mode == "unavailable blob" {
object := strings.TrimSpace(gitIdentityOutput(t, repository, "rev-parse", "HEAD:module.txt"))
if err := os.Remove(filepath.Join(repository, ".git", "objects", object[:2], object[2:])); err != nil {
t.Fatal(err)
}
}
identity, err := FromCommitted(t.Context(), repository, ".", "v1.2.3", commit)
if err == nil || !strings.Contains(err.Error(), wantCause) || identity.RepositoryDir != repository || identity.ModuleDir != repository {
t.Fatalf("identity = %#v, error = %v; want %s", identity, err, wantCause)
}
})
}
}
func TestSelectedNestedModuleDoesNotRequireRootDeclaration(t *testing.T) {
repository := t.TempDir()
moduleDir := filepath.Join(repository, "nested")