gnodet commented on code in PR #12744:
URL: https://github.com/apache/maven/pull/12744#discussion_r3841054801
##########
impl/maven-core/src/main/java/org/apache/maven/internal/transformation/impl/DefaultConsumerPomBuilder.java:
##########
@@ -451,6 +459,127 @@ private static void warnNotDowngraded(MavenProject
project) {
+ "attribute on the <project> element of your POM.");
}
+ /**
+ * Inlines packaging-activated profiles into the model.
+ * <p>
+ * When a profile is activated by packaging and the packaging matches the
project's packaging,
+ * the profile's content (dependencies, dependency management,
repositories) is merged into
+ * the main model and the profile is removed. This ensures consistent
behavior across all
+ * tools consuming the POM, since packaging activation is a 4.1.0+ feature
not available
+ * in Maven 3 or other tools like Gradle.
+ * <p>
+ * If the profile has other activation conditions besides packaging, only
the packaging
+ * part is stripped from the activation; the profile's content is
<b>not</b> inlined to
+ * preserve AND semantics (the content remains gated by the remaining
conditions).
+ * <p>
+ * Profiles with a non-matching packaging activation are dropped entirely,
since they
+ * can never activate for this artifact's fixed packaging and their
presence would block
+ * model version downgrade to 4.0.0.
+ * <p>
+ * Non-transitive scope dependencies (test, provided, system) from inlined
profiles are
+ * filtered out to prevent leakage into the consumer POM.
+ *
+ * @param model the model to process
+ * @param packaging the project's packaging type
+ * @return the model with packaging-activated profiles inlined
+ */
+ static Model inlinePackagingActivatedProfiles(Model model, String
packaging) {
+ List<Profile> remainingProfiles = new ArrayList<>();
+ List<Dependency> additionalDeps = new ArrayList<>();
+ List<Dependency> additionalManagedDeps = new ArrayList<>();
+ List<Repository> additionalRepos = new ArrayList<>();
+
+ for (Profile profile : model.getProfiles()) {
+ Activation activation = profile.getActivation();
+ if (activation != null && activation.getPackaging() != null) {
+ if (Objects.equals(activation.getPackaging(), packaging)) {
+ Activation strippedActivation =
stripPackagingActivation(activation);
+ if (strippedActivation != null) {
+ // Keep the profile but remove the packaging
activation part
+ // Do not inline its contents since it has other
activation conditions
+
remainingProfiles.add(profile.withActivation(strippedActivation));
+ } else {
+ // Packaging is the ONLY condition.
+ // Inline profile content into the model
+ additionalDeps.addAll(profile.getDependencies());
+ if (profile.getDependencyManagement() != null) {
+ additionalManagedDeps.addAll(
+
profile.getDependencyManagement().getDependencies());
+ }
+ additionalRepos.addAll(profile.getRepositories());
+ }
+ } else {
+ // Packaging does not match — drop the profile entirely
+ }
+ } else {
+ // No packaging activation — keep the profile as-is
+ remainingProfiles.add(profile);
+ }
+ }
+
+ // Merge additional dependencies into the model, deduplicating by key
+ if (!additionalDeps.isEmpty()) {
+
additionalDeps.removeIf(DefaultConsumerPomBuilder::hasDependencyScope);
+ Map<String, Dependency> mergedDeps = new LinkedHashMap<>();
+ for (Dependency dep : model.getDependencies()) {
+ mergedDeps.put(getDependencyKey(dep), dep);
+ }
+ for (Dependency dep : additionalDeps) {
+ mergedDeps.putIfAbsent(getDependencyKey(dep), dep);
+ }
+ model = model.withDependencies(mergedDeps.values());
Review Comment:
Minor: managed dependencies inlined from profiles are not filtered for
`import` scope. In `buildEffectiveModel` (line ~232), managed deps with
`scope=import` are explicitly filtered out. But
`inlinePackagingActivatedProfiles` adds profile managed deps via `putIfAbsent`
without this filter.
Since `transformNonPom` receives the effective model (where import-scoped
managed deps were already filtered by `buildEffectiveModel`), profiles still
retain their original declarations, and `putIfAbsent` could re-add
import-scoped managed deps that were previously filtered. This is an edge case
(requires BOM imports inside a packaging-activated profile) but represents a
gap in the filtering logic.
##########
impl/maven-core/src/test/java/org/apache/maven/internal/transformation/impl/ConsumerPomBuilderTest.java:
##########
@@ -135,6 +153,62 @@ void testTrivialConsumer() throws Exception {
assertNotNull(model.getDependencies());
}
+ @Test
+ void testPackagingActivatedProfiles() throws Exception {
+ setRootDirectory("packaging-profiles");
+ Path file =
Paths.get("src/test/resources/consumer/packaging-profiles/pom.xml");
+
+ MavenProject project = getEffectiveModel(file);
+
+ Model model =
DefaultConsumerPomBuilder.transformNonPom(getConsumerModel(file, false),
project);
+
+ assertNotNull(model);
+
+ assertEquals(1, model.getProfiles().size());
+ org.apache.maven.api.model.Profile mixedProfile =
model.getProfiles().get(0);
+ assertEquals("mixed-profile", mixedProfile.getId());
+ assertNotNull(mixedProfile.getActivation());
+ assertNull(mixedProfile.getActivation().getPackaging());
+ assertNotNull(mixedProfile.getActivation().getProperty());
+ assertEquals("foo",
mixedProfile.getActivation().getProperty().getName());
+
+ assertNotNull(model.getDependencies());
+ assertEquals(1, model.getDependencies().size());
+ assertEquals("slf4j-api",
model.getDependencies().get(0).getArtifactId());
+ }
+
+ @Test
+ void testParentPomPackagingActivatedProfilesArePreserved() throws
Exception {
+ setRootDirectory("packaging-parent-profiles");
Review Comment:
Missing test resource file: `testBomPackagingActivatedProfilesArePreserved`
references `src/test/resources/consumer/packaging-bom-profiles/pom.xml` but
this file is not included in the PR. Only `packaging-profiles/pom.xml` and
`packaging-parent-profiles/pom.xml` were added. This test will fail at runtime
with a file-not-found error.
A BOM-style POM (packaging=pom with dependencyManagement in profiles) needs
to be created at the referenced path.
--
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]