diff --git a/go/packages_list_test.go b/go/packages_list_test.go new file mode 100644 index 0000000..8d224e0 --- /dev/null +++ b/go/packages_list_test.go @@ -0,0 +1,76 @@ +package stdio + +import ( + "go/ast" + "go/parser" + "go/token" + "io/fs" + "path/filepath" + "slices" + "strings" + "testing" +) + +// meshSDKPackages is every package mesh-sdk holds (novox/hq ADR 0593 §1): what every module shares, the value shapes +// and names more than one part reads, and the seat contracts it holds until they move into SDK modules (issue 167). +// Logic only some modules need is its owner module's package. A package added here is a decision to say in the pull +// request: does every module share it, or is it a shape more than one part reads? +var meshSDKPackages = []string{ + ".", "announce", "announcetest", "asker", "asks", "buildstep", "buscompose", "busretry", "calladdress", "catalogue", + "composer", "declaration", "delivery", "forgekey", "handacts", "health", "internal/beside", "kvlimit", "membership", + "objectlink", "outward", "overlay", "pernode", "process", "provider", "provider/harness", "provisions", + "sdkversion", "seal", "testbus", +} + +// computesNot are the functions whose computation is one owner's alone (ADR 0593 §2, §7): the indexer computes a +// fingerprint, its named tree and a package's version; the node-engine composes. +var computesNot = []string{"SourceFingerprint", "SourceFingerprint2", "NamedTree", "MeshPackagesOf", "PackageVersionsOf", + "OtherPackages", "Compose", "CompositionsShadow", "JudgeMove", "Run"} + +// ADR 0593 §1's check: mesh-sdk holds exactly the packages it keeps, and none of them computes what one owner alone +// computes. +func TestMeshSDKHoldsOnlyWhatEveryModuleShares(t *testing.T) { + var found []string + err := filepath.WalkDir(".", func(path string, d fs.DirEntry, err error) error { + if err != nil { + return err + } + if d.IsDir() { + if n := d.Name(); n == "testdata" || (strings.HasPrefix(n, ".") && path != ".") { + return filepath.SkipDir + } + return nil + } + if !strings.HasSuffix(path, ".go") || strings.HasSuffix(path, "_test.go") { + return nil + } + dir := filepath.ToSlash(filepath.Dir(path)) + if !slices.Contains(found, dir) { + found = append(found, dir) + } + file, err := parser.ParseFile(token.NewFileSet(), path, nil, parser.SkipObjectResolution) + if err != nil { + return err + } + for _, decl := range file.Decls { + if fn, ok := decl.(*ast.FuncDecl); ok && fn.Recv == nil && slices.Contains(computesNot, fn.Name.Name) { + t.Errorf("%s: %s computes what its owner alone computes (ADR 0593 §2, §7)", path, fn.Name.Name) + } + } + return nil + }) + if err != nil { + t.Fatal(err) + } + slices.Sort(found) + for _, dir := range found { + if !slices.Contains(meshSDKPackages, dir) { + t.Errorf("mesh-sdk holds the package %s, which it does not keep (ADR 0593 §1): it is its owner module's package", dir) + } + } + for _, want := range meshSDKPackages { + if !slices.Contains(found, want) { + t.Errorf("mesh-sdk's list keeps %s, which is gone: take it off the list", want) + } + } +}