Skip to content

Commit

Permalink
Fixed missing version on multiple dependency management sections in m… (
Browse files Browse the repository at this point in the history
#4888)

* Fixed missing version on multiple dependency management sections in multi-module projects and fixed ignored classifiers when choosing snapshot timestamp

* Formatted code, add unit test

* Added issue annotation to test

* Formatted

* Minor polish

* Further polish

* Generalize comment on continue

* Test for snapshot downloading issue

* Minor polish

---------

Co-authored-by: Tobias Hübner <[email protected]>
Co-authored-by: Tim te Beek <[email protected]>
  • Loading branch information
3 people authored Jan 16, 2025
1 parent 1fd511c commit 3d9653d
Show file tree
Hide file tree
Showing 5 changed files with 378 additions and 90 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ private List<Pom> getAncestryWithinProject(Pom projectPom, Map<Path, Pom> projec
.normalize();
Pom parentPom = projectPoms.get(parentPath);
return parentPom != null && parentPom.getGav().getGroupId().equals(parent.getGav().getGroupId()) &&
parentPom.getGav().getArtifactId().equals(parent.getGav().getArtifactId()) ? parentPom : null;
parentPom.getGav().getArtifactId().equals(parent.getGav().getArtifactId()) ? parentPom : null;
}

public MavenMetadata downloadMetadata(GroupArtifact groupArtifact, @Nullable ResolvedPom containingPom, List<MavenRepository> repositories) throws MavenDownloadingException {
Expand Down Expand Up @@ -259,9 +259,9 @@ public MavenMetadata downloadMetadata(GroupArtifactVersion gav, @Nullable Resolv
try {
String scheme = URI.create(repo.getUri()).getScheme();
String baseUri = repo.getUri() + (repo.getUri().endsWith("/") ? "" : "/") +
requireNonNull(gav.getGroupId()).replace('.', '/') + '/' +
gav.getArtifactId() + '/' +
(gav.getVersion() == null ? "" : gav.getVersion() + '/');
requireNonNull(gav.getGroupId()).replace('.', '/') + '/' +
gav.getArtifactId() + '/' +
(gav.getVersion() == null ? "" : gav.getVersion() + '/');

if ("file".equals(scheme)) {
// A maven repository can be expressed as a URI with a file scheme
Expand Down Expand Up @@ -356,8 +356,8 @@ public MavenMetadata downloadMetadata(GroupArtifactVersion gav, @Nullable Resolv

String scheme = URI.create(repo.getUri()).getScheme();
String uri = repo.getUri() + (repo.getUri().endsWith("/") ? "" : "/") +
requireNonNull(gav.getGroupId()).replace('.', '/') + '/' +
gav.getArtifactId() + '/';
requireNonNull(gav.getGroupId()).replace('.', '/') + '/' +
gav.getArtifactId() + '/';

try {
MavenMetadata.Versioning versioning;
Expand Down Expand Up @@ -496,7 +496,7 @@ public Pom download(GroupArtifactVersion gav,
// The requested gav might itself have an unresolved placeholder in the version, so also check raw values
for (Pom projectPom : projectPoms.values()) {
if (!projectPom.getGroupId().equals(gav.getGroupId()) ||
!projectPom.getArtifactId().equals(gav.getArtifactId())) {
!projectPom.getArtifactId().equals(gav.getArtifactId())) {
continue;
}

Expand All @@ -512,7 +512,7 @@ public Pom download(GroupArtifactVersion gav,
}

if (containingPom != null && containingPom.getRequested().getSourcePath() != null &&
!StringUtils.isBlank(relativePath) && !relativePath.contains(":")) {
!StringUtils.isBlank(relativePath) && !relativePath.contains(":")) {
Path folderContainingPom = containingPom.getRequested().getSourcePath().getParent();
if (folderContainingPom != null) {
Pom maybeLocalPom = projectPoms.get(folderContainingPom.resolve(Paths.get(relativePath, "pom.xml"))
Expand All @@ -521,9 +521,9 @@ public Pom download(GroupArtifactVersion gav,
// So double check that the GAV coordinates match so that we don't get a relative path from a remote
// pom like ".." or "../.." which coincidentally _happens_ to have led to an unrelated pom on the local filesystem
if (maybeLocalPom != null &&
gav.getGroupId().equals(maybeLocalPom.getGroupId()) &&
gav.getArtifactId().equals(maybeLocalPom.getArtifactId()) &&
gav.getVersion().equals(maybeLocalPom.getVersion())) {
gav.getGroupId().equals(maybeLocalPom.getGroupId()) &&
gav.getArtifactId().equals(maybeLocalPom.getArtifactId()) &&
gav.getVersion().equals(maybeLocalPom.getVersion())) {
return maybeLocalPom;
}
}
Expand Down Expand Up @@ -552,10 +552,10 @@ public Pom download(GroupArtifactVersion gav,

if (result == null) {
URI uri = URI.create(repo.getUri() + (repo.getUri().endsWith("/") ? "" : "/") +
requireNonNull(gav.getGroupId()).replace('.', '/') + '/' +
gav.getArtifactId() + '/' +
gav.getVersion() + '/' +
gav.getArtifactId() + '-' + versionMaybeDatedSnapshot + ".pom");
requireNonNull(gav.getGroupId()).replace('.', '/') + '/' +
gav.getArtifactId() + '/' +
gav.getVersion() + '/' +
gav.getArtifactId() + '-' + versionMaybeDatedSnapshot + ".pom");
uris.add(uri.toString());
if ("file".equals(uri.getScheme())) {
Path inputPath = Paths.get(gav.getGroupId(), gav.getArtifactId(), gav.getVersion());
Expand Down Expand Up @@ -688,9 +688,9 @@ private GroupArtifactVersion handleSnapshotTimestampVersion(GroupArtifactVersion
if (gav.getVersion() != null && gav.getVersion().endsWith("-SNAPSHOT")) {
for (ResolvedGroupArtifactVersion pinnedSnapshotVersion : new MavenExecutionContextView(ctx).getPinnedSnapshotVersions()) {
if (pinnedSnapshotVersion.getDatedSnapshotVersion() != null &&
pinnedSnapshotVersion.getGroupId().equals(gav.getGroupId()) &&
pinnedSnapshotVersion.getArtifactId().equals(gav.getArtifactId()) &&
pinnedSnapshotVersion.getVersion().equals(gav.getVersion())) {
pinnedSnapshotVersion.getGroupId().equals(gav.getGroupId()) &&
pinnedSnapshotVersion.getArtifactId().equals(gav.getArtifactId()) &&
pinnedSnapshotVersion.getVersion().equals(gav.getVersion())) {
return pinnedSnapshotVersion.getDatedSnapshotVersion();
}
}
Expand All @@ -702,6 +702,23 @@ private GroupArtifactVersion handleSnapshotTimestampVersion(GroupArtifactVersion
//This can happen if the artifact only exists in the local maven cache. In this case, just return the original
return gav.getVersion();
}

// Find the newest <snapshotVersion> with a matching classifier - the latest snapshot may not have artifacts for all classifiers.
List<MavenMetadata.SnapshotVersion> snapshotVersions = mavenMetadata.getVersioning().getSnapshotVersions();
if (snapshotVersions != null) {
// Try to get requested classifier (this is unfortunately not present in 'gav' structure)
String classifier = getClassifierFromContainingPom(gav, containingPom);
MavenMetadata.SnapshotVersion snapshotVersion = snapshotVersions.stream()
.sorted(Comparator.comparing(MavenMetadata.SnapshotVersion::getUpdated).reversed())
.filter(s -> Objects.equals(s.getClassifier(), classifier))
.findFirst()
.orElse(null);
if (snapshotVersion != null) {
return snapshotVersion.getValue();
}
}

// Replace SNAPSHOT suffix with timestamp and build number
MavenMetadata.Snapshot snapshot = mavenMetadata.getVersioning().getSnapshot();
if (snapshot != null && snapshot.getTimestamp() != null) {
return gav.getVersion().replaceFirst("SNAPSHOT$", snapshot.getTimestamp() + "-" + snapshot.getBuildNumber());
Expand Down Expand Up @@ -1054,4 +1071,27 @@ private static boolean hasPomFile(Path dir, Path versionPath, GroupArtifactVersi
String artifactPomFile = gav.getArtifactId() + "-" + versionPath.getFileName() + ".pom";
return Files.exists(dir.resolve(versionPath.resolve(artifactPomFile)));
}

/**
* Retrieves the classifier of a dependency from a provided resolved POM, if it exists.
*
* @param gav The group, artifact, and version information of the dependency to locate.
* @param containingPom The resolved POM that potentially contains the dependency information.
* If null, the method will return null.
* @return The classifier of the dependency within the provided POM, or null if no matching
* dependency or classifier is found.
*/
private static @Nullable String getClassifierFromContainingPom(GroupArtifactVersion gav, @Nullable ResolvedPom containingPom) {
if (containingPom != null) {
for (Dependency dep : containingPom.getRequestedDependencies()) {
if (Objects.equals(dep.getGroupId(), gav.getGroupId())) {
if (Objects.equals(dep.getArtifactId(), gav.getArtifactId())) {
return dep.getClassifier();
}
}
}
}
return null;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -101,5 +101,7 @@ public static class SnapshotVersion {
String extension;
String value;
String updated;
@Nullable
String classifier;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -320,11 +320,13 @@ public String getPackaging() {

public @Nullable String getManagedVersion(@Nullable String groupId, String artifactId, @Nullable String type, @Nullable String classifier) {
for (ResolvedManagedDependency dm : dependencyManagement) {
if (dm.getVersion() == null) {
continue; // Unclear why this happens; just ignore those entries, because a valid version is requested
}
if (dm.matches(groupId, artifactId, type, classifier)) {
return getValue(dm.getVersion());
}
}

return null;
}

Expand Down
Loading

0 comments on commit 3d9653d

Please sign in to comment.