Skip to content

Commit

Permalink
Add a new Java configuration option to recursively search parent poms…
Browse files Browse the repository at this point in the history
… for licenses

Signed-off-by: Colm O hEigeartaigh <coheigea@apache.org>
  • Loading branch information
coheigea committed Oct 31, 2023
1 parent 78ac2f9 commit 6f32ee0
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 12 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,7 @@ java:
# but it is not accessible from within the final built artifact
search-maven-for-licenses: false
maven-url: "https://repo1.maven.org/maven2"
max-parent-recursive-depth: 5

linux-kernel:
# whether to catalog linux kernel modules found within lib/modules/** directories
Expand Down
3 changes: 2 additions & 1 deletion cmd/syft/cli/options/catalog.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,8 @@ func (cfg Catalog) ToCatalogerConfig() cataloger.Config {
},
Java: javaCataloger.DefaultCatalogerOpts().
WithSearchMavenForLicenses(cfg.Java.SearchMavenForLicenses).
WithMavenCentralURL(cfg.Java.MavenURL),
WithMavenCentralURL(cfg.Java.MavenURL).
WithMaxParentRecursiveDepth(cfg.Java.MaxParentRecursiveDepth),
Python: pythonCataloger.CatalogerConfig{
GuessUnpinnedRequirements: cfg.Python.GuessUnpinnedRequirements,
},
Expand Down
5 changes: 3 additions & 2 deletions cmd/syft/cli/options/java.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package options

type java struct {
SearchMavenForLicenses bool `yaml:"search-maven-for-licenses" json:"search-maven-for-licenses" mapstructure:"search-maven-for-licenses"`
MavenURL string `yaml:"maven-url" json:"maven-url" mapstructure:"maven-url"`
SearchMavenForLicenses bool `yaml:"search-maven-for-licenses" json:"search-maven-for-licenses" mapstructure:"search-maven-for-licenses"`
MavenURL string `yaml:"maven-url" json:"maven-url" mapstructure:"maven-url"`
MaxParentRecursiveDepth int `yaml:"max-parent-recursive-depth" json:"max-parent-recursive-depth" mapstructure:"max-parent-recursive-depth"`
}
1 change: 1 addition & 0 deletions syft/pkg/cataloger/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,6 @@ func (c Config) JavaConfig() java.Config {
SearchUnindexedArchives: c.Search.IncludeUnindexedArchives,
SearchIndexedArchives: c.Search.IncludeIndexedArchives,
SearchMavenForLicenses: c.Java.SearchMavenForLicenses,
MaxParentRecursiveDepth: c.Java.MaxParentRecursiveDepth,
}
}
32 changes: 27 additions & 5 deletions syft/pkg/cataloger/java/archive_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ func (j *archiveParser) guessMainPackageNameAndVersionFromPomInfo() (name, versi
version = pomProjectObject.Version
}
if pomProjectObject != nil && j.cfg.SearchMavenForLicenses {
findPomLicenses(pomProjectObject)
findPomLicenses(pomProjectObject, j.cfg.MaxParentRecursiveDepth)
}

