diff --git a/go.mod b/go.mod
index 8fb0449fce..13ea845b56 100644
--- a/go.mod
+++ b/go.mod
@@ -3,10 +3,10 @@ module github.com/google/osv-scanner
go 1.21.12
require (
- deps.dev/api/v3 v3.0.0-20240711010811-c5a1406b0470
- deps.dev/util/maven v0.0.0-20240711010811-c5a1406b0470
- deps.dev/util/resolve v0.0.0-20240711010811-c5a1406b0470
- deps.dev/util/semver v0.0.0-20240711010811-c5a1406b0470
+ deps.dev/api/v3 v3.0.0-20240730004939-e80e6658c33b
+ deps.dev/util/maven v0.0.0-20240730004939-e80e6658c33b
+ deps.dev/util/resolve v0.0.0-20240730004939-e80e6658c33b
+ deps.dev/util/semver v0.0.0-20240730004939-e80e6658c33b
github.com/BurntSushi/toml v1.4.0
github.com/CycloneDX/cyclonedx-go v0.9.0
github.com/charmbracelet/bubbles v0.18.0
diff --git a/go.sum b/go.sum
index 6dfe294a16..feca9a9981 100644
--- a/go.sum
+++ b/go.sum
@@ -1,13 +1,13 @@
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
-deps.dev/api/v3 v3.0.0-20240711010811-c5a1406b0470 h1:AXexCbWOahap0SWSsyDbEkeGJt2KxX4+1zWWZ+RsWQU=
-deps.dev/api/v3 v3.0.0-20240711010811-c5a1406b0470/go.mod h1:DyBY3wNVqRCwvb4tLvz6LL/FupH3FMflEROyQAv2Vi0=
-deps.dev/util/maven v0.0.0-20240711010811-c5a1406b0470 h1:T990wxZ1ph9gKl8K4/qzorVmS24rNj2pNBTl5BYMxXA=
-deps.dev/util/maven v0.0.0-20240711010811-c5a1406b0470/go.mod h1:SBW3EribdkZYk6zxi5oVn/ZECvi4ixb7EGgEWfSimNk=
-deps.dev/util/resolve v0.0.0-20240711010811-c5a1406b0470 h1:/djBEKpc04deGl+68W1nv7GnsygaVnmAFZCgadZEWPs=
-deps.dev/util/resolve v0.0.0-20240711010811-c5a1406b0470/go.mod h1:XXi6yRYqhtxw5DvGX/mbG6fHSLn8OgoPowNd8EAxDgk=
-deps.dev/util/semver v0.0.0-20240711010811-c5a1406b0470 h1:3wJIdP0Z4so7k3PjqwxVIhCOrrYDsTOe2GBsInNEZWM=
-deps.dev/util/semver v0.0.0-20240711010811-c5a1406b0470/go.mod h1:jkcH+k02gWHBiZ7G4OnUOkSZ6WDq54Pt5DrOA8FN8Uo=
+deps.dev/api/v3 v3.0.0-20240730004939-e80e6658c33b h1:uWv66hsFIMA+4mfvYroVOpJ4+trL7PVc4zTiJ+FVUpE=
+deps.dev/api/v3 v3.0.0-20240730004939-e80e6658c33b/go.mod h1:DyBY3wNVqRCwvb4tLvz6LL/FupH3FMflEROyQAv2Vi0=
+deps.dev/util/maven v0.0.0-20240730004939-e80e6658c33b h1:4/2szyn/8mZhaI3PW/JkRRDpv0aVMILL/R0rICgAA50=
+deps.dev/util/maven v0.0.0-20240730004939-e80e6658c33b/go.mod h1:SBW3EribdkZYk6zxi5oVn/ZECvi4ixb7EGgEWfSimNk=
+deps.dev/util/resolve v0.0.0-20240730004939-e80e6658c33b h1:MTE07TVpmsX13qjSHiVxLPR2u52R7w8m0TBlk7rNvF8=
+deps.dev/util/resolve v0.0.0-20240730004939-e80e6658c33b/go.mod h1:XXi6yRYqhtxw5DvGX/mbG6fHSLn8OgoPowNd8EAxDgk=
+deps.dev/util/semver v0.0.0-20240730004939-e80e6658c33b h1:kGG4/rm/slq+X/SfMVS7JnDBWeJhX2u2EudaPJeHyHI=
+deps.dev/util/semver v0.0.0-20240730004939-e80e6658c33b/go.mod h1:jkcH+k02gWHBiZ7G4OnUOkSZ6WDq54Pt5DrOA8FN8Uo=
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/CycloneDX/cyclonedx-go v0.9.0 h1:inaif7qD8bivyxp7XLgxUYtOXWtDez7+j72qKTMQTb8=
diff --git a/internal/manifest/fixtures/maven/my-app/pom.xml b/internal/manifest/fixtures/maven/my-app/pom.xml
new file mode 100644
index 0000000000..d01d047889
--- /dev/null
+++ b/internal/manifest/fixtures/maven/my-app/pom.xml
@@ -0,0 +1,8 @@
+
+
+
+ org.test
+ my-app
+ 1.0.0
+
+
diff --git a/internal/resolution/manifest/fixtures/maven/pom.xml b/internal/manifest/fixtures/maven/pom.xml
similarity index 80%
rename from internal/resolution/manifest/fixtures/maven/pom.xml
rename to internal/manifest/fixtures/maven/pom.xml
index cb678cdf43..1d2896858e 100644
--- a/internal/resolution/manifest/fixtures/maven/pom.xml
+++ b/internal/manifest/fixtures/maven/pom.xml
@@ -1,8 +1,6 @@
- 4.0.0
-
org.test
test
1.0.0
diff --git a/internal/manifest/maven.go b/internal/manifest/maven.go
index f1a39ce347..f7b39bf9ab 100644
--- a/internal/manifest/maven.go
+++ b/internal/manifest/maven.go
@@ -14,12 +14,18 @@ import (
mavenresolve "deps.dev/util/resolve/maven"
"github.com/google/osv-scanner/internal/resolution/client"
"github.com/google/osv-scanner/internal/resolution/datasource"
- "github.com/google/osv-scanner/internal/resolution/manifest"
"github.com/google/osv-scanner/internal/resolution/util"
"github.com/google/osv-scanner/pkg/lockfile"
"golang.org/x/exp/maps"
)
+const (
+ OriginManagement = "management"
+ OriginParent = "parent"
+ OriginPlugin = "plugin"
+ OriginProfile = "profile"
+)
+
type MavenResolverExtractor struct {
client.DependencyClient
datasource.MavenRegistryAPIClient
@@ -37,7 +43,7 @@ func (e MavenResolverExtractor) Extract(f lockfile.DepFile) ([]lockfile.PackageD
return []lockfile.PackageDetails{}, fmt.Errorf("could not extract from %s: %w", f.Path(), err)
}
// Merging parents data by parsing local parent pom.xml or fetching from upstream.
- if err := e.mergeParents(ctx, &project, project.Parent, 1, true, f.Path()); err != nil {
+ if err := MergeMavenParents(ctx, e.MavenRegistryAPIClient, &project, project.Parent, 1, f.Path(), true); err != nil {
return []lockfile.PackageDetails{}, fmt.Errorf("failed to merge parents: %w", err)
}
// Process the dependencies:
@@ -47,7 +53,7 @@ func (e MavenResolverExtractor) Extract(f lockfile.DepFile) ([]lockfile.PackageD
project.ProcessDependencies(func(groupID, artifactID, version maven.String) (maven.DependencyManagement, error) {
root := maven.Parent{ProjectKey: maven.ProjectKey{GroupID: groupID, ArtifactID: artifactID, Version: version}}
var result maven.Project
- if err := e.mergeParents(ctx, &result, root, 0, false, f.Path()); err != nil {
+ if err := MergeMavenParents(ctx, e.MavenRegistryAPIClient, &result, root, 0, f.Path(), false); err != nil {
return maven.DependencyManagement{}, err
}
@@ -91,7 +97,7 @@ func (e MavenResolverExtractor) Extract(f lockfile.DepFile) ([]lockfile.PackageD
VersionType: resolve.Requirement,
Version: string(d.Version),
},
- Type: resolve.MavenDepType(d, manifest.OriginManagement),
+ Type: resolve.MavenDepType(d, OriginManagement),
}
}
overrideClient.AddVersion(root, reqs)
@@ -130,7 +136,7 @@ func (e MavenResolverExtractor) Extract(f lockfile.DepFile) ([]lockfile.PackageD
// MaxParent sets a limit on the number of parents to avoid indefinite loop.
const MaxParent = 100
-// mergeParents parses local accessible parent pom.xml or fetches it from
+// MergeMavenParents parses local accessible parent pom.xml or fetches it from
// upstream, merges into root project, then interpolate the properties.
// result holds the merged Maven project.
// current holds the current parent project to merge.
@@ -139,7 +145,7 @@ const MaxParent = 100
// allowLocal indicates whether parsing local parent pom.xml is allowed.
// path holds the path to the current pom.xml, which is used to compute the
// relative path of parent.
-func (e MavenResolverExtractor) mergeParents(ctx context.Context, result *maven.Project, current maven.Parent, start int, allowLocal bool, path string) error {
+func MergeMavenParents(ctx context.Context, mavenClient datasource.MavenRegistryAPIClient, result *maven.Project, current maven.Parent, start int, path string, allowLocal bool) error {
currentPath := path
visited := make(map[maven.ProjectKey]bool, MaxParent)
for n := start; n < MaxParent; n++ {
@@ -154,7 +160,7 @@ func (e MavenResolverExtractor) mergeParents(ctx context.Context, result *maven.
var proj maven.Project
parentFound := false
- if parentPath := manifest.MavenParentPOMPath(currentPath, string(current.RelativePath)); allowLocal && parentPath != "" {
+ if parentPath := MavenParentPOMPath(currentPath, string(current.RelativePath)); allowLocal && parentPath != "" {
currentPath = parentPath
f, err := os.Open(parentPath)
if err != nil {
@@ -174,7 +180,7 @@ func (e MavenResolverExtractor) mergeParents(ctx context.Context, result *maven.
allowLocal = false
var err error
- proj, err = e.MavenRegistryAPIClient.GetProject(ctx, string(current.GroupID), string(current.ArtifactID), string(current.Version))
+ proj, err = mavenClient.GetProject(ctx, string(current.GroupID), string(current.ArtifactID), string(current.Version))
if err != nil {
return fmt.Errorf("failed to get Maven project %s:%s:%s: %w", current.GroupID, current.ArtifactID, current.Version, err)
}
@@ -198,6 +204,28 @@ func (e MavenResolverExtractor) mergeParents(ctx context.Context, result *maven.
return result.Interpolate()
}
+// Maven looks for the parent POM first in 'relativePath',
+// then the local repository '../pom.xml',
+// and lastly in the remote repo.
+func MavenParentPOMPath(currentPath, relativePath string) string {
+ if relativePath == "" {
+ relativePath = "../pom.xml"
+ }
+ path := filepath.Join(filepath.Dir(currentPath), relativePath)
+ if info, err := os.Stat(path); err == nil {
+ if !info.IsDir() {
+ return path
+ }
+ // Current path is a directory, so look for pom.xml in the directory.
+ path = filepath.Join(path, "pom.xml")
+ if _, err := os.Stat(path); err == nil {
+ return path
+ }
+ }
+
+ return ""
+}
+
func ParseMavenWithResolver(depClient client.DependencyClient, mavenClient datasource.MavenRegistryAPIClient, pathToLockfile string) ([]lockfile.PackageDetails, error) {
f, err := lockfile.OpenLocalDepFile(pathToLockfile)
if err != nil {
diff --git a/internal/manifest/maven_test.go b/internal/manifest/maven_test.go
index 0b8e73048f..d8b9fe1aba 100644
--- a/internal/manifest/maven_test.go
+++ b/internal/manifest/maven_test.go
@@ -2,6 +2,8 @@ package manifest_test
import (
"io/fs"
+ "os"
+ "path/filepath"
"testing"
"github.com/google/osv-scanner/internal/manifest"
@@ -358,3 +360,65 @@ func TestParseMavenWithResolver_Transitive(t *testing.T) {
},
})
}
+
+func TestParentPOMPath(t *testing.T) {
+ t.Parallel()
+ dir, err := os.Getwd()
+ if err != nil {
+ t.Fatalf("failed to get current directory: %v", err)
+ }
+ tests := []struct {
+ currentPath, relativePath string
+ want string
+ }{
+ // fixtures
+ // |- maven
+ // | |- my-app
+ // | | |- pom.xml
+ // | |- parent
+ // | | |- pom.xml
+ // |- pom.xml
+ {
+ // Parent path is specified correctly.
+ currentPath: filepath.Join(dir, "fixtures", "maven", "my-app", "pom.xml"),
+ relativePath: "../parent/pom.xml",
+ want: filepath.Join(dir, "fixtures", "maven", "parent", "pom.xml"),
+ },
+ {
+ // Wrong file name is specified in relative path.
+ currentPath: filepath.Join(dir, "fixtures", "maven", "my-app", "pom.xml"),
+ relativePath: "../parent/abc.xml",
+ want: "",
+ },
+ {
+ // Wrong directory is specified in relative path.
+ currentPath: filepath.Join(dir, "fixtures", "maven", "my-app", "pom.xml"),
+ relativePath: "../not-found/pom.xml",
+ want: "",
+ },
+ {
+ // Only directory is specified.
+ currentPath: filepath.Join(dir, "fixtures", "maven", "my-app", "pom.xml"),
+ relativePath: "../parent",
+ want: filepath.Join(dir, "fixtures", "maven", "parent", "pom.xml"),
+ },
+ {
+ // Parent relative path is default to '../pom.xml'.
+ currentPath: filepath.Join(dir, "fixtures", "maven", "my-app", "pom.xml"),
+ relativePath: "",
+ want: filepath.Join(dir, "fixtures", "maven", "pom.xml"),
+ },
+ {
+ // No pom.xml is found even in the default path.
+ currentPath: filepath.Join(dir, "fixtures", "maven", "pom.xml"),
+ relativePath: "",
+ want: "",
+ },
+ }
+ for _, test := range tests {
+ got := manifest.MavenParentPOMPath(test.currentPath, test.relativePath)
+ if got != test.want {
+ t.Errorf("parentPOMPath(%s, %s): got %s, want %s", test.currentPath, test.relativePath, got, test.want)
+ }
+ }
+}
diff --git a/internal/remediation/override.go b/internal/remediation/override.go
index bc75c2651b..9cedc63974 100644
--- a/internal/remediation/override.go
+++ b/internal/remediation/override.go
@@ -9,9 +9,10 @@ import (
"deps.dev/util/resolve"
"deps.dev/util/resolve/dep"
"deps.dev/util/semver"
+ "github.com/google/osv-scanner/internal/manifest"
"github.com/google/osv-scanner/internal/resolution"
"github.com/google/osv-scanner/internal/resolution/client"
- "github.com/google/osv-scanner/internal/resolution/manifest"
+ resolutionmanifest "github.com/google/osv-scanner/internal/resolution/manifest"
"github.com/google/osv-scanner/internal/resolution/util"
"github.com/google/osv-scanner/internal/utility/vulns"
)
@@ -76,9 +77,9 @@ func ComputeOverridePatches(ctx context.Context, cl client.ResolutionClient, res
// CalculateDiff does not compute override manifest patches correctly, manually fill it out.
// TODO: CalculateDiff maybe should not be reconstructing patches.
// Refactor CalculateDiff, Relaxer, Override to make patches in a more sane way.
- diff.Deps = make([]manifest.DependencyPatch, len(res.patches))
+ diff.Deps = make([]resolutionmanifest.DependencyPatch, len(res.patches))
for i, p := range res.patches {
- diff.Deps[i] = manifest.DependencyPatch{
+ diff.Deps[i] = resolutionmanifest.DependencyPatch{
Pkg: p.PackageKey,
Type: dep.Type{},
OrigRequire: "", // Using empty original to signal this is an override patch
@@ -279,9 +280,9 @@ func getVersionsGreater(ctx context.Context, cl client.DependencyClient, vk reso
}
// patchManifest applies the overridePatches to the manifest in-memory. Returns a copy of the manifest that has been patched.
-func patchManifest(patches []overridePatch, m manifest.Manifest) (manifest.Manifest, error) {
+func patchManifest(patches []overridePatch, m resolutionmanifest.Manifest) (resolutionmanifest.Manifest, error) {
if m.System() != resolve.Maven {
- return manifest.Manifest{}, errors.New("unsupported ecosystem")
+ return resolutionmanifest.Manifest{}, errors.New("unsupported ecosystem")
}
// TODO: The overridePatch does not have an artifact's type or classifier, which is part of what uniquely identifies them.
diff --git a/internal/resolution/manifest/maven.go b/internal/resolution/manifest/maven.go
index 46a7c31676..6e18ec0b52 100644
--- a/internal/resolution/manifest/maven.go
+++ b/internal/resolution/manifest/maven.go
@@ -8,25 +8,17 @@ import (
"errors"
"fmt"
"io"
- "os"
- "path/filepath"
"slices"
"strings"
"deps.dev/util/maven"
"deps.dev/util/resolve"
"deps.dev/util/resolve/dep"
+ "github.com/google/osv-scanner/internal/manifest"
"github.com/google/osv-scanner/internal/resolution/datasource"
"github.com/google/osv-scanner/pkg/lockfile"
)
-const (
- OriginManagement = "management"
- OriginParent = "parent"
- OriginPlugin = "plugin"
- OriginProfile = "profile"
-)
-
func mavenRequirementKey(requirement resolve.RequirementVersion) RequirementKey {
// Maven dependencies must have unique groupId:artifactId:type:classifier.
artifactType, _ := requirement.Type.GetAttr(dep.MavenArtifactType)
@@ -89,7 +81,7 @@ func (m MavenManifestIO) Read(df lockfile.DepFile) (Manifest, error) {
VersionType: resolve.Requirement,
Version: string(project.Parent.Version),
},
- Type: resolve.MavenDepType(maven.Dependency{Type: "pom"}, OriginParent),
+ Type: resolve.MavenDepType(maven.Dependency{Type: "pom"}, manifest.OriginParent),
})
}
@@ -99,7 +91,7 @@ func (m MavenManifestIO) Read(df lockfile.DepFile) (Manifest, error) {
}
// Merging parents data by parsing local parent pom.xml or fetching from upstream.
- if err := m.mergeParents(ctx, &project, project.Parent, 1, df.Path(), true); err != nil {
+ if err := manifest.MergeMavenParents(ctx, m.MavenRegistryAPIClient, &project, project.Parent, 1, df.Path(), true); err != nil {
return Manifest{}, fmt.Errorf("failed to merge parents: %w", err)
}
@@ -108,7 +100,7 @@ func (m MavenManifestIO) Read(df lockfile.DepFile) (Manifest, error) {
// dependencies, so add them to requirements first.
for _, dep := range project.DependencyManagement.Dependencies {
if dep.Scope == "import" && dep.Type == "pom" {
- reqsForUpdates = append(reqsForUpdates, makeRequirementVersion(dep, OriginManagement))
+ reqsForUpdates = append(reqsForUpdates, makeRequirementVersion(dep, manifest.OriginManagement))
}
}
@@ -122,7 +114,7 @@ func (m MavenManifestIO) Read(df lockfile.DepFile) (Manifest, error) {
// To get dependency management from another project, we need the
// project with parents merged, so we call mergeParents by passing
// an empty project.
- if err := m.mergeParents(ctx, &result, root, 0, "", false); err != nil {
+ if err := manifest.MergeMavenParents(ctx, m.MavenRegistryAPIClient, &result, root, 0, "", false); err != nil {
return maven.DependencyManagement{}, err
}
@@ -131,12 +123,12 @@ func (m MavenManifestIO) Read(df lockfile.DepFile) (Manifest, error) {
groups := make(map[RequirementKey][]string)
requirements := addRequirements([]resolve.RequirementVersion{}, groups, project.Dependencies, "")
- requirements = addRequirements(requirements, groups, project.DependencyManagement.Dependencies, OriginManagement)
+ requirements = addRequirements(requirements, groups, project.DependencyManagement.Dependencies, manifest.OriginManagement)
// Requirements may not appear in the dependency graph but needs to be updated.
for _, profile := range project.Profiles {
reqsForUpdates = addRequirements(reqsForUpdates, groups, profile.Dependencies, "")
- reqsForUpdates = addRequirements(reqsForUpdates, groups, profile.DependencyManagement.Dependencies, OriginManagement)
+ reqsForUpdates = addRequirements(reqsForUpdates, groups, profile.DependencyManagement.Dependencies, manifest.OriginManagement)
}
for _, plugin := range project.Build.PluginManagement.Plugins {
reqsForUpdates = addRequirements(reqsForUpdates, groups, plugin.Dependencies, "")
@@ -190,7 +182,7 @@ func buildPropertiesWithOrigins(project maven.Project) []PropertyWithOrigin {
for _, prop := range profile.Properties.Properties {
properties = append(properties, PropertyWithOrigin{
Property: prop,
- Origin: mavenOrigin(OriginProfile, string(profile.ID)),
+ Origin: mavenOrigin(manifest.OriginProfile, string(profile.ID)),
})
}
}
@@ -208,7 +200,7 @@ func buildOriginalRequirements(project maven.Project) []DependencyWithOrigin {
Version: project.Parent.Version,
Type: "pom",
},
- Origin: OriginParent,
+ Origin: manifest.OriginParent,
})
}
for _, d := range project.Dependencies {
@@ -217,20 +209,20 @@ func buildOriginalRequirements(project maven.Project) []DependencyWithOrigin {
for _, d := range project.DependencyManagement.Dependencies {
dependencies = append(dependencies, DependencyWithOrigin{
Dependency: d,
- Origin: OriginManagement,
+ Origin: manifest.OriginManagement,
})
}
for _, prof := range project.Profiles {
for _, d := range prof.Dependencies {
dependencies = append(dependencies, DependencyWithOrigin{
Dependency: d,
- Origin: mavenOrigin(OriginProfile, string(prof.ID)),
+ Origin: mavenOrigin(manifest.OriginProfile, string(prof.ID)),
})
}
for _, d := range prof.DependencyManagement.Dependencies {
dependencies = append(dependencies, DependencyWithOrigin{
Dependency: d,
- Origin: mavenOrigin(OriginProfile, string(prof.ID), OriginManagement),
+ Origin: mavenOrigin(manifest.OriginProfile, string(prof.ID), manifest.OriginManagement),
})
}
}
@@ -238,7 +230,7 @@ func buildOriginalRequirements(project maven.Project) []DependencyWithOrigin {
for _, d := range plugin.Dependencies {
dependencies = append(dependencies, DependencyWithOrigin{
Dependency: d,
- Origin: mavenOrigin(OriginPlugin, plugin.ProjectKey.Name()),
+ Origin: mavenOrigin(manifest.OriginPlugin, plugin.ProjectKey.Name()),
})
}
}
@@ -246,89 +238,6 @@ func buildOriginalRequirements(project maven.Project) []DependencyWithOrigin {
return dependencies
}
-// To avoid indefinite loop when fetching parents,
-// set a limit on the number of parents.
-const MaxParent = 100
-
-func (m MavenManifestIO) mergeParents(ctx context.Context, result *maven.Project, current maven.Parent, start int, path string, allowLocal bool) error {
- currentPath := path
- visited := make(map[maven.ProjectKey]bool, MaxParent)
- for n := start; n < MaxParent; n++ {
- if current.GroupID == "" || current.ArtifactID == "" || current.Version == "" {
- break
- }
- if visited[current.ProjectKey] {
- // A cycle of parents is detected
- return errors.New("a cycle of parents is detected")
- }
- visited[current.ProjectKey] = true
- var proj maven.Project
- parentFound := false
- if parentPath := MavenParentPOMPath(currentPath, string(current.RelativePath)); allowLocal && parentPath != "" {
- currentPath = parentPath
- f, err := os.Open(parentPath)
- if err != nil {
- return fmt.Errorf("failed to open parent file %s: %w", parentPath, err)
- }
- if err := xml.NewDecoder(f).Decode(&proj); err != nil {
- return fmt.Errorf("failed to unmarshal project: %w", err)
- }
- if proj.ProjectKey == current.ProjectKey && proj.Packaging == "pom" {
- // Only mark parent is found when the identifiers and packaging are exptected.
- parentFound = true
- }
- }
- if !parentFound {
- // Once we fetch a parent pom.xml from upstream, we should not allow
- // parsing parent pom.xml locally anymore.
- allowLocal = false
- var err error
- proj, err = m.MavenRegistryAPIClient.GetProject(ctx, string(current.GroupID), string(current.ArtifactID), string(current.Version))
- if err != nil {
- return fmt.Errorf("failed to get Maven project %s:%s:%s: %w", current.GroupID, current.ArtifactID, current.Version, err)
- }
- if n > 0 && proj.Packaging != "pom" {
- // A parent project should only be of "pom" packaging type.
- return fmt.Errorf("invalid packaging for parent project %s", proj.Packaging)
- }
- if proj.ProjectKey != current.ProjectKey {
- // The identifiers in parent does not match what we want.
- return fmt.Errorf("parent identifiers mismatch: %v, expect %v", proj.ProjectKey, current.ProjectKey)
- }
- }
- // Empty JDK and ActivationOS indicates merging the default profiles.
- if err := result.MergeProfiles("", maven.ActivationOS{}); err != nil {
- return err
- }
- result.MergeParent(proj)
- current = proj.Parent
- }
-
- return result.Interpolate()
-}
-
-// Maven looks for the parent POM first in 'relativePath',
-// then the local repository '../pom.xml',
-// and lastly in the remote repo.
-func MavenParentPOMPath(currentPath, relativePath string) string {
- if relativePath == "" {
- relativePath = "../pom.xml"
- }
- path := filepath.Join(filepath.Dir(currentPath), relativePath)
- if info, err := os.Stat(path); err == nil {
- if !info.IsDir() {
- return path
- }
- // Current path is a directory, so look for pom.xml in the directory.
- path = filepath.Join(path, "pom.xml")
- if _, err := os.Stat(path); err == nil {
- return path
- }
- }
-
- return ""
-}
-
// For dependencies in profiles and plugins, we use origin to indicate where they are from.
// The origin is in the format prefix@identifier[@postfix] (where @ is the separator):
// - prefix indicates it is from profile or plugin
@@ -466,9 +375,9 @@ func buildPatches(patches []DependencyPatch, specific MavenManifestSpecific) (Ma
}
depOrigin := origDep.Origin
- if strings.HasPrefix(depOrigin, OriginProfile) {
+ if strings.HasPrefix(depOrigin, manifest.OriginProfile) {
// Dependency management is not indicated in property origin.
- depOrigin, _ = strings.CutSuffix(depOrigin, "@"+OriginManagement)
+ depOrigin, _ = strings.CutSuffix(depOrigin, "@"+manifest.OriginManagement)
} else {
// Properties are defined either universally or in a profile. For property
// origin not starting with 'profile', this is an universal property.
@@ -663,7 +572,7 @@ func write(buf *bytes.Buffer, w io.Writer, depPatches MavenDependencyPatches, pr
}
// Check whether dependency management is updated, if not, add a new section of dependency management.
- if dmPatches := depPatches[OriginManagement]; len(dmPatches) > 0 && !updated[OriginManagement] {
+ if dmPatches := depPatches[manifest.OriginManagement]; len(dmPatches) > 0 && !updated[manifest.OriginManagement] {
enc.Indent(" ", " ")
var dm dependencyManagement
for p := range dmPatches {
@@ -763,7 +672,7 @@ func writeProject(w io.Writer, enc *xml.Encoder, raw, prefix, id string, patches
if err := dec.DecodeElement(&rawProfile, &tt); err != nil {
return err
}
- if err := writeProject(w, enc, ""+rawProfile.InnerXML+"", OriginProfile, string(rawProfile.ID), patches, properties, updated); err != nil {
+ if err := writeProject(w, enc, ""+rawProfile.InnerXML+"", manifest.OriginProfile, string(rawProfile.ID), patches, properties, updated); err != nil {
return fmt.Errorf("updating profile: %w", err)
}
@@ -781,7 +690,7 @@ func writeProject(w io.Writer, enc *xml.Encoder, raw, prefix, id string, patches
if err := dec.DecodeElement(&rawPlugin, &tt); err != nil {
return err
}
- if err := writeProject(w, enc, ""+rawPlugin.InnerXML+"", OriginPlugin, rawPlugin.ProjectKey.Name(), patches, properties, updated); err != nil {
+ if err := writeProject(w, enc, ""+rawPlugin.InnerXML+"", manifest.OriginPlugin, rawPlugin.ProjectKey.Name(), patches, properties, updated); err != nil {
return fmt.Errorf("updating profile: %w", err)
}
@@ -795,7 +704,7 @@ func writeProject(w io.Writer, enc *xml.Encoder, raw, prefix, id string, patches
if err := dec.DecodeElement(&rawDepMgmt, &tt); err != nil {
return err
}
- o := mavenOrigin(prefix, id, OriginManagement)
+ o := mavenOrigin(prefix, id, manifest.OriginManagement)
updated[o] = true
dmPatches := patches[o]
if err := writeDependency(w, enc, ""+rawDepMgmt.InnerXML+"", dmPatches); err != nil {
diff --git a/internal/resolution/manifest/maven_test.go b/internal/resolution/manifest/maven_test.go
index 84f0c4fe0a..fd4cb32aa1 100644
--- a/internal/resolution/manifest/maven_test.go
+++ b/internal/resolution/manifest/maven_test.go
@@ -257,7 +257,7 @@ func TestMavenRead(t *testing.T) {
{Property: maven.Property{Name: "maven.compiler.source", Value: "1.7"}},
{Property: maven.Property{Name: "maven.compiler.target", Value: "1.7"}},
{Property: maven.Property{Name: "junit.version", Value: "4.12"}},
- {Property: maven.Property{Name: "zeppelin.daemon.package.base", Value: "\n\t ../bin\n "}},
+ {Property: maven.Property{Name: "zeppelin.daemon.package.base", Value: "../bin"}},
{Property: maven.Property{Name: "def.version", Value: "2.3.4"}, Origin: "profile@profile-one"},
},
OriginalRequirements: []DependencyWithOrigin{
@@ -868,65 +868,3 @@ func TestGeneratePropertyPatches(t *testing.T) {
}
}
}
-
-func TestParentPOMPath(t *testing.T) {
- t.Parallel()
- dir, err := os.Getwd()
- if err != nil {
- t.Fatalf("failed to get current directory: %v", err)
- }
- tests := []struct {
- currentPath, relativePath string
- want string
- }{
- // fixtures
- // |- maven
- // | |- my-app
- // | | |- pom.xml
- // | |- parent
- // | | |- pom.xml
- // |- pom.xml
- {
- // Parent path is specified correctly.
- currentPath: filepath.Join(dir, "fixtures", "maven", "my-app", "pom.xml"),
- relativePath: "../parent/pom.xml",
- want: filepath.Join(dir, "fixtures", "maven", "parent", "pom.xml"),
- },
- {
- // Wrong file name is specified in relative path.
- currentPath: filepath.Join(dir, "fixtures", "maven", "my-app", "pom.xml"),
- relativePath: "../parent/abc.xml",
- want: "",
- },
- {
- // Wrong directory is specified in relative path.
- currentPath: filepath.Join(dir, "fixtures", "maven", "my-app", "pom.xml"),
- relativePath: "../not-found/pom.xml",
- want: "",
- },
- {
- // Only directory is specified.
- currentPath: filepath.Join(dir, "fixtures", "maven", "my-app", "pom.xml"),
- relativePath: "../parent",
- want: filepath.Join(dir, "fixtures", "maven", "parent", "pom.xml"),
- },
- {
- // Parent relative path is default to '../pom.xml'.
- currentPath: filepath.Join(dir, "fixtures", "maven", "my-app", "pom.xml"),
- relativePath: "",
- want: filepath.Join(dir, "fixtures", "maven", "pom.xml"),
- },
- {
- // No pom.xml is found even in the default path.
- currentPath: filepath.Join(dir, "fixtures", "maven", "pom.xml"),
- relativePath: "",
- want: "",
- },
- }
- for _, test := range tests {
- got := MavenParentPOMPath(test.currentPath, test.relativePath)
- if got != test.want {
- t.Errorf("parentPOMPath(%s, %s): got %s, want %s", test.currentPath, test.relativePath, got, test.want)
- }
- }
-}