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  }