if pomProjectObject != nil {
Expand All @@ -304,17 +304,17 @@ func artifactIDMatchesFilename(artifactID, fileName string) bool {
return strings.HasPrefix(artifactID, fileName) || strings.HasSuffix(fileName, artifactID)
}

func findPomLicenses(pomProjectObject *parsedPomProject) {
func findPomLicenses(pomProjectObject *parsedPomProject, MaxParentRecursiveDepth int) {

Check failure on line 307 in syft/pkg/cataloger/java/archive_parser.go

View workflow job for this annotation

GitHub Actions / Static analysis

captLocal: `MaxParentRecursiveDepth' should not be capitalized (gocritic)
// If we don't have any licenses until now, and if we have a parent Pom, then we'll check the parent pom in maven central for licenses.
if pomProjectObject != nil && pomProjectObject.Parent != nil && len(pomProjectObject.Licenses) == 0 {
parentPom, err := getPomFromMavenCentral(pomProjectObject.Parent.GroupID, pomProjectObject.Parent.ArtifactID, pomProjectObject.Parent.Version)
parentLicenses, err := recursivelyFindLicensesFromParentPom(pomProjectObject.Parent.GroupID, pomProjectObject.Parent.ArtifactID,
pomProjectObject.Parent.Version, MaxParentRecursiveDepth)
if err != nil {
// We don't want to abort here as the parent pom might not exist in Maven Central, we'll just log the error
log.Tracef("unable to get parent pom from Maven central: %v", err)
return
}
parentLicenses := parseLicensesFromPom(parentPom)
if len(parentLicenses) > 0 || parentPom == nil || parentPom.Parent == nil {
if len(parentLicenses) > 0 {
for _, licenseName := range parentLicenses {
pomProjectObject.Licenses = append(pomProjectObject.Licenses, pkg.NewLicenseFromFields(licenseName, "", nil))
}
Expand All @@ -336,6 +336,28 @@ func formatMavenPomURL(groupID, artifactID, version string) (requestURL string,
return requestURL, err
}

func recursivelyFindLicensesFromParentPom(groupId, artifactId, version string, MaxParentRecursiveDepth int) ([]string, error) {

Check failure on line 339 in syft/pkg/cataloger/java/archive_parser.go

View workflow job for this annotation

GitHub Actions / Static analysis

captLocal: `MaxParentRecursiveDepth' should not be capitalized (gocritic)

Check failure on line 339 in syft/pkg/cataloger/java/archive_parser.go

View workflow job for this annotation

GitHub Actions / Static analysis

var-naming: func parameter groupId should be groupID (revive)

Check failure on line 339 in syft/pkg/cataloger/java/archive_parser.go

View workflow job for this annotation

GitHub Actions / Static analysis

var-naming: func parameter artifactId should be artifactID (revive)

Check failure on line 339 in syft/pkg/cataloger/java/archive_parser.go

View workflow job for this annotation

GitHub Actions / Static analysis

ST1003: func parameter groupId should be groupID (stylecheck)

Check failure on line 339 in syft/pkg/cataloger/java/archive_parser.go

View workflow job for this annotation

GitHub Actions / Static analysis

ST1003: func parameter artifactId should be artifactID (stylecheck)
var licenses []string
// As there can be nested parent poms, we'll recursively check for licenses until we reach the max depth
for i := 0; i < MaxParentRecursiveDepth; i++ {
parentPom, err := getPomFromMavenCentral(groupId, artifactId, version)
if err != nil {
return nil, err
}
parentLicenses := parseLicensesFromPom(parentPom)
if len(parentLicenses) > 0 || parentPom == nil || parentPom.Parent == nil {
licenses = parentLicenses
break
}

groupId = *parentPom.Parent.GroupID
artifactId = *parentPom.Parent.ArtifactID
version = *parentPom.Parent.Version
}

return licenses, nil
}

func getPomFromMavenCentral(groupID, artifactID, version string) (*gopom.Project, error) {
requestURL, err := formatMavenPomURL(groupID, artifactID, version)
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions syft/pkg/cataloger/java/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ type Config struct {
SearchIndexedArchives bool
SearchMavenForLicenses bool
MavenBaseURL string
MaxParentRecursiveDepth int
}
17 changes: 13 additions & 4 deletions syft/pkg/cataloger/java/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ package java
const MavenBaseURL = "https://repo1.maven.org/maven2"

type CatalogerOpts struct {
SearchMavenForLicenses bool
MavenURL string
SearchMavenForLicenses bool
MavenURL string
MaxParentRecursiveDepth int
}

func (j CatalogerOpts) WithSearchMavenForLicenses(input bool) CatalogerOpts {
Expand All @@ -19,9 +20,17 @@ func (j CatalogerOpts) WithMavenCentralURL(input string) CatalogerOpts {
return j
}

func (j CatalogerOpts) WithMaxParentRecursiveDepth(input int) CatalogerOpts {
if input > 0 {
j.MaxParentRecursiveDepth = input
}
return j
}

func DefaultCatalogerOpts() CatalogerOpts {
return CatalogerOpts{
SearchMavenForLicenses: false,
MavenURL: MavenBaseURL,
SearchMavenForLicenses: false,
MavenURL: MavenBaseURL,
MaxParentRecursiveDepth: 5,
}
}

0 comments on commit 6f32ee0

Please sign in to comment.