Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -344,23 +344,37 @@ public final class Constants {
public static final String MAVEN_RELOCATIONS_ENTRIES = "maven.relocations.entries";

/**
* User property for version filter expression used in session, applied to resolving ranges: a semicolon separated
* list of filters to apply. By default, no version filter is applied (like in Maven 3).
* Builds <code>org.eclipse.aether.collection.VersionFilter</code> instances out of input expression string.
* <br/>
* Expression is a semicolon separated list of filters to apply. By default, no version filter is applied (like in Maven 3).
* <br/>
* Supported filters:
* <ul>
* <li>"h" or "h(num)" - highest version or top list of highest ones filter</li>
* <li>"l" or "l(num)" - lowest version or bottom list of lowest ones filter</li>
* <li>"s" - contextual snapshot filter</li>
* <li>"ns" - unconditional snapshot filter (no snapshots selected from ranges)</li>
* <li>"e(G:A:V)" - predicate filter (leaves out G:A:V from range, if hit, V can be range)</li>
* <li><code>"s"</code> - contextual snapshot filter (project version decides are snapshots allowed or not)</li>
* <li><code>"nosnapshot"</code> - unconditional snapshot filter (no snapshot versions selected from ranges)</li>
* <li><code>"norelease"</code> - unconditional release filter (no release versions selected from ranges)</li>
* <li><code>"nopreview"</code> - unconditional preview filter (no preview versions selected from ranges)</li>
* <li><code>"noprerelease"</code> - unconditional pre-release filter (no preview and rc/cr versions selected from ranges)</li>
* <li><code>"noqualifier"</code> - unconditional any-qualifier filter (no version with any qualifier selected from ranges)</li>
* <li><code>"h"</code> (shorthand of <code>h(1)</code>) or <code>"h(num)"</code> - highest N version (based on version ordering)</li>
* <li><code>"l"</code> (shorthand of <code>l(1)</code>) or <code>"l(num)"</code> - lowest N version (based on version ordering)</li>
* <li><code>"e(V)"</code> - exclusion filter (excludes versions matching V version constraint)</li>
* <li><code>"i(V)"</code> - inclusion filter (includes versions matching V version constraint)</li>
* </ul>
* Every filter expression may have "scope" applied, in form of <code>@G[:A]</code>. Presence of "scope" narrows the
* application of filter to given G or G:A.
* <br/>
* In case of multiple "similar" rule scopes, user should enlist rules from "most specific" to "least specific".
* <br/>
* Example filter expression: <code>"h(5);s;e(1)@org.foo:bar"</code> will cause:
* <ul>
* <li>ranges are filtered for "top 5" (instead of full range)</li>
* <li>snapshots are banned if root project is not a snapshot</li>
* <li>if range for <code>org.foo:bar</code> is being processed, version 1 is omitted</li>
* </ul>
* Example filter expression: <code>"h(5);s;e(org.foo:bar:1)</code> will cause: ranges are filtered for "top 5" (instead
* full range), snapshots are banned if root project is not a snapshot, and if range for <code>org.foo:bar</code> is
* being processed, version 1 is omitted. Value in this property builds
* <code>org.eclipse.aether.collection.VersionFilter</code> instance.
* Values in this property builds <code>org.eclipse.aether.collection.VersionFilter</code> instance.
*
* @since 4.0.0
* @since 3.10.0
*/
@Config
public static final String MAVEN_VERSION_FILTER = "maven.session.versionFilter";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
import org.apache.maven.artifact.repository.metadata.RepositoryMetadata;
import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.logging.console.ConsoleLogger;
import org.eclipse.aether.internal.impl.DefaultTrackingFileManager;
import org.eclipse.aether.internal.impl.LegacyTrackingFileManager;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

Expand Down Expand Up @@ -59,7 +59,7 @@ public void setUp() throws Exception {
super.setUp();

updateCheckManager = new DefaultUpdateCheckManager(
new ConsoleLogger(Logger.LEVEL_DEBUG, "test"), new DefaultTrackingFileManager());
new ConsoleLogger(Logger.LEVEL_DEBUG, "test"), new LegacyTrackingFileManager());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ private MavenExecutionResult doExecute(MavenExecutionRequest request) {
session.setSession(defaultSessionFactory.newSession(session));

sessionScope.seed(MavenSession.class, session);
sessionScope.seed(RepositorySystemSession.class, closeableSession); // fixed in Maven 3.10.x
sessionScope.seed(Session.class, session.getSession());
sessionScope.seed(InternalMavenSession.class, InternalMavenSession.from(session.getSession()));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import org.apache.maven.api.Constants;
Expand All @@ -54,17 +53,9 @@
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.RepositorySystemSession.SessionBuilder;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.collection.VersionFilter;
import org.eclipse.aether.collection.VersionFilterBuilder;
import org.eclipse.aether.repository.RepositoryPolicy;
import org.eclipse.aether.resolution.ResolutionErrorPolicy;
import org.eclipse.aether.util.graph.version.ChainedVersionFilter;
import org.eclipse.aether.util.graph.version.ContextualSnapshotVersionFilter;
import org.eclipse.aether.util.graph.version.HighestVersionFilter;
import org.eclipse.aether.util.graph.version.LowestVersionFilter;
import org.eclipse.aether.util.graph.version.PredicateVersionFilter;
import org.eclipse.aether.util.graph.version.SnapshotVersionFilter;
import org.eclipse.aether.util.listener.ChainedRepositoryListener;
import org.eclipse.aether.util.repository.AuthenticationBuilder;
import org.eclipse.aether.util.repository.ChainedLocalRepositoryManager;
Expand All @@ -74,8 +65,7 @@
import org.eclipse.aether.util.repository.SimpleArtifactDescriptorPolicy;
import org.eclipse.aether.util.repository.SimpleResolutionErrorPolicy;
import org.eclipse.aether.version.InvalidVersionSpecificationException;
import org.eclipse.aether.version.Version;
import org.eclipse.aether.version.VersionRange;
import org.eclipse.aether.version.VersionConstraint;
import org.eclipse.aether.version.VersionScheme;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -131,6 +121,8 @@ public class DefaultRepositorySystemSessionFactory implements RepositorySystemSe

private final Map<String, RepositorySystemSessionExtender> sessionExtenders;

private final VersionFilterBuilder versionFilterBuilder;

@SuppressWarnings("checkstyle:ParameterNumber")
@Inject
DefaultRepositorySystemSessionFactory(
Expand All @@ -139,13 +131,15 @@ public class DefaultRepositorySystemSessionFactory implements RepositorySystemSe
RuntimeInformation runtimeInformation,
TypeRegistry typeRegistry,
VersionScheme versionScheme,
Map<String, RepositorySystemSessionExtender> sessionExtenders) {
Map<String, RepositorySystemSessionExtender> sessionExtenders,
VersionFilterBuilder versionFilterBuilder) {
this.repoSystem = repoSystem;
this.eventSpyDispatcher = eventSpyDispatcher;
this.runtimeInformation = runtimeInformation;
this.typeRegistry = typeRegistry;
this.versionScheme = versionScheme;
this.sessionExtenders = sessionExtenders;
this.versionFilterBuilder = versionFilterBuilder;
}

@Deprecated
Expand Down Expand Up @@ -194,10 +188,9 @@ public SessionBuilder newRepositorySessionBuilder(MavenExecutionRequest request)
sessionBuilder.setArtifactDescriptorPolicy(new SimpleArtifactDescriptorPolicy(
request.isIgnoreMissingArtifactDescriptor(), request.isIgnoreInvalidArtifactDescriptor()));

VersionFilter versionFilter = buildVersionFilter(mergedProps.get(Constants.MAVEN_VERSION_FILTER));
if (versionFilter != null) {
sessionBuilder.setVersionFilter(versionFilter);
}
versionFilterBuilder
.buildVersionFilter(mergedProps.get(Constants.MAVEN_VERSION_FILTER), this::parseVersionConstraint)
.ifPresent(sessionBuilder::setVersionFilter);

DefaultMirrorSelector mirrorSelector = new DefaultMirrorSelector();
for (Mirror mirror : request.getMirrors()) {
Expand Down Expand Up @@ -405,6 +398,14 @@ public SessionBuilder newRepositorySessionBuilder(MavenExecutionRequest request)
return sessionBuilder;
}

private VersionConstraint parseVersionConstraint(String spec) {
try {
return versionScheme.parseVersionConstraint(spec);
} catch (InvalidVersionSpecificationException e) {
throw new IllegalArgumentException(e);
}
}

private Path resolve(String string) {
if (string.startsWith("~/") || string.startsWith("~\\")) {
// resolve based on $HOME
Expand All @@ -418,74 +419,6 @@ private Path resolve(String string) {
}
}

private VersionFilter buildVersionFilter(String filterExpression) {
ArrayList<VersionFilter> filters = new ArrayList<>();
if (filterExpression != null) {
List<String> expressions = Arrays.stream(filterExpression.split(";"))
.filter(s -> s != null && !s.trim().isEmpty())
.toList();
for (String expression : expressions) {
if ("h".equals(expression)) {
filters.add(new HighestVersionFilter());
} else if (expression.startsWith("h(") && expression.endsWith(")")) {
int num = Integer.parseInt(expression.substring(2, expression.length() - 1));
filters.add(new HighestVersionFilter(num));
} else if ("l".equals(expression)) {
filters.add(new LowestVersionFilter());
} else if (expression.startsWith("l(") && expression.endsWith(")")) {
int num = Integer.parseInt(expression.substring(2, expression.length() - 1));
filters.add(new LowestVersionFilter(num));
} else if ("s".equals(expression)) {
filters.add(new ContextualSnapshotVersionFilter());
} else if ("ns".equals(expression)) {
filters.add(new SnapshotVersionFilter());
} else if (expression.startsWith("e(") && expression.endsWith(")")) {
Artifact artifact = new DefaultArtifact(expression.substring(2, expression.length() - 1));
VersionRange versionRange =
artifact.getVersion().contains(",") ? parseVersionRange(artifact.getVersion()) : null;
Predicate<Artifact> predicate = a -> {
if (artifact.getGroupId().equals(a.getGroupId())
&& artifact.getArtifactId().equals(a.getArtifactId())) {
if (versionRange != null) {
Version v = parseVersion(a.getVersion());
return !versionRange.containsVersion(v);
} else {
return !artifact.getVersion().equals(a.getVersion());
}
}
return true;
};
filters.add(new PredicateVersionFilter(predicate));
} else {
throw new IllegalArgumentException("Unsupported filter expression: " + expression);
}
}
}
if (filters.isEmpty()) {
return null;
} else if (filters.size() == 1) {
return filters.get(0);
} else {
return ChainedVersionFilter.newInstance(filters);
}
}

private Version parseVersion(String spec) {
try {
return versionScheme.parseVersion(spec);
} catch (InvalidVersionSpecificationException e) {
throw new RuntimeException(e);
}
}

private VersionRange parseVersionRange(String spec) {
try {
return versionScheme.parseVersionRange(spec);
} catch (InvalidVersionSpecificationException e) {
throw new RuntimeException(e);
}
}

@SuppressWarnings({"unchecked", "rawtypes"})
private Map<String, String> createMergedProperties(MavenExecutionRequest request) {
// this throwaway map is really ONLY to get config from (profiles + env + system + user)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.collection.CollectRequest;
import org.eclipse.aether.collection.DependencyCollectionException;
import org.eclipse.aether.collection.VersionFilterBuilder;
import org.eclipse.aether.graph.DependencyFilter;
import org.eclipse.aether.graph.DependencyNode;
import org.eclipse.aether.repository.RemoteRepository;
Expand Down Expand Up @@ -237,6 +238,7 @@ private DependencyResult resolveInternal(

try {
DefaultRepositorySystemSession pluginSession = new DefaultRepositorySystemSession(session);
pluginSession.setConfigProperty(VersionFilterBuilder.VERSION_FILTER_SUPPRESSED, Boolean.TRUE.toString());
pluginSession.setDependencySelector(session.getDependencySelector());
pluginSession.setDependencyGraphTransformer(session.getDependencyGraphTransformer());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import org.apache.maven.api.Session;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.internal.impl.InternalMavenSession;
import org.eclipse.aether.RepositorySystemSession;

/**
* SessionScopeModule
Expand All @@ -52,6 +53,9 @@ protected void configure() {
bind(MavenSession.class)
.toProvider(SessionScope.seededKeyProvider(MavenSession.class))
.in(scope);
bind(RepositorySystemSession.class)
.toProvider(SessionScope.seededKeyProvider(RepositorySystemSession.class))
.in(scope);
bind(Session.class)
.toProvider(SessionScope.seededKeyProvider(Session.class))
.in(scope);
Expand Down
Loading
Loading