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)
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:
@@ -320,10 +320,11 @@ func build(ctx context.Context, run Runner, publish Publisher,
|
||||
if fingerprint == "" {
|
||||
say("source", "no source fingerprint: %s", orNoTree(src.unpinned))
|
||||
}
|
||||
// **Only a trunk build says its build source** (novox/hq ADR 0267): the planner maps the next merge onto
|
||||
// the build source of the trunk's last build, and a branch's closure is not the trunk's.
|
||||
// **Only a build of the trunk's head says its build source** (novox/hq ADR 0267): the planner maps the
|
||||
// next merge onto the build source of the newest build, and a branch's closure — or an older trunk
|
||||
// commit's, built by hand — is not the trunk's. Nor does a build whose context was not its trunk's head.
|
||||
var sources []BuildSource
|
||||
if trunk != "" && onTrunk {
|
||||
if trunk != "" && onTrunk && src.contextsAtHead && atTrunkHead(ctx, run, tree, commit, trunk) {
|
||||
sources = src.buildSources()
|
||||
for _, s := range sources {
|
||||
where := "its own repository"
|
||||
@@ -380,6 +381,28 @@ func trunkOf(ctx context.Context, run Runner, clone, commit string) (string, boo
|
||||
return trunk, err == nil
|
||||
}
|
||||
|
||||
// atTrunkHead is whether a clone's commit is its trunk's head as the clone holds it.
|
||||
func atTrunkHead(ctx context.Context, run Runner, clone, commit, trunk string) bool {
|
||||
head, err := run(ctx, clone, "git", "rev-parse", "origin/"+trunk)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
at, err := run(ctx, clone, "git", "rev-parse", commit)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return strings.TrimSpace(head) != "" && strings.TrimSpace(head) == strings.TrimSpace(at)
|
||||
}
|
||||
|
||||
// cleanEntry is a path of the module's directory as an entry: cleaned, relative, `.` for the directory.
|
||||
func cleanEntry(p string) string {
|
||||
c := strings.Trim(path.Clean("/"+filepath.ToSlash(p)), "/")
|
||||
if c == "" {
|
||||
return "."
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// orNoTree is why a build has no source fingerprint, for its log.
|
||||
func orNoTree(why string) string {
|
||||
if why == "" {
|
||||
@@ -684,6 +707,9 @@ func one(ctx context.Context, run Runner, publish Publisher,
|
||||
src.contexts[a.Name] = t
|
||||
}
|
||||
buildDir = cloned
|
||||
if t, _ := trunkOf(ctx, run, cloned, "HEAD"); t == "" || !atTrunkHead(ctx, run, cloned, "HEAD", t) {
|
||||
src.contextOffHead()
|
||||
}
|
||||
}
|
||||
// docker build accepts -f outside the context it is given; the recipe stays exactly where it was
|
||||
// read from and validated against, absolute so a context elsewhere does not change which file
|
||||
@@ -722,7 +748,7 @@ func one(ctx context.Context, run Runner, publish Publisher,
|
||||
src.readWhole(*a.Context)
|
||||
}
|
||||
if a.Compiles != "" || a.Context != nil {
|
||||
src.ownHas(a.From)
|
||||
src.ownHas(cleanEntry(a.From))
|
||||
} else {
|
||||
src.ownWhole()
|
||||
}
|
||||
@@ -844,7 +870,7 @@ func one(ctx context.Context, run Runner, publish Publisher,
|
||||
return catalogue.Built{Name: a.Name, Kind: a.Kind, Reference: reference}, nil
|
||||
|
||||
case catalogue.ArtifactArchive:
|
||||
src.ownHas(strings.Trim(path.Clean("/"+filepath.ToSlash(a.From)), "/") + "/**")
|
||||
src.ownHas(cleanEntry(a.From) + "/**")
|
||||
body, err := pack(filepath.Join(tree, a.From))
|
||||
if err != nil {
|
||||
return catalogue.Built{}, fmt.Errorf("%s: packing %s failed: %w", module, a.Name, err)
|
||||
|
||||
Reference in New Issue
Block a user