Add Magefile and release target

This commit is contained in:
2019-05-24 19:29:22 +02:00
parent eba02717cf
commit e6b5c55df8
13 changed files with 829 additions and 167 deletions

24
mage/release/fs.go Normal file
View File

@ -0,0 +1,24 @@
package release
import (
"fmt"
"github.com/magefile/mage/mg"
"github.com/otiai10/copy"
)
func Copy(src, dst string) error {
if mg.Verbose() {
fmt.Printf("Copying file from '%s' to '%s'\n", src, dst)
}
return copy.Copy(dst, src)
}
func MultiCopy(files map[string]string) error {
for dst, src := range files {
if err := Copy(src, dst); err != nil {
return err
}
}
return nil
}

67
mage/release/option.go Normal file
View File

@ -0,0 +1,67 @@
package release
type Options struct {
Systems []OS
Archs []Arch
DefaultArchiveType string
ArchiveTypeMap map[OS]string
BaseDir string
ProjectName string
Env map[string]string
}
type OptionFunc func(*Options)
func WithEnv(env map[string]string) OptionFunc {
return func(opts *Options) {
opts.Env = env
}
}
func WithSystems(systems ...OS) OptionFunc {
return func(opts *Options) {
opts.Systems = systems
}
}
func WithArchs(archs ...Arch) OptionFunc {
return func(opts *Options) {
opts.Archs = archs
}
}
func WithProjectName(projectName string) OptionFunc {
return func(opts *Options) {
opts.ProjectName = projectName
}
}
func WithBaseDir(baseDir string) OptionFunc {
return func(opts *Options) {
opts.BaseDir = baseDir
}
}
func defaultOptions() *Options {
return &Options{
Systems: []OS{
OSLinux,
OSWindows,
OSDarwin,
},
Archs: []Arch{
Arch386,
ArchAMD64,
ArchARM,
},
DefaultArchiveType: "tar.gz",
ArchiveTypeMap: map[OS]string{
OSWindows: "zip",
OSLinux: "tar.gz",
OSDarwin: "zip",
},
BaseDir: "release",
ProjectName: "my-project",
Env: make(map[string]string),
}
}

131
mage/release/release.go Normal file
View File

@ -0,0 +1,131 @@
package release
import (
"fmt"
"os"
"path"
"strings"
"github.com/magefile/mage/mg"
"github.com/magefile/mage/sh"
"github.com/mholt/archiver"
)
type OS string
const (
OSAix OS = "aix"
OSAndroid OS = "android"
OSDarwin OS = "darwin"
OSDragonfly OS = "dragonfly"
OSFreeBSD OS = "freebsd"
OSHurd OS = "hurd"
OSIllumos OS = "illumos"
OSJavascript OS = "js"
OSLinux OS = "linux"
OSNacl OS = "nacl"
OSNetBSD OS = "netbsd"
OSOpenBSD OS = "openbsd"
OSPlan9 OS = "plan9"
OSSolaris OS = "solaris"
OSWindows OS = "windows"
OSZos OS = "zos"
)
type Arch string
// 386 amd64 amd64p32 arm armbe arm64 arm64be ppc64 ppc64le mips mipsle mips64 mips64le mips64p32 mips64p32le ppc riscv riscv64 s390 s390x sparc sparc64 wasm
const (
Arch386 Arch = "386"
ArchAMD64 Arch = "amd64"
ArchARM Arch = "arm"
)
type Handler func(env map[string]string, destDir string) error
func EachTarget(handler Handler, opts ...OptionFunc) error {
options := defaultOptions()
for _, o := range opts {
o(options)
}
// Clean up existing directory
if err := sh.Rm(options.BaseDir); err != nil {
return err
}
baseEnv := environment()
for _, system := range options.Systems {
for _, arch := range options.Archs {
dirName := fmt.Sprintf("%s-%s-%s", options.ProjectName, system, arch)
destDir := path.Join(options.BaseDir, dirName)
if mg.Verbose() {
fmt.Printf("Generating release '%s'...\n", dirName)
}
// (Re)create destination directory
if err := os.MkdirAll(destDir, os.ModePerm); err != nil {
return err
}
// Generate Go build-related environment variables
env := override(
baseEnv,
options.Env,
map[string]string{
"GOOS": string(system),
"GOARCH": string(arch),
},
)
if err := handler(env, destDir); err != nil {
return err
}
archiveType := getArchiveType(system, options.DefaultArchiveType, options.ArchiveTypeMap)
archiveDest := fmt.Sprintf("%s.%s", destDir, archiveType)
if mg.Verbose() {
fmt.Printf("Generating archive '%s'...\n", archiveDest)
}
if err := archiver.Archive([]string{destDir}, archiveDest); err != nil {
return err
}
}
}
return nil
}
func environment() map[string]string {
env := make(map[string]string)
for _, o := range os.Environ() {
tokens := strings.SplitN(o, "=", 2)
env[tokens[0]] = tokens[1]
}
return env
}
func override(base map[string]string, overrides ...map[string]string) map[string]string {
env := make(map[string]string)
for k, v := range base {
env[k] = v
}
for _, o := range overrides {
for k, v := range o {
env[k] = v
}
}
return env
}
func getArchiveType(system OS, defaultArchiveType string, archiveTypeMap map[OS]string) string {
archiveType, exists := archiveTypeMap[system]
if !exists {
return defaultArchiveType
}
return archiveType
}