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 // TODO: add missing architectures 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 }