ADR 0573 §2 has every module build against the latest published version of each mesh package it uses, chosen by the planner and written by the build, never pinned by hand (issue 1585, S4). The ask, the fetch request and the merge preview now carry the packages and their versions, and the new-form fingerprint takes each version, so a package's trunk merge changes every dependent's fingerprint. A module using no package keeps its fingerprint. Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
65 lines
2.9 KiB
Go
65 lines
2.9 KiB
Go
package buildstep
|
|
|
|
import (
|
|
"reflect"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// A build's fetch is handed the paths of a module that names them (novox/hq ADR 0499 clause 4): the builder fills them
|
|
// from the indexer's kept inputs and the build module reads them from the call, never from the manifest (ADR 0495
|
|
// clause 1). The request survives the trip through a tool call's arguments.
|
|
func TestAFetchRequestCarriesTheNamedPathsThroughTheToolCall(t *testing.T) {
|
|
// And the versions of the mesh packages to build against (novox/hq ADR 0573 §2; issue 1585 S4).
|
|
req := FetchRequest{Repository: "novox/mesh-sdk", Commit: strings.Repeat("a", 40), Ref: "refs/pull/7/head",
|
|
Dir: ".", Paths: []string{"package.json", "src"}, Packages: map[string]string{"git.novox.be/novox/mesh-sdk/go": strings.Repeat("d", 40)}}
|
|
args := req.Args()
|
|
// A tool call's arguments arrive as JSON: lists of any, objects of any.
|
|
args["paths"] = []any{"package.json", "src"}
|
|
if p, ok := args["packages"].(map[string]any); !ok || p["git.novox.be/novox/mesh-sdk/go"] != strings.Repeat("d", 40) {
|
|
t.Fatalf("the packages are not in the call's arguments: %v", args["packages"])
|
|
}
|
|
got, err := ParseFetchRequest(args)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !reflect.DeepEqual(got, req) {
|
|
t.Fatalf("got %+v, want %+v", got, req)
|
|
}
|
|
plain, err := ParseFetchRequest(map[string]any{"repository": "novox/x", "commit": strings.Repeat("b", 40),
|
|
"base": strings.Repeat("c", 40), "beside": []any{}})
|
|
if err != nil || plain.Paths != nil || plain.Base != strings.Repeat("c", 40) {
|
|
t.Fatalf("a request without paths: %+v, %v", plain, err)
|
|
}
|
|
|
|
ok := map[string]any{"repository": "novox/x", "commit": strings.Repeat("b", 40)}
|
|
for _, c := range []struct {
|
|
set map[string]any
|
|
says string
|
|
}{
|
|
{map[string]any{"repository": "novox"}, "is not a repository"},
|
|
{map[string]any{"repository": "novox/../x"}, "is not a repository"},
|
|
{map[string]any{"commit": "abc"}, "is not a full commit"},
|
|
{map[string]any{"base": "abc"}, "is not a trunk commit"},
|
|
{map[string]any{"paths": []any{"src"}}, "names no module directory"},
|
|
{map[string]any{"dir": "modules/a", "paths": []any{"../b"}}, "leaves the module's directory"},
|
|
{map[string]any{"dir": "../a", "paths": []any{"src"}}, "leaves the repository"},
|
|
{map[string]any{"dir": "modules/a", "paths": []any{3}}, "paths is a list of strings"},
|
|
{map[string]any{"dir": "modules/a"}, "names a module directory and no path"},
|
|
{map[string]any{"packages": map[string]any{"git.novox.be/novox/mesh-sdk/go": "v0.1.7"}}, "no full commit"},
|
|
{map[string]any{"packages": map[string]any{"a b": strings.Repeat("d", 40)}}, "no module path"},
|
|
{map[string]any{"packages": []any{"x"}}, "packages is an object"},
|
|
} {
|
|
args := map[string]any{}
|
|
for k, v := range ok {
|
|
args[k] = v
|
|
}
|
|
for k, v := range c.set {
|
|
args[k] = v
|
|
}
|
|
if _, err := ParseFetchRequest(args); err == nil || !strings.Contains(err.Error(), c.says) {
|
|
t.Errorf("%v: %v, wanted a refusal saying %q", c.set, err, c.says)
|
|
}
|
|
}
|
|
}
|