Add the repository-identity and trunk-build tests both delivery readers need (issue 1281)
mesh/repo-check head 84a764372337 merged into trunk 8360a3bba2b4 — pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (typescript)…
mesh/merge-gate head 84a764372337 merged into trunk 8360a3bba2b4 — pass: group fix/1281-trunk-builds-by-repository composed: every machine composes with th…
mesh/delivery delivered
mesh/delivery-group group fix/1281-trunk-builds-by-repository delivered: every member is delivered
mesh/repo-check head 84a764372337 merged into trunk 8360a3bba2b4 — pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (typescript)…
mesh/merge-gate head 84a764372337 merged into trunk 8360a3bba2b4 — pass: group fix/1281-trunk-builds-by-repository composed: every machine composes with th…
mesh/delivery delivered
mesh/delivery-group group fix/1281-trunk-builds-by-repository delivered: every member is delivered
A build record names its repository by clone URL and a plan-asked build carries no ref; the indexer and view compared both naively.
This commit is contained in:
@@ -0,0 +1,32 @@
|
|||||||
|
package delivery
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
|
// RepositoryName is the repository as the forge names it, "owner/name", from either spelling the mesh holds: the name
|
||||||
|
// itself, or the clone URL a build record carries ("http://host:port/owner/name.git", with or without ".git" or a
|
||||||
|
// trailing slash). A string of fewer than two path segments is returned as it is, trimmed (issue 1281).
|
||||||
|
func RepositoryName(s string) string {
|
||||||
|
s = strings.TrimSpace(s)
|
||||||
|
s = strings.TrimRight(s, "/")
|
||||||
|
s = strings.TrimSuffix(s, ".git")
|
||||||
|
s = strings.TrimRight(s, "/")
|
||||||
|
parts := strings.FieldsFunc(s, func(r rune) bool { return r == '/' || r == ':' })
|
||||||
|
if len(parts) < 2 {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
return parts[len(parts)-2] + "/" + parts[len(parts)-1]
|
||||||
|
}
|
||||||
|
|
||||||
|
// SameRepository is whether two spellings name one repository: the same owner and name, whichever way each is written
|
||||||
|
// (RepositoryName), compared without regard to case as the forge does. An empty spelling names none (issue 1281).
|
||||||
|
func SameRepository(a, b string) bool {
|
||||||
|
a, b = RepositoryName(a), RepositoryName(b)
|
||||||
|
return a != "" && strings.EqualFold(a, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsTrunkBuild is whether the record is a successful build of the trunk that recorded its source inputs: state built, and
|
||||||
|
// ref "main" or none. A build a delivery plan asked after a merge, or rebuild or build --behind, follows the branch
|
||||||
|
// without naming it, so it carries no ref; a build of any other branch or of a commit names it (issue 1281).
|
||||||
|
func (r BuildRecord) IsTrunkBuild() bool {
|
||||||
|
return r.State == "built" && r.SourceInputs != nil && (r.Ref == "" || r.Ref == "main")
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
package delivery
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSameRepository(t *testing.T) { // 1281/AC1
|
||||||
|
const forge = "novox/mesh-catalog"
|
||||||
|
for _, c := range []struct {
|
||||||
|
a, b string
|
||||||
|
same bool
|
||||||
|
}{
|
||||||
|
// the clone URL as a build record carries it (mesh-controller.command builds, 2026-10-19 ~21:20 local)
|
||||||
|
{forge, "http://novox.internal:20000/novox/mesh-catalog.git", true},
|
||||||
|
{forge, "http://novox.internal:20000/novox/mesh-catalog", true},
|
||||||
|
{forge, "http://novox.internal:20000/novox/mesh-catalog.git/", true},
|
||||||
|
{"http://novox.internal:20000/novox/mesh-catalog.git/", forge, true},
|
||||||
|
{forge, "novox/mesh-catalog", true},
|
||||||
|
{forge, "Novox/Mesh-Catalog", true},
|
||||||
|
{forge, "http://novox.internal:20000/novox/mesh-catalog-x.git", false},
|
||||||
|
{forge, "novox/mesh-catalog-x", false},
|
||||||
|
{forge, "http://novox.internal:20000/other/mesh-catalog.git", false},
|
||||||
|
{forge, "other/mesh-catalog", false},
|
||||||
|
{forge, "http://novox.internal:20000/novox/mesh-media-catalog.git", false},
|
||||||
|
{forge, "", false},
|
||||||
|
{"", "", false},
|
||||||
|
} {
|
||||||
|
if got := SameRepository(c.a, c.b); got != c.same {
|
||||||
|
t.Errorf("SameRepository(%q, %q) = %v, want %v", c.a, c.b, got, c.same)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if got := RepositoryName("http://novox.internal:20000/novox/mesh-catalog.git"); got != "novox/mesh-catalog" {
|
||||||
|
t.Errorf("RepositoryName = %q", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestIsTrunkBuild(t *testing.T) { // 1281/AC2
|
||||||
|
inputs := &SourceInputs{Module: "zsh", Tree: "t"}
|
||||||
|
for _, c := range []struct {
|
||||||
|
name string
|
||||||
|
r BuildRecord
|
||||||
|
want bool
|
||||||
|
}{
|
||||||
|
{"built on main", BuildRecord{State: "built", Ref: "main", SourceInputs: inputs}, true},
|
||||||
|
// a build a delivery plan asked after a merge, or rebuild / build --behind, carries no ref (live builds,
|
||||||
|
// 2026-10-19: zsh build-1792417485811374131, mesh-delivery build-1792435539606203626)
|
||||||
|
{"built with no ref", BuildRecord{State: "built", SourceInputs: inputs}, true},
|
||||||
|
{"another branch", BuildRecord{State: "built", Ref: "feat/x", SourceInputs: inputs}, false},
|
||||||
|
{"a commit", BuildRecord{State: "built", Ref: "9efdd87a", SourceInputs: inputs}, false},
|
||||||
|
{"failed", BuildRecord{State: "failed", Ref: "main", SourceInputs: inputs}, false},
|
||||||
|
{"no state", BuildRecord{Ref: "main", SourceInputs: inputs}, false},
|
||||||
|
{"no source inputs", BuildRecord{State: "built", Ref: "main"}, false},
|
||||||
|
{"no ref and no source inputs", BuildRecord{State: "built"}, false},
|
||||||
|
} {
|
||||||
|
if got := c.r.IsTrunkBuild(); got != c.want {
|
||||||
|
t.Errorf("%s: IsTrunkBuild = %v, want %v", c.name, got, c.want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// decoded as the controller writes it: the key "ref" is absent
|
||||||
|
var r BuildRecord
|
||||||
|
raw := `{"id":"build-1792417485811374131","state":"built","repository":"http://novox.internal:20000/novox/mesh-catalog.git","module":"zsh","source-inputs":{"Module":"zsh","Tree":"t"}}`
|
||||||
|
if err := json.Unmarshal([]byte(raw), &r); err != nil || !r.IsTrunkBuild() {
|
||||||
|
t.Errorf("a decoded record with no ref: trunk = %v, err %v", r.IsTrunkBuild(), err)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user