From faec0ff816c33602dccf2a8efc64c0cc319b9c63 Mon Sep 17 00:00:00 2001 From: Michael Eischer Date: Fri, 9 Jun 2023 13:17:24 +0200 Subject: [PATCH] build-release-binaries: support building a subset of all platforms --- helpers/build-release-binaries/main.go | 69 ++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 5 deletions(-) diff --git a/helpers/build-release-binaries/main.go b/helpers/build-release-binaries/main.go index 0c0015f42..94269fe2c 100644 --- a/helpers/build-release-binaries/main.go +++ b/helpers/build-release-binaries/main.go @@ -1,11 +1,14 @@ package main import ( + "errors" "fmt" "os" "os/exec" "path/filepath" "runtime" + "sort" + "strconv" "strings" "time" @@ -14,16 +17,18 @@ import ( ) var opts = struct { - Verbose bool - SourceDir string - OutputDir string - Version string + Verbose bool + SourceDir string + OutputDir string + PlatformSubset string + Version string }{} func init() { pflag.BoolVarP(&opts.Verbose, "verbose", "v", false, "be verbose") pflag.StringVarP(&opts.SourceDir, "source", "s", "/restic", "path to the source code `directory`") pflag.StringVarP(&opts.OutputDir, "output", "o", "/output", "path to the output `directory`") + pflag.StringVar(&opts.PlatformSubset, "platform-subset", "", "specify `n/t` to only build this subset") pflag.StringVar(&opts.Version, "version", "", "use `x.y.z` as the version for output files") pflag.Parse() } @@ -244,15 +249,69 @@ func downloadModules(sourceDir string) { } } +func selectSubset(subset string, target map[string][]string) (map[string][]string, error) { + t, n, _ := strings.Cut(subset, "/") + part, err := strconv.ParseInt(t, 10, 8) + if err != nil { + return nil, fmt.Errorf("failed to parse platform subset %q", subset) + } + total, err := strconv.ParseInt(n, 10, 8) + if err != nil { + return nil, fmt.Errorf("failed to parse platform subset %q", subset) + } + if total < 0 || part < 0 { + return nil, errors.New("platform subset out of range") + } + if part >= total { + return nil, errors.New("t must be in 0 <= t < n") + } + + // flatten platform list + platforms := []string{} + for os, archs := range target { + for _, arch := range archs { + platforms = append(platforms, os+"/"+arch) + } + } + sort.Strings(platforms) + + // select subset + lower := len(platforms) * int(part) / int(total) + upper := len(platforms) * int(part+1) / int(total) + platforms = platforms[lower:upper] + + return buildPlatformList(platforms), nil +} + +func buildPlatformList(platforms []string) map[string][]string { + fmt.Printf("Building for %v\n", platforms) + + targets := make(map[string][]string) + for _, platform := range platforms { + os, arch, _ := strings.Cut(platform, "/") + targets[os] = append(targets[os], arch) + } + return targets +} + func main() { if len(pflag.Args()) != 0 { die("USAGE: build-release-binaries [OPTIONS]") } + targets := defaultBuildTargets + if opts.PlatformSubset != "" { + var err error + targets, err = selectSubset(opts.PlatformSubset, targets) + if err != nil { + die("%s", err) + } + } + sourceDir := abs(opts.SourceDir) outputDir := abs(opts.OutputDir) mkdir(outputDir) downloadModules(sourceDir) - buildTargets(sourceDir, outputDir, defaultBuildTargets) + buildTargets(sourceDir, outputDir, targets) }