-
Notifications
You must be signed in to change notification settings - Fork 3.1k
[MNG-8099] Add explicit 'api' scope for dependencies and make 'compile' non-transitive for Maven 4 #12745
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
[MNG-8099] Add explicit 'api' scope for dependencies and make 'compile' non-transitive for Maven 4 #12745
Changes from all commits
bda6953
3a48a68
589b172
03557bc
587beb5
7d67618
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -257,7 +257,7 @@ private Model buildEffectiveModel(RepositorySystemSession session, MavenProject | |
| } | ||
| return dependency; | ||
| }); | ||
| // Only keep transitive scopes (null/empty => COMPILE) | ||
| // Only keep consumer-visible scopes (compile, api, runtime) | ||
| directDependencies.values().removeIf(DefaultConsumerPomBuilder::hasDependencyScope); | ||
| managedDependencies.keySet().removeAll(directDependencies.keySet()); | ||
|
|
||
|
|
@@ -275,7 +275,7 @@ private Model buildEffectiveModel(RepositorySystemSession session, MavenProject | |
| Function.identity(), | ||
| this::merge, | ||
| LinkedHashMap::new)); | ||
| // Only keep transitive scopes | ||
| // Only keep consumer-visible scopes (compile, api, runtime) | ||
| directDependencies.values().removeIf(DefaultConsumerPomBuilder::hasDependencyScope); | ||
| model = model.withDependencies(directDependencies.isEmpty() ? null : directDependencies.values()); | ||
| } | ||
|
|
@@ -291,7 +291,7 @@ private static boolean hasDependencyScope(Dependency dependency) { | |
| } else { | ||
| scope = DependencyScope.forId(scopeId); | ||
| } | ||
| return scope == null || !scope.isTransitive(); | ||
| return scope != DependencyScope.COMPILE && scope != DependencyScope.RUNTIME && scope != DependencyScope.API; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Non-blocking — stale comments: The |
||
| } | ||
|
|
||
| private Dependency merge(Dependency dep1, Dependency dep2) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -345,6 +345,12 @@ private int getPolicy(RepositorySystemSession session, Artifact a, ArtifactDescr | |
| private void populateResult(InternalSession session, ArtifactDescriptorResult result, Model model) { | ||
| ArtifactTypeRegistry stereotypes = session.getSession().getArtifactTypeRegistry(); | ||
|
|
||
| // Compute once whether compile-scoped dependencies should be remapped to api (transitive) | ||
| // for backward compatibility. Use the declared modelVersion rather than feature detection | ||
| // to respect the developer's explicit intent. | ||
| String declaredModelVersion = model.getModelVersion(); | ||
| boolean remapCompileToApi = declaredModelVersion == null || declaredModelVersion.startsWith("4.0."); | ||
|
|
||
| for (Repository repository : model.getRepositories()) { | ||
| result.addRepository(session.toRepository( | ||
| session.getService(RepositoryFactory.class).createRemote(repository))); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Non-blocking — test coverage gap: The
|
||
|
|
@@ -355,7 +361,7 @@ private void populateResult(InternalSession session, ArtifactDescriptorResult re | |
| logger.debug("Filtered dependency with uninterpolated expression: {}", dependency); | ||
| continue; | ||
| } | ||
| result.addDependency(convert(dependency, stereotypes)); | ||
| result.addDependency(convert(dependency, stereotypes, remapCompileToApi)); | ||
| } | ||
|
|
||
| DependencyManagement dependencyManagement = model.getDependencyManagement(); | ||
|
|
@@ -365,7 +371,7 @@ private void populateResult(InternalSession session, ArtifactDescriptorResult re | |
| logger.debug("Filtered managed dependency with uninterpolated expression: {}", dependency); | ||
| continue; | ||
| } | ||
| result.addManagedDependency(convert(dependency, stereotypes)); | ||
| result.addManagedDependency(convert(dependency, stereotypes, remapCompileToApi)); | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -391,7 +397,10 @@ private void populateResult(InternalSession session, ArtifactDescriptorResult re | |
| setArtifactProperties(result, model); | ||
| } | ||
|
|
||
| private Dependency convert(org.apache.maven.api.model.Dependency dependency, ArtifactTypeRegistry stereotypes) { | ||
| private Dependency convert( | ||
| org.apache.maven.api.model.Dependency dependency, | ||
| ArtifactTypeRegistry stereotypes, | ||
| boolean remapCompileToApi) { | ||
| ArtifactType stereotype = stereotypes.get(dependency.getType()); | ||
| if (stereotype == null) { | ||
| stereotype = new DefaultType(dependency.getType(), Language.NONE, dependency.getType(), null, false) | ||
|
|
@@ -420,11 +429,13 @@ private Dependency convert(org.apache.maven.api.model.Dependency dependency, Art | |
| exclusions.add(convert(exclusion)); | ||
| } | ||
|
|
||
| String scope = dependency.getScope() != null ? dependency.getScope() : ""; | ||
| if (remapCompileToApi && ("compile".equals(scope) || scope.isEmpty())) { | ||
| scope = "api"; | ||
| } | ||
|
|
||
| return new Dependency( | ||
| artifact, | ||
| dependency.getScope(), | ||
| dependency.getOptional() != null ? dependency.isOptional() : null, | ||
| exclusions); | ||
| artifact, scope, dependency.getOptional() != null ? dependency.isOptional() : null, exclusions); | ||
| } | ||
|
|
||
| private Exclusion convert(org.apache.maven.api.model.Exclusion exclusion) { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Critical regression: Changing
COMPILEfromtransitive=truetotransitive=falsehas cascading effects:DefaultConsumerPomBuilder.hasDependencyScope()uses!scope.isTransitive()to decide which dependencies to strip from consumer POMs. With this change, all compile-scoped dependencies (the most common case, since compile is the default scope) will be silently removed from consumer POMs.Maven4ScopeManagerConfigurationpassesDependencyScope.COMPILE.isTransitive()tocreateDependencyScope(). COMPILE now falls intononTransitiveDependencyScopesinbuildResolutionScopes(), causing the resolver to eliminate transitive dependencies of compile-scoped libraries.At minimum,
DefaultConsumerPomBuilder.hasDependencyScope()needs to be updated to not rely onisTransitive()for consumer POM inclusion, and the compile-to-non-transitive behavior should be gated on model version so 4.0.0 projects retain current behavior.