mirror of
https://github.com/anchore/syft.git
synced 2025-11-17 08:23:15 +01:00
Parse the Maven license from the pom.xml if not contained in the mani… (#2115)
* Parse the Maven license from the pom.xml if not contained in the manifest Signed-off-by: Colm O hEigeartaigh <coheigea@apache.org> * chore: restore 10.0.2 schema Signed-off-by: Christopher Phillips <christopher.phillips@anchore.com> * chore: generate new 11.0.1 schema Signed-off-by: Christopher Phillips <christopher.phillips@anchore.com> * refactor: remove schema change Signed-off-by: Christopher Phillips <christopher.phillips@anchore.com> * test: update unit tests to align with new pattern Signed-off-by: Christopher Phillips <christopher.phillips@anchore.com> * chore: pr feedback Signed-off-by: Christopher Phillips <christopher.phillips@anchore.com> * chore: remove struct tags Signed-off-by: Christopher Phillips <christopher.phillips@anchore.com> * keep license name and url semantics preserved on the pkg object Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> --------- Signed-off-by: Colm O hEigeartaigh <coheigea@apache.org> Signed-off-by: Christopher Phillips <christopher.phillips@anchore.com> Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> Co-authored-by: Christopher Angelo Phillips <32073428+spiffcs@users.noreply.github.com> Co-authored-by: Christopher Phillips <christopher.phillips@anchore.com> Co-authored-by: Alex Goodman <wagoodman@users.noreply.github.com>
This commit is contained in:
parent
185d0d1bfa
commit
0748945c83
@ -171,19 +171,14 @@ func (j *archiveParser) discoverMainPackage() (*pkg.Package, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
archiveCloser, err := os.Open(j.archivePath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to open archive path (%s): %w", j.archivePath, err)
|
||||
}
|
||||
defer archiveCloser.Close()
|
||||
|
||||
// grab and assign digest for the entire archive
|
||||
digests, err := intFile.NewDigestsFromFile(archiveCloser, javaArchiveHashes)
|
||||
digests, err := getDigestsFromArchive(j.archivePath)
|
||||
if err != nil {
|
||||
log.Warnf("failed to create digest for file=%q: %+v", j.archivePath, err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// we use j.location because we want to associate the license declaration with where we discovered the contents in the manifest
|
||||
// TODO: when we support locations of paths within archives we should start passing the specific manifest location object instead of the top jar
|
||||
licenses := pkg.NewLicensesFromLocation(j.location, selectLicenses(manifest)...)
|
||||
/*
|
||||
We should name and version from, in this order:
|
||||
@ -192,13 +187,20 @@ func (j *archiveParser) discoverMainPackage() (*pkg.Package, error) {
|
||||
3. manifest
|
||||
4. filename
|
||||
*/
|
||||
name, version := j.guessMainPackageNameAndVersionFromPomInfo()
|
||||
name, version, pomLicenses := j.guessMainPackageNameAndVersionFromPomInfo()
|
||||
if name == "" {
|
||||
name = selectName(manifest, j.fileInfo)
|
||||
}
|
||||
if version == "" {
|
||||
version = selectVersion(manifest, j.fileInfo)
|
||||
}
|
||||
if len(licenses) == 0 {
|
||||
// Today we don't have a way to distinguish between licenses from the manifest and licenses from the pom.xml
|
||||
// until the file.Location object can support sub-paths (i.e. paths within archives, recursively; issue https://github.com/anchore/syft/issues/2211).
|
||||
// Until then it's less confusing to use the licenses from the pom.xml only if the manifest did not list any.
|
||||
licenses = append(licenses, pomLicenses...)
|
||||
}
|
||||
|
||||
return &pkg.Package{
|
||||
// TODO: maybe select name should just have a pom properties in it?
|
||||
Name: name,
|
||||
@ -218,11 +220,16 @@ func (j *archiveParser) discoverMainPackage() (*pkg.Package, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (j *archiveParser) guessMainPackageNameAndVersionFromPomInfo() (string, string) {
|
||||
type parsedPomProject struct {
|
||||
*pkg.PomProject
|
||||
Licenses []pkg.License
|
||||
}
|
||||
|
||||
func (j *archiveParser) guessMainPackageNameAndVersionFromPomInfo() (name, version string, licenses []pkg.License) {
|
||||
pomPropertyMatches := j.fileManifest.GlobMatch(pomPropertiesGlob)
|
||||
pomMatches := j.fileManifest.GlobMatch(pomXMLGlob)
|
||||
var pomPropertiesObject pkg.PomProperties
|
||||
var pomProjectObject pkg.PomProject
|
||||
var pomProjectObject parsedPomProject
|
||||
if len(pomPropertyMatches) == 1 || len(pomMatches) == 1 {
|
||||
// we have exactly 1 pom.properties or pom.xml in the archive; assume it represents the
|
||||
// package we're scanning if the names seem like a plausible match
|
||||
@ -238,15 +245,15 @@ func (j *archiveParser) guessMainPackageNameAndVersionFromPomInfo() (string, str
|
||||
}
|
||||
}
|
||||
}
|
||||
name := pomPropertiesObject.ArtifactID
|
||||
if name == "" {
|
||||
name = pomPropertiesObject.ArtifactID
|
||||
if name == "" && pomProjectObject.PomProject != nil {
|
||||
name = pomProjectObject.ArtifactID
|
||||
}
|
||||
version := pomPropertiesObject.Version
|
||||
if version == "" {
|
||||
version = pomPropertiesObject.Version
|
||||
if version == "" && pomProjectObject.PomProject != nil {
|
||||
version = pomProjectObject.Version
|
||||
}
|
||||
return name, version
|
||||
return name, version, pomProjectObject.Licenses
|
||||
}
|
||||
|
||||
// discoverPkgsFromAllMavenFiles parses Maven POM properties/xml for a given
|
||||
@ -273,7 +280,7 @@ func (j *archiveParser) discoverPkgsFromAllMavenFiles(parentPkg *pkg.Package) ([
|
||||
}
|
||||
|
||||
for parentPath, propertiesObj := range properties {
|
||||
var pomProject *pkg.PomProject
|
||||
var pomProject *parsedPomProject
|
||||
if proj, exists := projects[parentPath]; exists {
|
||||
pomProject = &proj
|
||||
}
|
||||
@ -287,6 +294,22 @@ func (j *archiveParser) discoverPkgsFromAllMavenFiles(parentPkg *pkg.Package) ([
|
||||
return pkgs, nil
|
||||
}
|
||||
|
||||
func getDigestsFromArchive(archivePath string) ([]file.Digest, error) {
|
||||
archiveCloser, err := os.Open(archivePath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to open archive path (%s): %w", archivePath, err)
|
||||
}
|
||||
defer archiveCloser.Close()
|
||||
|
||||
// grab and assign digest for the entire archive
|
||||
digests, err := intFile.NewDigestsFromFile(archiveCloser, javaArchiveHashes)
|
||||
if err != nil {
|
||||
log.Warnf("failed to create digest for file=%q: %+v", archivePath, err)
|
||||
}
|
||||
|
||||
return digests, nil
|
||||
}
|
||||
|
||||
func (j *archiveParser) discoverPkgsFromNestedArchives(parentPkg *pkg.Package) ([]pkg.Package, []artifact.Relationship, error) {
|
||||
// we know that all java archives are zip formatted files, so we can use the shared zip helper
|
||||
return discoverPkgsFromZip(j.location, j.archivePath, j.contentPath, j.fileManifest, parentPkg)
|
||||
@ -388,15 +411,16 @@ func pomPropertiesByParentPath(archivePath string, location file.Location, extra
|
||||
return propertiesByParentPath, nil
|
||||
}
|
||||
|
||||
func pomProjectByParentPath(archivePath string, location file.Location, extractPaths []string) (map[string]pkg.PomProject, error) {
|
||||
func pomProjectByParentPath(archivePath string, location file.Location, extractPaths []string) (map[string]parsedPomProject, error) {
|
||||
contentsOfMavenProjectFiles, err := intFile.ContentsFromZip(archivePath, extractPaths...)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to extract maven files: %w", err)
|
||||
}
|
||||
|
||||
projectByParentPath := make(map[string]pkg.PomProject)
|
||||
projectByParentPath := make(map[string]parsedPomProject)
|
||||
for filePath, fileContents := range contentsOfMavenProjectFiles {
|
||||
pomProject, err := parsePomXMLProject(filePath, strings.NewReader(fileContents))
|
||||
// TODO: when we support locations of paths within archives we should start passing the specific pom.xml location object instead of the top jar
|
||||
pomProject, err := parsePomXMLProject(filePath, strings.NewReader(fileContents), location)
|
||||
if err != nil {
|
||||
log.WithFields("contents-path", filePath, "location", location.AccessPath()).Warnf("failed to parse pom.xml: %+v", err)
|
||||
continue
|
||||
@ -418,7 +442,7 @@ func pomProjectByParentPath(archivePath string, location file.Location, extractP
|
||||
|
||||
// newPackageFromMavenData processes a single Maven POM properties for a given parent package, returning all listed Java packages found and
|
||||
// associating each discovered package to the given parent package. Note the pom.xml is optional, the pom.properties is not.
|
||||
func newPackageFromMavenData(pomProperties pkg.PomProperties, pomProject *pkg.PomProject, parentPkg *pkg.Package, location file.Location) *pkg.Package {
|
||||
func newPackageFromMavenData(pomProperties pkg.PomProperties, parsedPomProject *parsedPomProject, parentPkg *pkg.Package, location file.Location) *pkg.Package {
|
||||
// keep the artifact name within the virtual path if this package does not match the parent package
|
||||
vPathSuffix := ""
|
||||
groupID := ""
|
||||
@ -440,20 +464,27 @@ func newPackageFromMavenData(pomProperties pkg.PomProperties, pomProject *pkg.Po
|
||||
}
|
||||
virtualPath := location.AccessPath() + vPathSuffix
|
||||
|
||||
// discovered props = new package
|
||||
var pkgPomProject *pkg.PomProject
|
||||
licenses := make([]pkg.License, 0)
|
||||
if parsedPomProject != nil {
|
||||
pkgPomProject = parsedPomProject.PomProject
|
||||
licenses = append(licenses, parsedPomProject.Licenses...)
|
||||
}
|
||||
|
||||
p := pkg.Package{
|
||||
Name: pomProperties.ArtifactID,
|
||||
Version: pomProperties.Version,
|
||||
Locations: file.NewLocationSet(
|
||||
location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
|
||||
),
|
||||
Licenses: pkg.NewLicenseSet(licenses...),
|
||||
Language: pkg.Java,
|
||||
Type: pomProperties.PkgTypeIndicated(),
|
||||
MetadataType: pkg.JavaMetadataType,
|
||||
Metadata: pkg.JavaMetadata{
|
||||
VirtualPath: virtualPath,
|
||||
PomProperties: &pomProperties,
|
||||
PomProject: pomProject,
|
||||
PomProject: pkgPomProject,
|
||||
Parent: parentPkg,
|
||||
},
|
||||
}
|
||||
|
||||
@ -6,7 +6,6 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
@ -17,6 +16,7 @@ import (
|
||||
|
||||
"github.com/anchore/syft/internal"
|
||||
"github.com/anchore/syft/syft/file"
|
||||
"github.com/anchore/syft/syft/license"
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
"github.com/anchore/syft/syft/pkg/cataloger/internal/pkgtest"
|
||||
)
|
||||
@ -83,11 +83,13 @@ func generateJavaBuildFixture(t *testing.T, fixturePath string) {
|
||||
|
||||
func TestParseJar(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
fixture string
|
||||
expected map[string]pkg.Package
|
||||
ignoreExtras []string
|
||||
}{
|
||||
{
|
||||
name: "example-jenkins-plugin",
|
||||
fixture: "test-fixtures/java-builds/packages/example-jenkins-plugin.hpi",
|
||||
ignoreExtras: []string{
|
||||
"Plugin-Version", // has dynamic date
|
||||
@ -146,6 +148,7 @@ func TestParseJar(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "example-java-app-gradle",
|
||||
fixture: "test-fixtures/java-builds/packages/example-java-app-gradle-0.1.0.jar",
|
||||
expected: map[string]pkg.Package{
|
||||
"example-java-app-gradle": {
|
||||
@ -172,6 +175,16 @@ func TestParseJar(t *testing.T) {
|
||||
Language: pkg.Java,
|
||||
Type: pkg.JavaPkg,
|
||||
MetadataType: pkg.JavaMetadataType,
|
||||
Licenses: pkg.NewLicenseSet(
|
||||
pkg.NewLicenseFromFields(
|
||||
"Apache 2",
|
||||
"http://www.apache.org/licenses/LICENSE-2.0.txt",
|
||||
func() *file.Location {
|
||||
l := file.NewLocation("test-fixtures/java-builds/packages/example-java-app-gradle-0.1.0.jar")
|
||||
return &l
|
||||
}(),
|
||||
),
|
||||
),
|
||||
Metadata: pkg.JavaMetadata{
|
||||
// ensure that nested packages with different names than that of the parent are appended as
|
||||
// a suffix on the virtual path with a colon separator between group name and artifact name
|
||||
@ -196,6 +209,7 @@ func TestParseJar(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "example-java-app-maven",
|
||||
fixture: "test-fixtures/java-builds/packages/example-java-app-maven-0.1.0.jar",
|
||||
ignoreExtras: []string{
|
||||
"Build-Jdk", // can't guarantee the JDK used at build time
|
||||
@ -234,6 +248,16 @@ func TestParseJar(t *testing.T) {
|
||||
Name: "joda-time",
|
||||
Version: "2.9.2",
|
||||
PURL: "pkg:maven/joda-time/joda-time@2.9.2",
|
||||
Licenses: pkg.NewLicenseSet(
|
||||
pkg.NewLicenseFromFields(
|
||||
"Apache 2",
|
||||
"http://www.apache.org/licenses/LICENSE-2.0.txt",
|
||||
func() *file.Location {
|
||||
l := file.NewLocation("test-fixtures/java-builds/packages/example-java-app-maven-0.1.0.jar")
|
||||
return &l
|
||||
}(),
|
||||
),
|
||||
),
|
||||
Language: pkg.Java,
|
||||
Type: pkg.JavaPkg,
|
||||
MetadataType: pkg.JavaMetadataType,
|
||||
@ -263,7 +287,7 @@ func TestParseJar(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(path.Base(test.fixture), func(t *testing.T) {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
|
||||
generateJavaBuildFixture(t, test.fixture)
|
||||
|
||||
@ -618,7 +642,7 @@ func Test_newPackageFromMavenData(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
props pkg.PomProperties
|
||||
project *pkg.PomProject
|
||||
project *parsedPomProject
|
||||
parent *pkg.Package
|
||||
expectedParent pkg.Package
|
||||
expectedPackage *pkg.Package
|
||||
@ -687,7 +711,8 @@ func Test_newPackageFromMavenData(t *testing.T) {
|
||||
ArtifactID: "some-artifact-id",
|
||||
Version: "1.0",
|
||||
},
|
||||
project: &pkg.PomProject{
|
||||
project: &parsedPomProject{
|
||||
PomProject: &pkg.PomProject{
|
||||
Parent: &pkg.PomParent{
|
||||
GroupID: "some-parent-group-id",
|
||||
ArtifactID: "some-parent-artifact-id",
|
||||
@ -700,6 +725,16 @@ func Test_newPackageFromMavenData(t *testing.T) {
|
||||
Description: "desc",
|
||||
URL: "aweso.me",
|
||||
},
|
||||
Licenses: []pkg.License{
|
||||
{
|
||||
Value: "MIT",
|
||||
SPDXExpression: "MIT",
|
||||
Type: license.Declared,
|
||||
URLs: internal.NewStringSet("https://opensource.org/licenses/MIT"),
|
||||
Locations: file.NewLocationSet(file.NewLocation("some-license-path")),
|
||||
},
|
||||
},
|
||||
},
|
||||
parent: &pkg.Package{
|
||||
Name: "some-parent-name",
|
||||
Version: "2.0",
|
||||
@ -727,6 +762,15 @@ func Test_newPackageFromMavenData(t *testing.T) {
|
||||
Language: pkg.Java,
|
||||
Type: pkg.JavaPkg,
|
||||
MetadataType: pkg.JavaMetadataType,
|
||||
Licenses: pkg.NewLicenseSet(
|
||||
pkg.License{
|
||||
Value: "MIT",
|
||||
SPDXExpression: "MIT",
|
||||
Type: license.Declared,
|
||||
URLs: internal.NewStringSet("https://opensource.org/licenses/MIT"),
|
||||
Locations: file.NewLocationSet(file.NewLocation("some-license-path")),
|
||||
},
|
||||
),
|
||||
Metadata: pkg.JavaMetadata{
|
||||
VirtualPath: virtualPath + ":" + "some-group-id" + ":" + "some-artifact-id",
|
||||
PomProperties: &pkg.PomProperties{
|
||||
|
||||
@ -49,20 +49,41 @@ func parserPomXML(_ file.Resolver, _ *generic.Environment, reader file.LocationR
|
||||
return pkgs, nil, nil
|
||||
}
|
||||
|
||||
func parsePomXMLProject(path string, reader io.Reader) (*pkg.PomProject, error) {
|
||||
func parsePomXMLProject(path string, reader io.Reader, location file.Location) (*parsedPomProject, error) {
|
||||
project, err := decodePomXML(reader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newPomProject(path, project), nil
|
||||
return newPomProject(path, project, location), nil
|
||||
}
|
||||
|
||||
func newPomProject(path string, p gopom.Project) *pkg.PomProject {
|
||||
func newPomProject(path string, p gopom.Project, location file.Location) *parsedPomProject {
|
||||
artifactID := safeString(p.ArtifactID)
|
||||
name := safeString(p.Name)
|
||||
projectURL := safeString(p.URL)
|
||||
|
||||
var licenses []pkg.License
|
||||
if p.Licenses != nil {
|
||||
for _, license := range *p.Licenses {
|
||||
var licenseName, licenseURL string
|
||||
if license.Name != nil {
|
||||
licenseName = *license.Name
|
||||
}
|
||||
if license.URL != nil {
|
||||
licenseURL = *license.URL
|
||||
}
|
||||
|
||||
if licenseName == "" && licenseURL == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
licenses = append(licenses, pkg.NewLicenseFromFields(licenseName, licenseURL, &location))
|
||||
}
|
||||
}
|
||||
|
||||
log.WithFields("path", path, "artifactID", artifactID, "name", name, "projectURL", projectURL).Trace("parsing pom.xml")
|
||||
return &pkg.PomProject{
|
||||
return &parsedPomProject{
|
||||
PomProject: &pkg.PomProject{
|
||||
Path: path,
|
||||
Parent: pomParent(p, p.Parent),
|
||||
GroupID: resolveProperty(p, p.GroupID, "groupId"),
|
||||
@ -71,6 +92,8 @@ func newPomProject(path string, p gopom.Project) *pkg.PomProject {
|
||||
Name: name,
|
||||
Description: cleanDescription(p.Description),
|
||||
URL: projectURL,
|
||||
},
|
||||
Licenses: licenses,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -11,7 +11,9 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/vifraa/gopom"
|
||||
|
||||
"github.com/anchore/syft/internal"
|
||||
"github.com/anchore/syft/syft/file"
|
||||
"github.com/anchore/syft/syft/license"
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
"github.com/anchore/syft/syft/pkg/cataloger/internal/pkgtest"
|
||||
)
|
||||
@ -293,11 +295,16 @@ func Test_parseCommonsTextPomXMLProject(t *testing.T) {
|
||||
}
|
||||
|
||||
func Test_parsePomXMLProject(t *testing.T) {
|
||||
// TODO: ideally we would have the path to the contained pom.xml, not the jar
|
||||
jarLocation := file.NewLocation("path/to/archive.jar")
|
||||
tests := []struct {
|
||||
expected pkg.PomProject
|
||||
name string
|
||||
expected parsedPomProject
|
||||
}{
|
||||
{
|
||||
expected: pkg.PomProject{
|
||||
name: "go case",
|
||||
expected: parsedPomProject{
|
||||
PomProject: &pkg.PomProject{
|
||||
Path: "test-fixtures/pom/commons-codec.pom.xml",
|
||||
Parent: &pkg.PomParent{
|
||||
GroupID: "org.apache.commons",
|
||||
@ -312,14 +319,55 @@ func Test_parsePomXMLProject(t *testing.T) {
|
||||
URL: "http://commons.apache.org/proper/commons-codec/",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with license data",
|
||||
expected: parsedPomProject{
|
||||
PomProject: &pkg.PomProject{
|
||||
Path: "test-fixtures/pom/neo4j-license-maven-plugin.pom.xml",
|
||||
Parent: &pkg.PomParent{
|
||||
GroupID: "org.sonatype.oss",
|
||||
ArtifactID: "oss-parent",
|
||||
Version: "7",
|
||||
},
|
||||
GroupID: "org.neo4j.build.plugins",
|
||||
ArtifactID: "license-maven-plugin",
|
||||
Version: "4-SNAPSHOT",
|
||||
Name: "${project.artifactId}", // TODO: this is not an ideal answer
|
||||
Description: "Maven 2 plugin to check and update license headers in source files",
|
||||
URL: "http://components.neo4j.org/${project.artifactId}/${project.version}", // TODO: this is not an ideal answer
|
||||
},
|
||||
Licenses: []pkg.License{
|
||||
{
|
||||
Value: "The Apache Software License, Version 2.0",
|
||||
SPDXExpression: "", // TODO: ideally we would parse this title to get Apache-2.0 (created issue #2210 https://github.com/anchore/syft/issues/2210)
|
||||
Type: license.Declared,
|
||||
URLs: internal.NewStringSet("http://www.apache.org/licenses/LICENSE-2.0.txt"),
|
||||
Locations: file.NewLocationSet(jarLocation),
|
||||
},
|
||||
{
|
||||
Value: "MIT",
|
||||
SPDXExpression: "MIT",
|
||||
Type: license.Declared,
|
||||
URLs: internal.NewStringSet(),
|
||||
Locations: file.NewLocationSet(jarLocation),
|
||||
},
|
||||
{
|
||||
Type: license.Declared,
|
||||
URLs: internal.NewStringSet("https://opensource.org/license/unlicense/"),
|
||||
Locations: file.NewLocationSet(jarLocation),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.expected.Path, func(t *testing.T) {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
fixture, err := os.Open(test.expected.Path)
|
||||
assert.NoError(t, err)
|
||||
|
||||
actual, err := parsePomXMLProject(fixture.Name(), fixture)
|
||||
actual, err := parsePomXMLProject(fixture.Name(), fixture, jarLocation)
|
||||
assert.NoError(t, err)
|
||||
|
||||
assert.Equal(t, &test.expected, actual)
|
||||
|
||||
@ -0,0 +1,459 @@
|
||||
<!-- sourced from https://github.com/neo4j/license-maven-plugin/blob/3/pom.xml -->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.sonatype.oss</groupId>
|
||||
<artifactId>oss-parent</artifactId>
|
||||
<version>7</version>
|
||||
<relativePath />
|
||||
</parent>
|
||||
|
||||
<groupId>org.neo4j.build.plugins</groupId>
|
||||
<artifactId>license-maven-plugin</artifactId>å
|
||||
<version>4-SNAPSHOT</version>
|
||||
<packaging>maven-plugin</packaging>
|
||||
|
||||
<name>${project.artifactId}</name>
|
||||
<description>Maven 2 plugin to check and update license headers in source files</description>
|
||||
<url>http://components.neo4j.org/${project.artifactId}/${project.version}</url>
|
||||
<inceptionYear>2008</inceptionYear>
|
||||
|
||||
<!--
|
||||
Properties
|
||||
-->
|
||||
|
||||
<properties>
|
||||
<jdk>1.6</jdk>
|
||||
<jdk.version>1.6</jdk.version>
|
||||
</properties>
|
||||
|
||||
<!--
|
||||
Versioning system
|
||||
-->
|
||||
|
||||
<scm>
|
||||
<connection>scm:git:git://github.com/neo4j/license-maven-plugin.git</connection>
|
||||
<developerConnection>scm:git:git@github.com:neo4j/license-maven-plugin.git</developerConnection>
|
||||
<url>https://github.com/neo4j/license-maven-plugin</url>
|
||||
</scm>
|
||||
|
||||
<!--
|
||||
Project settings
|
||||
-->
|
||||
|
||||
<organization>
|
||||
<name>Mathieu Carbou</name>
|
||||
<url>http://mathieu.carbou.free.fr/</url>
|
||||
</organization>
|
||||
|
||||
<licenses>
|
||||
<!-- this has been modified for the purposes of a syft test -->
|
||||
<license>
|
||||
<name>The Apache Software License, Version 2.0</name>
|
||||
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
|
||||
<distribution>repo</distribution>
|
||||
</license>
|
||||
<license>
|
||||
<name>MIT</name>
|
||||
</license>
|
||||
<license>
|
||||
<url>https://opensource.org/license/unlicense/</url>
|
||||
</license>
|
||||
</licenses>
|
||||
|
||||
<developers>
|
||||
<developer>
|
||||
<id>mimilowns</id>
|
||||
<name>Cédric</name>
|
||||
<email>mimilowns@gmail.com</email>
|
||||
<timezone>+1</timezone>
|
||||
<roles>
|
||||
<role>developer</role>
|
||||
</roles>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>mathieu.carbou</id>
|
||||
<name>Mathieu Carbou</name>
|
||||
<email>mathieu.carbou@gmail.com</email>
|
||||
<organization>Mycila</organization>
|
||||
<organizationUrl>http://mathieu.carbou.free.fr/</organizationUrl>
|
||||
<timezone>-5</timezone>
|
||||
<roles>
|
||||
<role>project owner</role>
|
||||
<role>developer</role>
|
||||
</roles>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<issueManagement>
|
||||
<system>Google Code</system>
|
||||
<url>http://code.google.com/p/${project.artifactId}/issues/list</url>
|
||||
</issueManagement>
|
||||
|
||||
<ciManagement />
|
||||
|
||||
<mailingLists>
|
||||
<mailingList>
|
||||
<name>maven-license-plugin-announce</name>
|
||||
<subscribe>maven-license-plugin-announce-subscribe@googlegroups.com</subscribe>
|
||||
<unsubscribe>maven-license-plugin-announce-unsubscribe@googlegroups.com</unsubscribe>
|
||||
<archive>http://groups.google.com/group/maven-license-plugin-announce</archive>
|
||||
</mailingList>
|
||||
<mailingList>
|
||||
<name>maven-license-plugin-codesite</name>
|
||||
<subscribe>maven-license-plugin-codesite-subscribe@googlegroups.com</subscribe>
|
||||
<unsubscribe>maven-license-plugin-codesite-unsubscribe@googlegroups.com</unsubscribe>
|
||||
<archive>http://groups.google.com/group/maven-license-plugin-codesite</archive>
|
||||
</mailingList>
|
||||
</mailingLists>
|
||||
|
||||
<!--
|
||||
Distributions
|
||||
-->
|
||||
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<id>sonatype-nexus-staging</id>
|
||||
<name>Nexus Release Repository</name>
|
||||
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
|
||||
</repository>
|
||||
<snapshotRepository>
|
||||
<id>snapshots@m2.neo4j.org</id>
|
||||
<name>snapshots@m2.neo4j.org</name>
|
||||
<url>http://m2.neo4j.org/content/repositories/snapshots</url>
|
||||
</snapshotRepository>
|
||||
<site>
|
||||
<id>neo4j-site</id>
|
||||
<url>scpexe://components.neo4j.org/home/neo/components/${project.artifactId}/${project.version}</url>
|
||||
</site>
|
||||
</distributionManagement>
|
||||
|
||||
<!--
|
||||
BUILD
|
||||
-->
|
||||
|
||||
<build>
|
||||
<extensions>
|
||||
<extension>
|
||||
<groupId>org.apache.maven.wagon</groupId>
|
||||
<artifactId>wagon-webdav</artifactId>
|
||||
<version>1.0-beta-2</version>
|
||||
</extension>
|
||||
</extensions>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<version>2.1.0</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-ipojo-plugin</artifactId>
|
||||
<version>1.6.0</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.mycila.maven-license-plugin</groupId>
|
||||
<artifactId>maven-license-plugin</artifactId>
|
||||
<version>1.8.0</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<version>1.4</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>2.1.2</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>2.3.1</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>2.7</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<version>2.5</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-clean-plugin</artifactId>
|
||||
<version>2.4.1</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-invoker-plugin</artifactId>
|
||||
<version>1.5</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>1.3.3</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<version>2.2-beta-5</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<version>2.1</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>2.3.1</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-release-plugin</artifactId>
|
||||
<version>2.0</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.6</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-gpg-plugin</artifactId>
|
||||
<version>1.4</version>
|
||||
<configuration>
|
||||
<keyname>Neo Technology Build Server</keyname>
|
||||
<useAgent>true</useAgent>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<!-- for maven plugins -->
|
||||
<plugin>
|
||||
<artifactId>maven-plugin-plugin</artifactId>
|
||||
<version>2.6</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-clean-plugin</artifactId>
|
||||
<configuration>
|
||||
<filesets>
|
||||
<fileset>
|
||||
<directory>.clover</directory>
|
||||
</fileset>
|
||||
<fileset>
|
||||
<directory>test-output</directory>
|
||||
</fileset>
|
||||
</filesets>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!-- compilation -->
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>${jdk}</source>
|
||||
<target>${jdk}</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!-- testing -->
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
</plugin>
|
||||
<!-- packaging -->
|
||||
<plugin>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
|
||||
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-sources</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-remote-resources-plugin</artifactId>
|
||||
<version>1.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>process</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<resourceBundles>
|
||||
<resourceBundle>org.apache:apache-jar-resource-bundle:1.3</resourceBundle>
|
||||
</resourceBundles>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<configuration>
|
||||
<descriptorRefs>
|
||||
<descriptorRef>project</descriptorRef>
|
||||
</descriptorRefs>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<!-- releasing -->
|
||||
<plugin>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<configuration>
|
||||
<updateReleaseInfo>true</updateReleaseInfo>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-release-plugin</artifactId>
|
||||
</plugin>
|
||||
<!-- documentation -->
|
||||
<plugin>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.mycila.maven-license-plugin</groupId>
|
||||
<artifactId>maven-license-plugin</artifactId>
|
||||
<version>1.9.0</version>
|
||||
<configuration>
|
||||
<header>${basedir}/src/etc/header.txt</header>
|
||||
<failIfMissing>true</failIfMissing>
|
||||
<excludes>
|
||||
<exclude>.gitignore</exclude>
|
||||
<exclude>LICENSE.txt</exclude>
|
||||
<exclude>NOTICE.txt</exclude>
|
||||
<exclude>src/test/data/**</exclude>
|
||||
<exclude>src/test/integration/**</exclude>
|
||||
<exclude>src/test/resources/**</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>check</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<!-- automatically handle it tests -->
|
||||
<plugin>
|
||||
<artifactId>maven-clean-plugin</artifactId>
|
||||
<configuration>
|
||||
<filesets>
|
||||
<fileset>
|
||||
<directory>it</directory>
|
||||
<includes>
|
||||
<include>target/**</include>
|
||||
<include>*/target/**</include>
|
||||
</includes>
|
||||
</fileset>
|
||||
<fileset>
|
||||
<directory>target</directory>
|
||||
</fileset>
|
||||
</filesets>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<inherited>true</inherited>
|
||||
<artifactId>maven-invoker-plugin</artifactId>
|
||||
<configuration>
|
||||
<projectsDirectory>it</projectsDirectory>
|
||||
<showErrors>true</showErrors>
|
||||
<streamLogs>true</streamLogs>
|
||||
<skipInstallation>${ittest.skip}</skipInstallation>
|
||||
<skipInvocation>${ittest.skip}</skipInvocation>
|
||||
<properties>
|
||||
<target.version>${target.version}</target.version>
|
||||
</properties>
|
||||
<goals>
|
||||
<goal>test</goal>
|
||||
</goals>
|
||||
<pomIncludes>
|
||||
<pomInclude>**/pom.xml</pomInclude>
|
||||
</pomIncludes>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>integration-test</id>
|
||||
<goals>
|
||||
<goal>install</goal>
|
||||
<goal>run</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<!--
|
||||
LIBS
|
||||
-->
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-plugin-api</artifactId>
|
||||
<version>3.0.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.mycila.xmltool</groupId>
|
||||
<artifactId>xmltool</artifactId>
|
||||
<version>3.3</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-project</artifactId>
|
||||
<version>3.0-alpha-2</version>
|
||||
<scope>compile</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>junit</artifactId>
|
||||
<groupId>junit</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.codehaus.plexus</groupId>
|
||||
<artifactId>plexus-utils</artifactId>
|
||||
<version>2.0.5</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<!-- testing -->
|
||||
<dependency>
|
||||
<groupId>org.testng</groupId>
|
||||
<artifactId>testng</artifactId>
|
||||
<version>5.7</version>
|
||||
<classifier>jdk15</classifier>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>junit</artifactId>
|
||||
<groupId>junit</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-embedder</artifactId>
|
||||
<version>3.0.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven.plugin-testing</groupId>
|
||||
<artifactId>maven-plugin-testing-harness</artifactId>
|
||||
<version>2.0-alpha-1</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>junit</artifactId>
|
||||
<groupId>junit</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@ -60,25 +60,18 @@ func (l Licenses) Swap(i, j int) {
|
||||
}
|
||||
|
||||
func NewLicense(value string) License {
|
||||
spdxExpression, err := license.ParseExpression(value)
|
||||
if err != nil {
|
||||
log.Trace("unable to parse license expression for %q: %w", value, err)
|
||||
}
|
||||
|
||||
return License{
|
||||
Value: value,
|
||||
SPDXExpression: spdxExpression,
|
||||
Type: license.Declared,
|
||||
URLs: internal.NewStringSet(),
|
||||
Locations: file.NewLocationSet(),
|
||||
}
|
||||
return NewLicenseFromType(value, license.Declared)
|
||||
}
|
||||
|
||||
func NewLicenseFromType(value string, t license.Type) License {
|
||||
spdxExpression, err := license.ParseExpression(value)
|
||||
var spdxExpression string
|
||||
if value != "" {
|
||||
var err error
|
||||
spdxExpression, err = license.ParseExpression(value)
|
||||
if err != nil {
|
||||
log.Trace("unable to parse license expression: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return License{
|
||||
Value: value,
|
||||
@ -124,6 +117,17 @@ func NewLicenseFromURLs(value string, urls ...string) License {
|
||||
return l
|
||||
}
|
||||
|
||||
func NewLicenseFromFields(value, url string, location *file.Location) License {
|
||||
l := NewLicense(value)
|
||||
if location != nil {
|
||||
l.Locations.Add(*location)
|
||||
}
|
||||
if url != "" {
|
||||
l.URLs.Add(url)
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
// this is a bit of a hack to not infinitely recurse when hashing a license
|
||||
func (s License) Merge(l License) (*License, error) {
|
||||
sHash, err := artifact.IDByHash(s)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user