Files
mesh-catalog/checks/trunk/trunk.go
T

91 lines
3.5 KiB
Go

// Package trunk is where a catalogue check finds the trunk's copy of a list that may only shrink (novox/hq ADR 0529 clause 2):
// the file as the catalogue's base commit holds it, to judge a change's list against.
//
// A check in a merge check finds it in the clone of the change's own repository at its base commit, which the checker places
// beside the change in MESH_CHECK_BESIDE as it places a sibling, under the repository's name. Run by hand, without that
// directory, it reads the file from git at the merge base with origin/<MESH_CHECK_BASE, main when unset>, as the script this
// replaces did. A trunk that holds no such file had none: the list's first copy, which nothing was added to. Where no base
// can be found at all, the comparison is not made, and the test says so in its log: NOT COMPARED, never a pass that looks like one.
package trunk
import (
"errors"
"os"
"os/exec"
"path/filepath"
"strings"
"testing"
)
// Repository is the catalogue's name beside a check.
const Repository = "mesh-catalog"
// BesideEnv is where a merge check says the clones beside the one checked are.
const BesideEnv = "MESH_CHECK_BESIDE"
// Copy is the trunk's copy of the file at rel (a path from the catalogue's root), written to a file of the test's own: its
// path, and whether there is one. False with a log line when the trunk holds none or cannot be read; the caller then judges
// the list as a first copy.
func Copy(t testing.TB, rel string) (string, bool) {
t.Helper()
raw, found, how := Read(rel, "../..")
if how != "" {
t.Log(how)
}
if !found {
return "", false
}
path := filepath.Join(t.TempDir(), filepath.Base(rel))
if err := os.WriteFile(path, raw, 0o644); err != nil {
t.Fatal(err)
}
return path, true
}
// Read is the trunk's copy of rel, whether the trunk holds one, and a line to log when the comparison was not made or
// where it was made. root is the catalogue's checkout (for git).
func Read(rel, root string) (content []byte, found bool, say string) {
if beside := os.Getenv(BesideEnv); beside != "" {
dir := filepath.Join(beside, Repository)
if _, err := os.Stat(dir); err == nil {
raw, err := os.ReadFile(filepath.Join(dir, rel))
if errors.Is(err, os.ErrNotExist) {
return nil, false, "the trunk holds no " + rel + " (read from " + dir + "): its first copy"
}
if err != nil {
return nil, false, "NOT COMPARED WITH THE TRUNK: " + err.Error()
}
return raw, true, "judged against the trunk's " + rel + " in " + dir
}
}
base := "origin/" + firstOf(os.Getenv("MESH_CHECK_BASE"), "main")
mergeBase, err := git(root, "merge-base", "HEAD", base)
if err != nil {
return nil, false, "NOT COMPARED WITH THE TRUNK: no merge base with " + base + ", and no clone of the trunk in " + BesideEnv +
"; " + rel + " is held to the list it was first written with"
}
raw, err := git(root, "show", strings.TrimSpace(string(mergeBase))+":"+rel)
if err != nil {
if _, exists := git(root, "cat-file", "-e", strings.TrimSpace(string(mergeBase))+":"+rel); exists != nil {
return nil, false, "the trunk holds no " + rel + " at the merge base: its first copy"
}
return nil, false, "NOT COMPARED WITH THE TRUNK: " + err.Error()
}
return raw, true, "judged against the trunk's " + rel + " at the merge base with " + base
}
func git(dir string, args ...string) ([]byte, error) {
cmd := exec.Command("git", args...)
cmd.Dir = dir
return cmd.Output()
}
func firstOf(s ...string) string {
for _, x := range s {
if x != "" {
return x
}
}
return ""
}