package delivery import ( "maps" "slices" "strings" ) // **Every module builds against the latest published version of each mesh package it uses** (novox/hq ADR 0573 §2; // issue 1585). A mesh package is a Go module of a repository of the mesh's forge (ForgeModulePrefix): mesh-sdk's Go // module, and a seat's contract its holder's repository publishes (ADR 0573 §1). Its version is the trunk merge the // indexer holds for the module whose directory holds the package (PackageVersionsOf): a merge that changes it changes // the fingerprint of every module that uses it, and the build writes that version into its own go.mod and go.sum // (StepAsk.Packages). Which packages a module uses is read from its lock file by MeshPackagesOf, the same way by the // forge bridge and by the build modules (buildstep.ModuleTrees), so nobody names a version by hand. // ForgeModulePrefix is the module path prefix of the Go modules the mesh's forge serves: a Go module whose path starts // with it is a mesh package, git.novox.be/novox/[/]. const ForgeModulePrefix = "git.novox.be/novox/" // MeshPackagesOf are the mesh packages a Go module's go.sum names (the module path of each line that starts with // ForgeModulePrefix), sorted and each once. go.sum names every module of the build's graph, so a package used only // through another is named too. Nil for none. A package of the module's own repository comes with its own tree, and // its reader leaves it out (OtherPackages). func MeshPackagesOf(goSum []byte) []string { seen := map[string]bool{} for _, line := range strings.Split(string(goSum), "\n") { f := strings.Fields(line) if len(f) < 2 || !strings.HasPrefix(f[0], ForgeModulePrefix) { continue } if _, _, ok := PackageRepository(f[0]); !ok { continue } seen[f[0]] = true } if len(seen) == 0 { return nil } return slices.Sorted(maps.Keys(seen)) } // OtherPackages are the packages not published from repository, the module's own, in their order; nil for none. func OtherPackages(packages []string, repository string) []string { var out []string for _, p := range packages { if repo, _, ok := PackageRepository(p); ok && !SameRepository(repo, repository) { out = append(out, p) } } return out } // PackageRepository is the repository (/) a mesh package is published from and the package's directory in // it ("" for its root); false for a path that is not a forge module's. func PackageRepository(pkg string) (repository, dir string, ok bool) { rest, found := strings.CutPrefix(pkg, ForgeModulePrefix) if !found || rest == "" { return "", "", false } name, dir, _ := strings.Cut(rest, "/") if name == "" { return "", "", false } return "novox/" + name, dir, true } // PackageVersionsOf is the latest published version of each package from the modules the indexer holds (by key): the // trunk merge commit of the module of the package's repository whose directory holds the package's directory (the // deepest, a module at the repository's root holding every directory). A package no held module holds, or whose // module names no commit or no directory, is in missing, sorted; versions is nil when packages is empty. func PackageVersionsOf(packages []string, modules map[string]Module) (versions PackageVersions, missing []string) { for _, pkg := range packages { repository, dir, ok := PackageRepository(pkg) commit, depth := "", -1 if ok { for _, key := range slices.Sorted(maps.Keys(modules)) { m := modules[key] if !SameRepository(m.Repository, repository) || m.Commit == "" { continue } at := strings.Trim(m.Path, "/") switch { case at == "": continue // a value that names no directory says nothing of where the package lies case at == RootPath: at = "" case dir != at && !strings.HasPrefix(dir, at+"/"): continue } if d := len(at); d > depth { commit, depth = m.Commit, d } } } if commit == "" { missing = append(missing, pkg) continue } if versions == nil { versions = PackageVersions{} } versions[pkg] = commit } slices.Sort(missing) return versions, missing }