Skip to content

Commit

Permalink
Add support for snapshotted Maven artifacts
Browse files Browse the repository at this point in the history
Artifacts with snapshots follow a different naming scheme than
non-snapshoted ones.  For snapshotted artifacts, the version component
in the URL is the generic *-SNAPSHOT name, whereas the version component
in the file name is the specific version number.

Fixes bazel-contrib#901.
  • Loading branch information
jmmv authored and sfc-gh-gkolobkov committed Sep 5, 2024
1 parent 61e8eda commit e4d12d2
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 19 deletions.
9 changes: 7 additions & 2 deletions private/rules/v2_lock_file.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,13 @@ def _compute_lock_file_hash(lock_file_contents):
return hash(repr(to_hash))

def _to_m2_path(unpacked):
path = "{group}/{artifact}/{version}/{artifact}-{version}".format(
version = unpacked["version"]
dir_version = getattr(unpacked, "dirVersion", version)
path = "{group}/{artifact}/{dir_version}/{artifact}-{version}".format(
artifact = unpacked["artifactId"],
group = unpacked["groupId"].replace(".", "/"),
version = unpacked["version"],
version = version,
dir_version = dir_version,
)

classifier = unpacked.get("scope", "jar")
Expand Down Expand Up @@ -108,6 +111,8 @@ def _get_artifacts(lock_file_contents):
"artifactId": parts[1],
"version": data["version"],
}
if "dirVersion" in data:
root_unpacked["dirVersion"] = data["dirVersion"]
if len(parts) > 2:
root_unpacked["type"] = parts[2]
else:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,15 @@
/**
* Represents a Maven coordinate using Maven's standard schema of
* <groupId>:<artifactId>[:<extension>[:<classifier>][:<version>].
*
* <p>The optional <tt>dirVersion</tt> property is used for snapshotted artifacts. For those,
* directory version component in the repository URL is of the <tt>*-SNAPSHOT</tt> * form
* whereas the version in the artifact itself numeric.</p>
*/
public class Coordinates implements Comparable<Coordinates> {
private final String groupId;
private final String artifactId;
private final String dirVersion;
private final String version;
private final String classifier;
private final String extension;
Expand All @@ -41,6 +46,7 @@ public Coordinates(String coordinates) {

groupId = Objects.requireNonNull(parts[0]);
artifactId = Objects.requireNonNull(parts[1]);
dirVersion = null;

if (parts.length == 2) {
extension = "jar";
Expand All @@ -62,13 +68,14 @@ public Coordinates(String coordinates) {
}

public Coordinates(
String groupId, String artifactId, String extension, String classifier, String version) {
String groupId, String artifactId, String extension, String classifier, String version, String dirVersion) {
this.groupId = Objects.requireNonNull(groupId, "Group ID");
this.artifactId = Objects.requireNonNull(artifactId, "Artifact ID");
this.extension = extension == null || extension.isEmpty() ? "jar" : extension;
this.classifier =
classifier == null || classifier.isEmpty() || "jar".equals(classifier) ? "" : classifier;
this.version = version == null || version.isEmpty() ? "" : version;
this.dirVersion = dirVersion;
}

public String getGroupId() {
Expand All @@ -79,6 +86,10 @@ public String getArtifactId() {
return artifactId;
}

public String getDirVersion() {
return dirVersion;
}

public String getVersion() {
return version;
}
Expand All @@ -88,15 +99,17 @@ public String getClassifier() {
}

public Coordinates setClassifier(String classifier) {
return new Coordinates(getGroupId(), getArtifactId(), getExtension(), classifier, getVersion());
return new Coordinates(
getGroupId(), getArtifactId(), getExtension(), classifier, getVersion(), getDirVersion());
}

public Coordinates setExtension(String extension) {
return new Coordinates(getGroupId(), getArtifactId(), extension, getClassifier(), getVersion());
return new Coordinates(
getGroupId(), getArtifactId(), extension, getClassifier(), getVersion(), getDirVersion());
}

public Coordinates setVersion(String version) {
return new Coordinates(getGroupId(), getArtifactId(), getExtension(), getClassifier(), version);
return new Coordinates(getGroupId(), getArtifactId(), getExtension(), getClassifier(), version, getDirVersion());
}

public String getExtension() {
Expand Down Expand Up @@ -177,6 +190,7 @@ public boolean equals(Object o) {
Coordinates that = (Coordinates) o;
return getGroupId().equals(that.getGroupId())
&& getArtifactId().equals(that.getArtifactId())
&& Objects.equals(getDirVersion(), that.getDirVersion())
&& Objects.equals(getVersion(), that.getVersion())
&& Objects.equals(getClassifier(), that.getClassifier())
&& Objects.equals(getExtension(), that.getExtension());
Expand All @@ -185,7 +199,8 @@ && getArtifactId().equals(that.getArtifactId())
@Override
public int hashCode() {
return Objects.hash(
getGroupId(), getArtifactId(), getVersion(), getClassifier(), getExtension());
getGroupId(), getArtifactId(), getDirVersion(), getVersion(), getClassifier(),
getExtension());
}

private boolean isNullOrEmpty(String value) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -275,21 +275,66 @@ private Map<Coordinates, Coordinates> deriveCoordinateMappings(Map<String, Objec
// After the version, there should be nothing left but a file name
pathSubstring = pathSubstring.substring(version.length() + 1);

// Now we know the version, we can calculate the expected file name. For now, ignore
// the fact that there may be a classifier. We're going to derive that if necessary.
String expectedFileName = coord.getArtifactId() + "-" + version;
String remainder;
String dirVersion;
if (version.endsWith("-SNAPSHOT")) {
String baseVersion = version.substring(0, version.length() - "-SNAPSHOT".length());

index = pathSubstring.indexOf(expectedFileName);
if (index == -1) {
throw new IllegalArgumentException(
String.format(
"Expected file name (%s) not found in path (%s). Current coordinates are %s",
expectedFileName, file, coord));
String expectedFileName = coord.getArtifactId() + "-" + baseVersion + "YYYYMMDD-HHMMSS.N+";

index = pathSubstring.indexOf(baseVersion);
if (index == -1) {
throw new IllegalArgumentException(
String.format(
"Expected artifact (%s) not found in path (%s). Current coordinates are %s",
expectedFileName, file, coord));
}
index = index + baseVersion.length();
int snapshotVersionStart = index;

// Skip over the YYYYMMDD part.
if (pathSubstring.charAt(index + 9) != '.') {
throw new IllegalArgumentException(
String.format(
"Expected artifact (%s) not found in path (%s). Current coordinates are %s",
expectedFileName, file, coord));
}
index = index + 9;

// Skip over the HHMMSS part.
if (pathSubstring.charAt(index + 7) != '-') {
throw new IllegalArgumentException(
String.format(
"Expected artifact (%s) not found in path (%s). Current coordinates are %s",
expectedFileName, file, coord));
}
index = index + 7;

// Skip over the variable-length build number.
index = pathSubstring.indexOf(".", index + 1);

remainder = pathSubstring.substring(index);
dirVersion = version;
version = baseVersion + pathSubstring.substring(snapshotVersionStart, index);
} else {
// Now we know the version, we can calculate the expected file name. For now, ignore
// the fact that there may be a classifier. We're going to derive that if necessary.
String expectedFileName = coord.getArtifactId() + "-" + version;

index = pathSubstring.indexOf(expectedFileName);
if (index == -1) {
throw new IllegalArgumentException(
String.format(
"Expected file name (%s) not found in path (%s). Current coordinates are %s",
expectedFileName, file, coord));
}

remainder = pathSubstring.substring(expectedFileName.length());
dirVersion = null;
}

String classifier = "";
String extension = "";
String remainder = pathSubstring.substring(expectedFileName.length());

if (remainder.isEmpty()) {
throw new IllegalArgumentException(
Expand Down Expand Up @@ -322,7 +367,7 @@ private Map<Coordinates, Coordinates> deriveCoordinateMappings(Map<String, Objec
toReturn.put(
coord,
new Coordinates(
coord.getGroupId(), coord.getArtifactId(), extension, classifier, version));
coord.getGroupId(), coord.getArtifactId(), extension, classifier, version, dirVersion));
}

return toReturn;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ public Map<String, Object> render(
Map<String, Object> artifactValue =
artifacts.computeIfAbsent(shortKey, k -> new TreeMap<>());
artifactValue.put("version", coords.getVersion());
String dirVersion = coords.getDirVersion();
if (dirVersion != null) {
artifactValue.put("dirVersion", coords.getDirVersion());
}

String classifier;
if (coords.getClassifier() == null || coords.getClassifier().isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ public ResolutionRequest addBom(Coordinates coordinates, String... exclusions) {
coordinates.getArtifactId(),
"pom",
"",
coordinates.getVersion());
coordinates.getVersion(),
coordinates.getDirVersion());
Artifact artifact =
new Artifact(bom, Stream.of(exclusions).map(Coordinates::new).collect(Collectors.toSet()));

Expand Down
Binary file modified private/tools/prebuilt/lock_file_converter_deploy.jar
Binary file not shown.

0 comments on commit e4d12d2

Please sign in to comment.