gnodet commented on code in PR #11904:
URL: https://github.com/apache/maven/pull/11904#discussion_r3973577240
##########
impl/maven-core/src/main/java/org/apache/maven/internal/transformation/impl/DefaultConsumerPomBuilder.java:
##########
@@ -800,6 +807,197 @@ private static void warnNotDowngraded(MavenProject
project) {
+ "attribute on the <project> element of your POM.");
}
+ /**
+ * Expands {@code id} attributes on {@code <dependency>} and {@code
<exclusion>}
+ * elements into their individual GAV fields, then clears the {@code id}
attribute.
+ * This mirrors the expansion performed by {@code DefaultModelNormalizer}
during
+ * model building and ensures the consumer POM does not contain
compact-form
+ * {@code id} attributes that downstream consumers (Maven 3, Gradle)
cannot parse.
+ *
+ * @param model the model to expand
+ * @return the model with all dependency/exclusion {@code id} attributes
expanded
+ */
+ static Model expandDependencyIds(Model model) {
+ Model.Builder mb = null;
+ List<Dependency> deps =
expandDependencyIdList(model.getDependencies());
+ if (deps != null) {
+ mb = Model.newBuilder(model, true);
+ mb.dependencies(deps);
+ }
+ DependencyManagement mgmt = model.getDependencyManagement();
+ if (mgmt != null) {
+ List<Dependency> mgmtDeps =
expandDependencyIdList(mgmt.getDependencies());
+ if (mgmtDeps != null) {
+ if (mb == null) {
+ mb = Model.newBuilder(model, true);
+ }
+ mb.dependencyManagement(DependencyManagement.newBuilder(mgmt,
true)
+ .dependencies(mgmtDeps)
+ .build());
+ }
+ }
+ List<Profile> profiles = model.getProfiles();
+ if (!profiles.isEmpty()) {
+ List<Profile> expandedProfiles = null;
+ for (int i = 0; i < profiles.size(); i++) {
+ Profile profile = profiles.get(i);
+ Profile.Builder pb = null;
+ List<Dependency> pdeps =
expandDependencyIdList(profile.getDependencies());
+ if (pdeps != null) {
+ pb = Profile.newBuilder(profile, true);
+ pb.dependencies(pdeps);
+ }
+ DependencyManagement pmgmt = profile.getDependencyManagement();
+ if (pmgmt != null) {
+ List<Dependency> pmgmtDeps =
expandDependencyIdList(pmgmt.getDependencies());
+ if (pmgmtDeps != null) {
+ if (pb == null) {
+ pb = Profile.newBuilder(profile, true);
+ }
+
pb.dependencyManagement(DependencyManagement.newBuilder(pmgmt, true)
+ .dependencies(pmgmtDeps)
+ .build());
+ }
+ }
+ if (pb != null) {
+ if (expandedProfiles == null) {
+ expandedProfiles = new ArrayList<>(profiles);
+ }
+ expandedProfiles.set(i, pb.build());
+ }
+ }
+ if (expandedProfiles != null) {
+ if (mb == null) {
+ mb = Model.newBuilder(model, true);
+ }
+ mb.profiles(expandedProfiles);
+ }
+ }
+ return mb != null ? mb.build() : model;
+ }
+
+ private static List<Dependency> expandDependencyIdList(List<Dependency>
dependencies) {
+ List<Dependency> result = null;
+ for (int i = 0; i < dependencies.size(); i++) {
+ Dependency dep = dependencies.get(i);
+ Dependency expanded = expandSingleDependencyId(dep);
+ if (expanded != dep) {
+ if (result == null) {
+ result = new ArrayList<>(dependencies);
+ }
+ result.set(i, expanded);
+ }
+ }
+ return result;
+ }
+
+ private static Dependency expandSingleDependencyId(Dependency d) {
+ String id = d.getId();
+ if (id == null || id.isEmpty()) {
+ // Still need to check exclusions
+ List<Exclusion> expanded =
expandExclusionIdList(d.getExclusions());
+ return expanded != null ? d.withExclusions(expanded) : d;
+ }
+
+ String remaining = id;
+ boolean optional = false;
+ if (remaining.endsWith("?")) {
+ optional = true;
+ remaining = remaining.substring(0, remaining.length() - 1);
+ }
+
+ String scope = null;
+ int atIndex = remaining.lastIndexOf('@');
+ if (atIndex >= 0) {
+ scope = remaining.substring(atIndex + 1);
+ remaining = remaining.substring(0, atIndex);
+ }
+
+ String[] parts = remaining.split(":", -1);
+ if (parts.length < 2 || parts.length > 5) {
+ return d;
+ }
+ Dependency.Builder builder = Dependency.newBuilder(d, true);
+ builder.id(null);
+ if (!parts[0].isEmpty() && isNullOrEmpty(d.getGroupId())) {
+ builder.groupId(parts[0]);
+ }
+ if (!parts[1].isEmpty() && isNullOrEmpty(d.getArtifactId())) {
+ builder.artifactId(parts[1]);
+ }
+ switch (parts.length) {
+ case 2:
+ break;
+ case 3:
+ if (!parts[2].isEmpty() && isNullOrEmpty(d.getVersion())) {
+ builder.version(parts[2]);
+ }
+ break;
+ case 4:
+ if (!parts[2].isEmpty() && isNullOrEmpty(d.getType())) {
Review Comment:
This uses `isNullOrEmpty(d.getType())` but the equivalent code in
`DefaultModelNormalizer` (line 264) uses `isNullOrEmptyOrDefault(d.getType())`
— which also treats `"jar"` as empty/default. The normalizer version is more
correct: if a dependency already has `type="jar"` set explicitly, the
normalizer will still set the type from the `id` attribute, but this consumer
POM builder code won't. Consider using `isNullOrEmptyOrDefault` here too for
consistency, or better yet, extract the shared parsing logic.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]