Say a build source only for the trunk's head, and hold what C, assembly and a new go.mod reach (hq ADR 0267, review)
mesh/merge-gate pass: builds build-agent, mesh-controller, route-proxy → ace, g14, novox, shanks; no bus step; every machine composes with the change as it…
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery superseded: a newer head of the same pull request

A hand build of an older trunk commit said a closure lacking what was
imported since, and the planner would have mapped the next merge onto it.
C and assembly beside Go may include files below their directory, and a
go.mod made above a package moves it out of its module: each is now held.
This commit is contained in:
jochen
2026-10-10 03:11:06 +02:00
parent 4d1b81b6cb
commit abe5f7dc17
5 changed files with 146 additions and 15 deletions
+41
View File
@@ -185,6 +185,10 @@ func GoBuildSource(root, pkg string) ([]string, error) {
}
seen[dir] = true
entries[goPackageDirEntry(dir)] = true
// A go.mod made between the module's root and a package moves that package out of the module.
for up := dir; up != modRoot && up != "." && up != "/" && !strings.HasPrefix(up, "../"); up = path.Dir(up) {
file(up, "go.mod")
}
listing, err := os.ReadDir(filepath.Join(root, filepath.FromSlash(dir)))
if err != nil {
// A package that is not there fails the build that imports it; its directory is held, so
@@ -193,6 +197,18 @@ func GoBuildSource(root, pkg string) ([]string, error) {
}
for _, f := range listing {
name := f.Name()
// **C and assembly beside Go** may include files from below the package's directory: the
// directory is held whole, and an include reaching above it is refused.
if !f.IsDir() && nativeSource(name) {
entries[strings.TrimPrefix(dir+"/**", "./")] = true
if dir == "." {
entries["**"] = true
}
if err := includesStayWithin(filepath.Join(root, filepath.FromSlash(dir), name)); err != nil {
return nil, fmt.Errorf("%s: %w", path.Join(dir, name), err)
}
continue
}
if f.IsDir() || !strings.HasSuffix(name, ".go") || strings.HasSuffix(name, "_test.go") {
continue
}
@@ -359,6 +375,31 @@ func goFileReads(file string) (imports, embeds []string, err error) {
return imports, embeds, scanner.Err()
}
// nativeSource is a file the Go command compiles or links beside Go: C, C++, Objective-C, Fortran,
// assembly, their headers and a system object.
func nativeSource(name string) bool {
switch strings.ToLower(path.Ext(name)) {
case ".c", ".h", ".cc", ".cpp", ".cxx", ".hh", ".hpp", ".hxx", ".m", ".s", ".sx", ".f", ".f90", ".for", ".syso":
return true
}
return false
}
// includesStayWithin refuses a native source whose #include names a path above its directory.
func includesStayWithin(file string) error {
body, err := os.ReadFile(file)
if err != nil {
return err
}
for _, line := range strings.Split(string(body), "\n") {
line = strings.TrimSpace(line)
if strings.HasPrefix(line, "#") && strings.Contains(line, "include") && strings.Contains(line, "..") {
return errors.New("it includes a path outside its directory: " + line)
}
}
return nil
}
// embedPatterns splits a //go:embed line's patterns: separated by spaces, each possibly quoted.
func embedPatterns(s string) ([]string, error) {
var out []string