github.com/anchore/syft@v1.38.2/syft/pkg/cataloger/golang/config.go (about)

     1  package golang
     2  
     3  import (
     4  	"os"
     5  	"path/filepath"
     6  	"strings"
     7  
     8  	"github.com/anchore/go-homedir"
     9  	"github.com/anchore/syft/internal/log"
    10  )
    11  
    12  const (
    13  	defaultProxies  = "https://proxy.golang.org,direct"
    14  	directProxyOnly = "direct"
    15  )
    16  
    17  var (
    18  	directProxiesOnly = []string{directProxyOnly}
    19  )
    20  
    21  type CatalogerConfig struct {
    22  	// SearchLocalModCacheLicenses enables searching for go package licenses in the local GOPATH mod cache.
    23  	// app-config: golang.search-local-mod-cache-licenses
    24  	SearchLocalModCacheLicenses bool `yaml:"search-local-mod-cache-licenses" json:"search-local-mod-cache-licenses" mapstructure:"search-local-mod-cache-licenses"`
    25  
    26  	// LocalModCacheDir specifies the location of the local go module cache directory. When not set, syft will attempt to discover the GOPATH env or default to $HOME/go.
    27  	// app-config: golang.local-mod-cache-dir
    28  	LocalModCacheDir string `yaml:"local-mod-cache-dir" json:"local-mod-cache-dir" mapstructure:"local-mod-cache-dir"`
    29  
    30  	// SearchLocalVendorLicenses enables searching for go package licenses in the local vendor directory relative to the go.mod file.
    31  	// app-config: golang.search-local-vendor-licenses
    32  	SearchLocalVendorLicenses bool `yaml:"search-local-vendor-licenses" json:"search-local-vendor-licenses" mapstructure:"search-local-vendor-licenses"`
    33  
    34  	// LocalVendorDir specifies the location of the local vendor directory. When not set, syft will search for a vendor directory relative to the go.mod file.
    35  	// app-config: golang.local-vendor-dir
    36  	LocalVendorDir string `yaml:"local-vendor-dir" json:"local-vendor-dir" mapstructure:"local-vendor-dir"`
    37  
    38  	// SearchRemoteLicenses enables downloading go package licenses from the upstream go proxy (typically proxy.golang.org).
    39  	// app-config: golang.search-remote-licenses
    40  	SearchRemoteLicenses bool `yaml:"search-remote-licenses" json:"search-remote-licenses" mapstructure:"search-remote-licenses"`
    41  
    42  	// Proxies is a list of go module proxies to use when fetching go module metadata and licenses. When not set, syft will use the GOPROXY env or default to https://proxy.golang.org,direct.
    43  	// app-config: golang.proxy
    44  	Proxies []string `yaml:"proxies,omitempty" json:"proxies,omitempty" mapstructure:"proxies"`
    45  
    46  	// NoProxy is a list of glob patterns that match go module names that should not be fetched from the go proxy. When not set, syft will use the GOPRIVATE and GONOPROXY env vars.
    47  	// app-config: golang.no-proxy
    48  	NoProxy []string `yaml:"no-proxy,omitempty" json:"no-proxy,omitempty" mapstructure:"no-proxy"`
    49  
    50  	MainModuleVersion MainModuleVersionConfig `yaml:"main-module-version" json:"main-module-version" mapstructure:"main-module-version"`
    51  }
    52  
    53  type MainModuleVersionConfig struct {
    54  	// FromLDFlags enables parsing the main module version from the -ldflags build settings.
    55  	// app-config: golang.main-module-version.from-ld-flags
    56  	FromLDFlags bool `yaml:"from-ld-flags" json:"from-ld-flags" mapstructure:"from-ld-flags"`
    57  
    58  	// FromContents enables parsing the main module version from the binary contents. This is useful when the version is embedded in the binary but not in the build settings.
    59  	// app-config: golang.main-module-version.from-contents
    60  	FromContents bool `yaml:"from-contents" json:"from-contents" mapstructure:"from-contents"`
    61  
    62  	// FromBuildSettings enables parsing the main module version from the go build settings.
    63  	// app-config: golang.main-module-version.from-build-settings
    64  	FromBuildSettings bool `yaml:"from-build-settings" json:"from-build-settings" mapstructure:"from-build-settings"`
    65  }
    66  
    67  // DefaultCatalogerConfig create a CatalogerConfig with default options, which includes:
    68  // - setting the default remote proxy if none is provided
    69  // - setting the default no proxy if none is provided
    70  // - setting the default local module cache dir if none is provided
    71  func DefaultCatalogerConfig() CatalogerConfig {
    72  	g := CatalogerConfig{
    73  		MainModuleVersion: DefaultMainModuleVersionConfig(),
    74  		LocalModCacheDir:  defaultGoModDir(),
    75  	}
    76  
    77  	// first process the proxy settings
    78  	if len(g.Proxies) == 0 {
    79  		goProxy := os.Getenv("GOPROXY")
    80  		if goProxy == "" {
    81  			goProxy = defaultProxies
    82  		}
    83  		g = g.WithProxy(goProxy)
    84  	}
    85  
    86  	// next process the gonoproxy settings
    87  	if len(g.NoProxy) == 0 {
    88  		goPrivate := os.Getenv("GOPRIVATE")
    89  		goNoProxy := os.Getenv("GONOPROXY")
    90  		// we only use the env var if it was not set explicitly
    91  		if goPrivate != "" {
    92  			g.NoProxy = append(g.NoProxy, strings.Split(goPrivate, ",")...)
    93  		}
    94  
    95  		// next process the goprivate settings; we always add those
    96  		if goNoProxy != "" {
    97  			g.NoProxy = append(g.NoProxy, strings.Split(goNoProxy, ",")...)
    98  		}
    99  	}
   100  
   101  	return g
   102  }
   103  
   104  // defaultGoModDir returns $GOPATH/pkg/mod or $HOME/go/pkg/mod based on environment variables available
   105  func defaultGoModDir() string {
   106  	goPath := os.Getenv("GOPATH")
   107  
   108  	if goPath == "" {
   109  		homeDir, err := homedir.Dir()
   110  		if err != nil {
   111  			log.Debugf("unable to determine GOPATH or user home dir: %w", err)
   112  			return ""
   113  		}
   114  		goPath = filepath.Join(homeDir, "go")
   115  	}
   116  
   117  	return filepath.Join(goPath, "pkg", "mod")
   118  }
   119  
   120  func DefaultMainModuleVersionConfig() MainModuleVersionConfig {
   121  	return MainModuleVersionConfig{
   122  		FromLDFlags:       true,
   123  		FromContents:      false,
   124  		FromBuildSettings: true,
   125  	}
   126  }
   127  
   128  func (g CatalogerConfig) WithSearchLocalModCacheLicenses(input bool) CatalogerConfig {
   129  	g.SearchLocalModCacheLicenses = input
   130  	return g
   131  }
   132  
   133  func (g CatalogerConfig) WithLocalModCacheDir(input string) CatalogerConfig {
   134  	if input == "" {
   135  		return g
   136  	}
   137  	g.LocalModCacheDir = input
   138  	return g
   139  }
   140  
   141  func (g CatalogerConfig) WithSearchLocalVendorLicenses(input bool) CatalogerConfig {
   142  	g.SearchLocalVendorLicenses = input
   143  	return g
   144  }
   145  
   146  func (g CatalogerConfig) WithLocalVendorDir(input string) CatalogerConfig {
   147  	if input == "" {
   148  		return g
   149  	}
   150  	g.LocalVendorDir = input
   151  	return g
   152  }
   153  
   154  func (g CatalogerConfig) WithSearchRemoteLicenses(input bool) CatalogerConfig {
   155  	g.SearchRemoteLicenses = input
   156  	return g
   157  }
   158  
   159  func (g CatalogerConfig) WithProxy(input string) CatalogerConfig {
   160  	if input == "" {
   161  		return g
   162  	}
   163  	if input == "off" {
   164  		input = directProxyOnly
   165  	}
   166  	g.Proxies = strings.Split(input, ",")
   167  	return g
   168  }
   169  
   170  func (g CatalogerConfig) WithNoProxy(input string) CatalogerConfig {
   171  	if input == "" {
   172  		return g
   173  	}
   174  	g.NoProxy = strings.Split(input, ",")
   175  	return g
   176  }
   177  
   178  func (g CatalogerConfig) WithMainModuleVersion(input MainModuleVersionConfig) CatalogerConfig {
   179  	g.MainModuleVersion = input
   180  	return g
   181  }
   182  
   183  func (g MainModuleVersionConfig) WithFromLDFlags(input bool) MainModuleVersionConfig {
   184  	g.FromLDFlags = input
   185  	return g
   186  }
   187  
   188  func (g MainModuleVersionConfig) WithFromContents(input bool) MainModuleVersionConfig {
   189  	g.FromContents = input
   190  	return g
   191  }
   192  
   193  func (g MainModuleVersionConfig) WithFromBuildSettings(input bool) MainModuleVersionConfig {
   194  	g.FromBuildSettings = input
   195  	return g
   196  }