From: Dan Fuhry Date: Wed, 3 Jun 2026 04:50:47 +0000 (-0400) Subject: [pkg] support rename rules and multiple bazel-bin directories X-Git-Url: https://go.fuhry.dev/?a=commitdiff_plain;h=8aade843c08d97987daf82d56e72f26e7d55663c;p=runtime.git [pkg] support rename rules and multiple bazel-bin directories I am not proud of this code, but at least it works. ``` bazel build //pkg:runtime_utils_deb_nfpm_pkg //pkg:runtime_utils_archlinux_nfpm_pkg ``` --- diff --git a/pkg/nfpmgen/BUILD.bazel b/pkg/nfpmgen/BUILD.bazel index 7532737..1037a74 100644 --- a/pkg/nfpmgen/BUILD.bazel +++ b/pkg/nfpmgen/BUILD.bazel @@ -10,6 +10,7 @@ go_multi_library( visibility = ["//visibility:private"], deps = [ "//constants", + "//utils/hashset", "//utils/subst", "@com_github_goreleaser_nfpm_v2//:nfpm", "@com_github_goreleaser_nfpm_v2//files", diff --git a/pkg/nfpmgen/config_generator.go b/pkg/nfpmgen/config_generator.go index d91fc64..e3c8396 100644 --- a/pkg/nfpmgen/config_generator.go +++ b/pkg/nfpmgen/config_generator.go @@ -13,6 +13,7 @@ import ( "gopkg.in/yaml.v3" "go.fuhry.dev/runtime/constants" + "go.fuhry.dev/runtime/utils/hashset" "go.fuhry.dev/runtime/utils/subst" ) @@ -26,10 +27,16 @@ func debug(fmtstr string, args ...any) { fmt.Fprintf(os.Stderr, fmtstr+"\n", args...) } +type RenameRule struct { + Source string `yaml:"src" json:"src" jsonschema:"title=source path"` + Destination string `yaml:"dst" json:"dst" jsonschema:"title=destination path"` +} + type NfpmConfig struct { *nfpm.Config - Vars subst.KV `yaml:"vars" json:"vars" jsonschema:"title=map of context vars to inject into subst"` + Vars subst.KV `yaml:"vars" json:"vars" jsonschema:"title=map of context vars to inject into subst"` + RenameRules []*RenameRule `yaml:"rename_rules" json:"rename_rules" jsonschema:"title=dictionary of files to rename as source: target"` files map[string]struct{} `yaml:"-" json:"-"` } @@ -97,28 +104,43 @@ func LoadNfpmConfig(yamlPath string, fileAllowlist []string, varOverrides subst. return out, nil } -func (c *NfpmConfig) DiscoverBinaries(bazelBinDir string) error { +func (c *NfpmConfig) DiscoverBinaries(bazelBinDirs []string) error { wd, err := os.Getwd() if err != nil { return err } - cmdDir, err := os.ReadDir(path.Join(wd, bazelBinDir, "cmd")) - if err != nil { - return err + var entries []os.DirEntry + dedup := hashset.NewHashSet[string]() + + for _, dir := range bazelBinDirs { + if dirEntries, err := os.ReadDir(path.Join(wd, dir, "cmd")); err == nil { + entries = append(entries, dirEntries...) + } } - for _, entry := range cmdDir { + for _, entry := range entries { if entry.Name() == "." || entry.Name() == ".." || !entry.IsDir() { continue } exe := executable(entry.Name()) + if dedup.Contains(exe.pkgPath(c.Vars)) { + continue + } - exePath := exe.buildPath(bazelBinDir) + var exePath string + for _, bazelBinDir := range bazelBinDirs { + checkPath := exe.buildPath(bazelBinDir) - if _, ok := c.files[exePath]; !ok { - debug("exe not allowlisted in includes: %s", exePath) + if _, ok := c.files[checkPath]; ok { + exePath = checkPath + break + } + } + + if exePath == "" { + debug("exe not allowlisted in includes: %s", entry.Name()) continue } @@ -148,9 +170,12 @@ func (c *NfpmConfig) DiscoverBinaries(bazelBinDir string) error { continue } + pkgPath := exe.pkgPath(c.Vars) + dedup.Add(pkgPath) + c.Config.Contents = append(c.Config.Contents, &files.Content{ Source: exePath, - Destination: exe.pkgPath(c.Vars), + Destination: pkgPath, FileInfo: &files.ContentFileInfo{ Owner: "root", Group: "root", @@ -187,19 +212,23 @@ func recursiveDirectoryScan(baseDir string, match func(e os.DirEntry) bool) ([]s return out, nil } -func (c *NfpmConfig) DiscoverSystemdUnits(bazelBinDir string) error { - unitFiles, err := recursiveDirectoryScan( - bazelBinDir, - func(e os.DirEntry) bool { - if e.IsDir() { - return false - } +func (c *NfpmConfig) DiscoverSystemdUnits(bazelBinDirs []string) error { + var unitFiles []string - return systemdUnitFilename.MatchString(e.Name()) - }, - ) - if err != nil { - return err + for _, bazelBinDir := range bazelBinDirs { + files, err := recursiveDirectoryScan( + bazelBinDir, + func(e os.DirEntry) bool { + if e.IsDir() { + return false + } + + return systemdUnitFilename.MatchString(e.Name()) + }, + ) + if err == nil { + unitFiles = append(unitFiles, files...) + } } for _, f := range unitFiles { @@ -235,6 +264,35 @@ func (c *NfpmConfig) DiscoverSystemdUnits(bazelBinDir string) error { return nil } +func (c *NfpmConfig) ProcessRenameRules() error { + for _, r := range c.RenameRules { + found := false + src, err := subst.Eval(c.Vars, r.Source) + if err != nil { + return err + } + dst, err := subst.Eval(c.Vars, r.Destination) + if err != nil { + return err + } + + for _, file := range c.Config.Contents { + if file.Destination == src { + found = true + file.Destination = dst + break + } + + debug("destination: %s", file.Destination) + } + + if !found { + return fmt.Errorf("src %q not found among contents", src) + } + } + return nil +} + func (c *NfpmConfig) Generate() (string, error) { out, err := yaml.Marshal(c.Config) if err != nil { diff --git a/pkg/nfpmgen/main.go b/pkg/nfpmgen/main.go index 6fa7be7..55c72fe 100644 --- a/pkg/nfpmgen/main.go +++ b/pkg/nfpmgen/main.go @@ -5,6 +5,7 @@ import ( "flag" "fmt" "os" + "slices" "strings" "go.fuhry.dev/runtime/utils/subst" @@ -49,23 +50,38 @@ func main() { panic(err) } - bazelBinDir := "" + var bazelBinDirs []string if outFile != nil && *outFile != "" { // pushd to the bazel-bin dir `bazel-bin/[arch]/bin` directory parts := strings.Split(*outFile, "/") if len(parts) >= 3 { - bazelBinDir = strings.Join(parts[:3], "/") + bazelBinDirs = append(bazelBinDirs, strings.Join(parts[:3], "/")) } } + for _, incl := range includes { + if strings.HasPrefix(incl, "bazel-out/") { + parts := strings.Split(incl, "/") + if len(parts) >= 3 { + candidate := strings.Join(parts[:3], "/") + if !slices.Contains(bazelBinDirs, candidate) { + bazelBinDirs = append(bazelBinDirs, candidate) + } + } + } + } + + debug("loaded nfpm config template: %s\ncwd: %s\nout: %s\nbazelBinDirs: %+v\n", + *yamlFile, wd, *outFile, bazelBinDirs) - debug("loaded nfpm config template: %s\ncwd: %s\nout: %s\n", - *yamlFile, wd, *outFile) + if err := c.DiscoverBinaries(bazelBinDirs); err != nil { + panic(err) + } - if err := c.DiscoverBinaries(bazelBinDir); err != nil { + if err := c.DiscoverSystemdUnits(bazelBinDirs); err != nil { panic(err) } - if err := c.DiscoverSystemdUnits(bazelBinDir); err != nil { + if err := c.ProcessRenameRules(); err != nil { panic(err) } diff --git a/pkg/runtime-utils.yaml b/pkg/runtime-utils.yaml index 6e87438..763ca20 100644 --- a/pkg/runtime-utils.yaml +++ b/pkg/runtime-utils.yaml @@ -6,8 +6,7 @@ section: "net" priority: "extra" replaces: - ${const:OrgSlug}-service-discovery -depends: - - glibc +depends: [] conflicts: - ${const:OrgSlug}-service-discovery maintainer: "Bazel Build Service " @@ -15,4 +14,18 @@ description: Tools needed by virtually all ${const:OrgName} systems for service vendor: "${const:OrgName}" homepage: "https://go.fuhry.dev/runtime" license: "Proprietary" -contents: [] \ No newline at end of file +contents: [] +rename_rules: + - src: "/usr/bin/${const:ExePrefix}ephs-client" + dst: "/usr/bin/ephs" + +overrides: + archlinux: + depends: + - glibc + deb: + depends: + - libc6 + rpm: + depends: + - glibc