github.com/joselitofilho/goreleaser@v0.155.1-0.20210123221854-e4891856c593/internal/builders/golang/targets.go (about)

     1  package golang
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	"github.com/apex/log"
     8  	"github.com/goreleaser/goreleaser/pkg/config"
     9  )
    10  
    11  type target struct {
    12  	os, arch, arm, mips string
    13  }
    14  
    15  func (t target) String() string {
    16  	if t.arm != "" {
    17  		return fmt.Sprintf("%s_%s_%s", t.os, t.arch, t.arm)
    18  	}
    19  	if t.mips != "" {
    20  		return fmt.Sprintf("%s_%s_%s", t.os, t.arch, t.mips)
    21  	}
    22  	return fmt.Sprintf("%s_%s", t.os, t.arch)
    23  }
    24  
    25  func matrix(build config.Build) ([]string, error) {
    26  	// nolint:prealloc
    27  	var targets []target
    28  	// nolint:prealloc
    29  	var result []string
    30  	for _, target := range allBuildTargets(build) {
    31  		if !contains(target.os, validGoos) {
    32  			return result, fmt.Errorf("invalid goos: %s", target.os)
    33  		}
    34  		if !contains(target.arch, validGoarch) {
    35  			return result, fmt.Errorf("invalid goarch: %s", target.arch)
    36  		}
    37  		if target.arm != "" && !contains(target.arm, validGoarm) {
    38  			return result, fmt.Errorf("invalid goarm: %s", target.arm)
    39  		}
    40  		if target.mips != "" && !contains(target.mips, validGomips) {
    41  			return result, fmt.Errorf("invalid gomips: %s", target.mips)
    42  		}
    43  		if !valid(target) {
    44  			log.WithField("target", target).
    45  				Debug("skipped invalid build")
    46  			continue
    47  		}
    48  		if ignored(build, target) {
    49  			log.WithField("target", target).
    50  				Debug("skipped ignored build")
    51  			continue
    52  		}
    53  		targets = append(targets, target)
    54  	}
    55  	for _, target := range targets {
    56  		result = append(result, target.String())
    57  	}
    58  	return result, nil
    59  }
    60  
    61  func allBuildTargets(build config.Build) (targets []target) {
    62  	for _, goos := range build.Goos {
    63  		for _, goarch := range build.Goarch {
    64  			if goarch == "arm" {
    65  				for _, goarm := range build.Goarm {
    66  					targets = append(targets, target{
    67  						os:   goos,
    68  						arch: goarch,
    69  						arm:  goarm,
    70  					})
    71  				}
    72  				continue
    73  			}
    74  			if strings.HasPrefix(goarch, "mips") {
    75  				for _, gomips := range build.Gomips {
    76  					targets = append(targets, target{
    77  						os:   goos,
    78  						arch: goarch,
    79  						mips: gomips,
    80  					})
    81  				}
    82  				continue
    83  			}
    84  			targets = append(targets, target{
    85  				os:   goos,
    86  				arch: goarch,
    87  			})
    88  		}
    89  	}
    90  	return
    91  }
    92  
    93  // TODO: this could be improved by using a map.
    94  // https://github.com/goreleaser/goreleaser/pull/522#discussion_r164245014
    95  func ignored(build config.Build, target target) bool {
    96  	for _, ig := range build.Ignore {
    97  		if ig.Goos != "" && ig.Goos != target.os {
    98  			continue
    99  		}
   100  		if ig.Goarch != "" && ig.Goarch != target.arch {
   101  			continue
   102  		}
   103  		if ig.Goarm != "" && ig.Goarm != target.arm {
   104  			continue
   105  		}
   106  		if ig.Gomips != "" && ig.Gomips != target.mips {
   107  			continue
   108  		}
   109  		return true
   110  	}
   111  	return false
   112  }
   113  
   114  func valid(target target) bool {
   115  	return contains(target.os+target.arch, validTargets)
   116  }
   117  
   118  func contains(s string, ss []string) bool {
   119  	for _, z := range ss {
   120  		if z == s {
   121  			return true
   122  		}
   123  	}
   124  	return false
   125  }
   126  
   127  // lists from https://golang.org/doc/install/source#environment
   128  // nolint: gochecknoglobals
   129  var (
   130  	validTargets = []string{
   131  		"aixppc64",
   132  		"android386",
   133  		"androidamd64",
   134  		"androidarm",
   135  		"androidarm64",
   136  		// "darwin386", - deprecated on latest go 1.15+
   137  		"darwinamd64",
   138  		// "darwinarm", - requires admin rights and other ios stuff
   139  		// "darwinarm64", - requires admin rights and other ios stuff
   140  		"dragonflyamd64",
   141  		"freebsd386",
   142  		"freebsdamd64",
   143  		"freebsdarm",
   144  		"freebsdarm64", // not on the official list for some reason, yet its supported on go 1.14+
   145  		"illumosamd64",
   146  		"jswasm",
   147  		"linux386",
   148  		"linuxamd64",
   149  		"linuxarm",
   150  		"linuxarm64",
   151  		"linuxppc64",
   152  		"linuxppc64le",
   153  		"linuxmips",
   154  		"linuxmipsle",
   155  		"linuxmips64",
   156  		"linuxmips64le",
   157  		"linuxs390x",
   158  		"linuxriscv64",
   159  		"netbsd386",
   160  		"netbsdamd64",
   161  		"netbsdarm",
   162  		"openbsd386",
   163  		"openbsdamd64",
   164  		"openbsdarm",
   165  		"openbsdarm64",
   166  		"plan9386",
   167  		"plan9amd64",
   168  		"plan9arm",
   169  		"solarisamd64",
   170  		"windows386",
   171  		"windowsamd64",
   172  	}
   173  
   174  	validGoos = []string{
   175  		"aix",
   176  		"android",
   177  		"darwin",
   178  		"dragonfly",
   179  		"freebsd",
   180  		"illumos",
   181  		"js",
   182  		"linux",
   183  		"netbsd",
   184  		"openbsd",
   185  		"plan9",
   186  		"solaris",
   187  		"windows",
   188  	}
   189  
   190  	validGoarch = []string{
   191  		"386",
   192  		"amd64",
   193  		"arm",
   194  		"arm64",
   195  		"mips",
   196  		"mips64",
   197  		"mips64le",
   198  		"mipsle",
   199  		"ppc64",
   200  		"ppc64le",
   201  		"s390x",
   202  		"wasm",
   203  		"riscv64",
   204  	}
   205  
   206  	validGoarm  = []string{"5", "6", "7"}
   207  	validGomips = []string{"hardfloat", "softfloat"}
   208  )