github.com/anchore/syft@v1.38.2/syft/pkg/cataloger/java/internal/maven/config.go (about) 1 package maven 2 3 import ( 4 "encoding/xml" 5 "fmt" 6 "io" 7 "net/url" 8 "os" 9 "path/filepath" 10 "strings" 11 12 "github.com/anchore/go-homedir" 13 "github.com/anchore/syft/internal" 14 "github.com/anchore/syft/internal/log" 15 ) 16 17 const mavenBaseURL = "https://repo1.maven.org/maven2" 18 19 type Config struct { 20 // UseNetwork instructs the maven resolver to use network operations to resolve maven artifacts 21 UseNetwork bool `yaml:"use-network" json:"use-network" mapstructure:"use-network"` 22 23 // Repositories are the set of remote repositories the network resolution should use 24 Repositories []string `yaml:"maven-repositories" json:"maven-repositories" mapstructure:"maven-repositories"` 25 26 // UseLocalRepository instructs the maven resolver to look in the host maven cache, usually ~/.m2/repository 27 UseLocalRepository bool `yaml:"use-maven-local-repository" json:"use-maven-local-repository" mapstructure:"use-maven-local-repository"` 28 29 // LocalRepositoryDir is an alternate directory to use to look up the local repository 30 LocalRepositoryDir string `yaml:"maven-local-repository-dir" json:"maven-local-repository-dir" mapstructure:"maven-local-repository-dir"` 31 32 // MaxParentRecursiveDepth allows for a maximum depth to use when recursively resolving parent poms and other information, 0 disables any maximum 33 MaxParentRecursiveDepth int `yaml:"max-parent-recursive-depth" json:"max-parent-recursive-depth" mapstructure:"max-parent-recursive-depth"` 34 } 35 36 func DefaultConfig() Config { 37 return Config{ 38 UseNetwork: false, 39 Repositories: []string{mavenBaseURL}, 40 UseLocalRepository: false, 41 LocalRepositoryDir: defaultMavenLocalRepoDir(), 42 MaxParentRecursiveDepth: 0, // unlimited 43 } 44 } 45 46 // defaultMavenLocalRepoDir gets default location of the Maven local repository, generally at <USER HOME DIR>/.m2/repository 47 func defaultMavenLocalRepoDir() string { 48 homeDir, err := homedir.Dir() 49 if err != nil { 50 return "" 51 } 52 53 mavenHome := filepath.Join(homeDir, ".m2") 54 55 settingsXML := filepath.Join(mavenHome, "settings.xml") 56 settings, err := os.Open(settingsXML) 57 if err == nil && settings != nil { 58 defer internal.CloseAndLogError(settings, settingsXML) 59 localRepository := getSettingsXMLLocalRepository(settings) 60 if localRepository != "" { 61 return localRepository 62 } 63 } 64 return filepath.Join(mavenHome, "repository") 65 } 66 67 // getSettingsXMLLocalRepository reads the provided settings.xml and parses the localRepository, if present 68 func getSettingsXMLLocalRepository(settingsXML io.Reader) string { 69 type settings struct { 70 LocalRepository string `xml:"localRepository"` 71 } 72 s := settings{} 73 err := xml.NewDecoder(settingsXML).Decode(&s) 74 if err != nil { 75 log.WithFields("error", err).Debug("unable to read maven settings.xml") 76 } 77 return s.LocalRepository 78 } 79 80 // remotePomURL returns a URL to download a POM from a remote repository 81 func remotePomURL(repoURL, groupID, artifactID, version string) (requestURL string, err error) { 82 // groupID needs to go from maven.org -> maven/org 83 urlPath := strings.Split(groupID, ".") 84 artifactPom := fmt.Sprintf("%s-%s.pom", artifactID, version) 85 urlPath = append(urlPath, artifactID, version, artifactPom) 86 87 // ex: https://repo1.maven.org/maven2/groupID/artifactID/artifactPom 88 requestURL, err = url.JoinPath(repoURL, urlPath...) 89 if err != nil { 90 return requestURL, fmt.Errorf("could not construct maven url: %w", err) 91 } 92 return requestURL, err 93 }