build-release-binaries: support building a subset of all platforms

This commit is contained in:
Michael Eischer 2023-06-09 13:17:24 +02:00
parent 237f32c651
commit faec0ff816
1 changed files with 64 additions and 5 deletions

View File

@ -1,11 +1,14 @@
package main package main
import ( import (
"errors"
"fmt" "fmt"
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"runtime" "runtime"
"sort"
"strconv"
"strings" "strings"
"time" "time"
@ -14,16 +17,18 @@ import (
) )
var opts = struct { var opts = struct {
Verbose bool Verbose bool
SourceDir string SourceDir string
OutputDir string OutputDir string
Version string PlatformSubset string
Version string
}{} }{}
func init() { func init() {
pflag.BoolVarP(&opts.Verbose, "verbose", "v", false, "be verbose") 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.SourceDir, "source", "s", "/restic", "path to the source code `directory`")
pflag.StringVarP(&opts.OutputDir, "output", "o", "/output", "path to the output `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.StringVar(&opts.Version, "version", "", "use `x.y.z` as the version for output files")
pflag.Parse() 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() { func main() {
if len(pflag.Args()) != 0 { if len(pflag.Args()) != 0 {
die("USAGE: build-release-binaries [OPTIONS]") 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) sourceDir := abs(opts.SourceDir)
outputDir := abs(opts.OutputDir) outputDir := abs(opts.OutputDir)
mkdir(outputDir) mkdir(outputDir)
downloadModules(sourceDir) downloadModules(sourceDir)
buildTargets(sourceDir, outputDir, defaultBuildTargets) buildTargets(sourceDir, outputDir, targets)
} }