Commit 2dca50de authored by Matthew Holt's avatar Matthew Holt

Rewrite automate.sh as Go program; add init folder to release archives

Easier parallelism and more control over platforms we build for, but
more importantly, we can do parallel builds using the build script which
properly embeds version information into the binaries. We also produce
the archive files ourselves and in parallel rather than using external
tar and zip commands.
parent 3faad41b
package main
import (
"fmt"
"log"
"os"
"os/exec"
"path/filepath"
"runtime"
"sync"
"github.com/mholt/archiver"
)
var buildScript, pkgDir, distDir, buildDir, releaseDir string
func init() {
pkgDir = filepath.Join(os.Getenv("GOPATH"), "src", "github.com", "mholt", "caddy")
buildScript = filepath.Join(pkgDir, "build.bash")
distDir = filepath.Join(pkgDir, "dist")
buildDir = filepath.Join(distDir, "builds")
releaseDir = filepath.Join(distDir, "release")
}
func main() {
// First, clean up
err := os.RemoveAll(buildDir)
if err != nil {
log.Fatal(err)
}
err = os.RemoveAll(releaseDir)
if err != nil {
log.Fatal(err)
}
// Then set up
err = os.MkdirAll(buildDir, 0755)
if err != nil {
log.Fatal(err)
}
err = os.MkdirAll(releaseDir, 0755)
if err != nil {
log.Fatal(err)
}
// Perform builds and make archives in parallel; only as many
// goroutines as we have processors.
var wg sync.WaitGroup
var throttle = make(chan struct{}, numProcs())
for _, p := range platforms {
wg.Add(1)
throttle <- struct{}{}
if p.os == "" || p.arch == "" || p.archive == "" {
log.Fatalf("Platform OS, architecture, and archive format is required: %+v", p)
}
go func(p platform) {
defer wg.Done()
defer func() { <-throttle }()
fmt.Printf("== Building %s\n", p)
var baseFilename, binFilename string
baseFilename = fmt.Sprintf("caddy_%s_%s", p.os, p.arch)
if p.arch == "arm" {
baseFilename += p.arm
}
binFilename = baseFilename
if p.os == "windows" {
binFilename += ".exe"
}
binPath := filepath.Join(buildDir, binFilename)
archive := filepath.Join(releaseDir, fmt.Sprintf("%s.%s", baseFilename, p.archive))
archiveContents := append(distContents, binPath)
err := build(p, binPath)
if err != nil {
log.Fatal(err)
}
fmt.Printf("== Compressing %s\n", baseFilename)
if p.archive == "zip" {
err := archiver.Zip(archive, archiveContents)
if err != nil {
log.Fatal(err)
}
} else if p.archive == "tar.gz" {
err := archiver.TarGz(archive, archiveContents)
if err != nil {
log.Fatal(err)
}
}
}(p)
}
wg.Wait()
}
func build(p platform, out string) error {
cmd := exec.Command(buildScript, out)
cmd.Dir = pkgDir
cmd.Env = os.Environ()
cmd.Env = append(cmd.Env, "CGO_ENABLED=0")
cmd.Env = append(cmd.Env, "GOOS="+p.os)
cmd.Env = append(cmd.Env, "GOARCH="+p.arch)
cmd.Env = append(cmd.Env, "GOARM="+p.arm)
cmd.Stderr = os.Stderr
return cmd.Run()
}
type platform struct {
os, arch, arm, binExt, archive string
}
func (p platform) String() string {
outStr := fmt.Sprintf("%s/%s", p.os, p.arch)
if p.arch == "arm" {
outStr += fmt.Sprintf(" (ARM v%s)", p.arm)
}
return outStr
}
func numProcs() int {
n := runtime.GOMAXPROCS(0)
if n == runtime.NumCPU() && n > 1 {
n -= 1
}
return n
}
// See: https://golang.org/doc/install/source#environment
// Not all supported platforms are listed since some are
// problematic and we only build the most common ones.
// These are just the pre-made, readily-available static
// builds, and we can add more upon request if there is
// enough demand.
var platforms = []platform{
{os: "darwin", arch: "386", archive: "zip"},
{os: "darwin", arch: "amd64", archive: "zip"},
{os: "freebsd", arch: "386", archive: "tar.gz"},
{os: "freebsd", arch: "amd64", archive: "tar.gz"},
{os: "freebsd", arch: "arm", arm: "7", archive: "tar.gz"},
{os: "linux", arch: "386", archive: "tar.gz"},
{os: "linux", arch: "amd64", archive: "tar.gz"},
{os: "linux", arch: "arm", arm: "7", archive: "tar.gz"},
{os: "linux", arch: "arm64", archive: "tar.gz"},
{os: "netbsd", arch: "386", archive: "tar.gz"},
{os: "netbsd", arch: "amd64", archive: "tar.gz"},
{os: "openbsd", arch: "386", archive: "tar.gz"},
{os: "openbsd", arch: "amd64", archive: "tar.gz"},
{os: "solaris", arch: "amd64", archive: "tar.gz"},
{os: "windows", arch: "386", archive: "zip"},
{os: "windows", arch: "amd64", archive: "zip"},
}
var distContents = []string{
filepath.Join(distDir, "init"),
filepath.Join(distDir, "CHANGES.txt"),
filepath.Join(distDir, "LICENSES.txt"),
filepath.Join(distDir, "README.txt"),
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment