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
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)
}