package buildstep import ( "os" "path/filepath" "sort" "strings" "testing" ) func filesUnder(t *testing.T, root string) []string { t.Helper() var out []string _ = filepath.Walk(root, func(p string, info os.FileInfo, err error) error { if err == nil && !info.IsDir() { rel, _ := filepath.Rel(root, p) out = append(out, filepath.ToSlash(rel)) } return nil }) sort.Strings(out) return out } // A build of an artifact that names its paths sees only those paths, its manifest and its lock files (novox/hq ADR 0499 // clause 4): Narrow removes everything else of the fetched tree but .git, package.json and go.mod among it, since // neither is in the named tree nor among the lock files; with no paths it changes nothing. func TestNarrowLeavesOnlyTheNamedPathsTheManifestAndTheLocks(t *testing.T) { tree := t.TempDir() for _, f := range []string{".git/HEAD", "module.json", "package.json", "package-lock.json", "go.sum", "src/index.ts", "src/deep/a.ts", "test/a.test.ts", "tsconfig.json", "go/delivery/x.go", "README.md", "other/module.json"} { writeTreeFile(t, tree, f, "x") } if err := Narrow(tree, FetchRequest{}); err != nil { t.Fatal(err) } if got := len(filesUnder(t, tree)); got != 12 { t.Fatalf("a request without paths changed the tree: %d files", got) } if err := Narrow(tree, FetchRequest{Dir: ".", Paths: []string{"src", "test", "tsconfig.json"}}); err != nil { t.Fatal(err) } want := ".git/HEAD,go.sum,module.json,package-lock.json,src/deep/a.ts,src/index.ts,test/a.test.ts,tsconfig.json" if got := strings.Join(filesUnder(t, tree), ","); got != want { t.Fatalf("the narrowed tree holds %s\nwant %s", got, want) } } func TestNarrowKeepsAModuleDirectorysPathsAndFailsOnAnAbsentOne(t *testing.T) { tree := t.TempDir() for _, f := range []string{".git/config", "modules/a/module.json", "modules/a/go.mod", "modules/a/src/x.ts", "modules/a/notes.md", "modules/b/module.json", "root.txt"} { writeTreeFile(t, tree, f, "x") } err := Narrow(tree, FetchRequest{Dir: "modules/a", Paths: []string{"src", "gone"}}) if err == nil || !strings.Contains(err.Error(), `"gone"`) { t.Fatalf("an absent named path gave %v", err) } if len(filesUnder(t, tree)) != 7 { t.Fatal("a refused narrowing removed files") } if err := Narrow(tree, FetchRequest{Dir: "modules/a", Paths: []string{"src"}}); err != nil { t.Fatal(err) } if got := strings.Join(filesUnder(t, tree), ","); got != ".git/config,modules/a/module.json,modules/a/src/x.ts" { t.Fatalf("the narrowed tree holds %s", got) } } // A build that needs package.json or go.mod names it among its paths, and so keys on it (ADR 0499 clause 4). func TestNarrowKeepsAManifestOfTheLanguageOnlyWhenNamed(t *testing.T) { tree := t.TempDir() for _, f := range []string{"module.json", "package.json", "go.mod", "src/a.ts"} { writeTreeFile(t, tree, f, "x") } if err := Narrow(tree, FetchRequest{Dir: ".", Paths: []string{"src", "package.json"}}); err != nil { t.Fatal(err) } if got := strings.Join(filesUnder(t, tree), ","); got != "module.json,package.json,src/a.ts" { t.Fatalf("the narrowed tree holds %s", got) } }