91 lines
3.5 KiB
Go
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 ""
|
|
}
|