0
Fork 0
mirror of https://github.com/caddyserver/caddy.git synced 2024-12-23 22:27:38 -05:00
caddy/dist/automate.go
Matthew Holt 2dca50dee8
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.
2016-04-09 00:21:55 -06:00

164 lines
4.1 KiB
Go

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