23 Commits

Author SHA1 Message Date
08498d4224 v1.3.4 pom 2023-08-20 16:56:20 -04:00
1c7997d85c Merge branch 'develop' into stable 2023-08-20 16:56:04 -04:00
9116d4bfd9 less warnings for non-empty directories during purge 2023-08-20 16:55:54 -04:00
9874ed9543 v1.3.3 pom 2023-08-20 15:03:10 -04:00
eeb7a84698 Merge branch 'develop' into stable 2023-08-20 15:02:58 -04:00
ca8913e558 don't delete pom metadata 2023-08-20 15:02:50 -04:00
4c1c4d412d v1.3.2 pom 2023-08-20 13:34:37 -04:00
fc5e0c6bd1 Merge branch 'develop' into stable 2023-08-20 13:32:59 -04:00
2a1523012b prevent sub-group matching for purge 2023-08-20 13:32:46 -04:00
d41d73fa1c v1.3.1 pom 2023-08-20 12:59:23 -04:00
a9aa47d412 Merge branch 'develop' into stable 2023-08-20 12:58:55 -04:00
47fd07247d fix version range impl 2023-08-20 12:58:46 -04:00
cfb13f3170 v1.3.0 pom 2023-08-20 12:04:15 -04:00
75f8175a1c Merge branch 'develop' into stable 2023-08-20 12:03:52 -04:00
f2c93eec50 added version range config support 2023-08-20 12:03:15 -04:00
58eb0ec013 v1.2.4 pom 2023-08-20 11:35:52 -04:00
dec181aa71 Merge branch 'develop' into stable 2023-08-20 11:35:29 -04:00
51f5d6d0a3 fixed missing group/artifact paths on purge 2023-08-20 11:35:12 -04:00
24d69c3715 forcing extension to "xml" 2023-08-20 11:26:24 -04:00
fe10e53fb4 added goal prefix config: "ban" 2023-08-20 11:26:07 -04:00
b6c7323203 v1.2.3 pom 2023-08-16 12:38:18 -04:00
9644bbe154 Merge branch 'develop' into stable 2023-08-16 12:37:38 -04:00
9a0b7207c0 fixed import/url; added default artifact ext: xml 2023-08-16 12:36:50 -04:00
6 changed files with 140 additions and 46 deletions

View File

@@ -7,7 +7,7 @@
<groupId>com.inteligr8</groupId> <groupId>com.inteligr8</groupId>
<artifactId>ban-maven-plugin</artifactId> <artifactId>ban-maven-plugin</artifactId>
<version>1.2.2</version> <version>1.3.4</version>
<packaging>maven-plugin</packaging> <packaging>maven-plugin</packaging>
<name>Ban Dependencies Maven Plugin</name> <name>Ban Dependencies Maven Plugin</name>
@@ -106,6 +106,9 @@
<goals> <goals>
<goal>descriptor</goal> <goal>descriptor</goal>
</goals> </goals>
<configuration>
<goalPrefix>ban</goalPrefix>
</configuration>
</execution> </execution>
<execution> <execution>
<id>help-descriptor</id> <id>help-descriptor</id>

View File

@@ -30,9 +30,14 @@ import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.eclipse.aether.artifact.Artifact; import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.artifact.DefaultArtifact; import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.impl.ArtifactResolver; import org.eclipse.aether.impl.ArtifactResolver;
import org.eclipse.aether.impl.VersionRangeResolver;
import org.eclipse.aether.resolution.ArtifactRequest; import org.eclipse.aether.resolution.ArtifactRequest;
import org.eclipse.aether.resolution.ArtifactResolutionException; import org.eclipse.aether.resolution.ArtifactResolutionException;
import org.eclipse.aether.resolution.ArtifactResult; import org.eclipse.aether.resolution.ArtifactResult;
import org.eclipse.aether.resolution.VersionRangeRequest;
import org.eclipse.aether.resolution.VersionRangeResolutionException;
import org.eclipse.aether.resolution.VersionRangeResult;
import org.eclipse.aether.version.Version;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -48,11 +53,13 @@ public abstract class AbstractBanConfiguration implements BanConfiguration {
protected final List<ArtifactFilter> excludeArtifacts = new LinkedList<>(); protected final List<ArtifactFilter> excludeArtifacts = new LinkedList<>();
private final ArtifactResolver artifactResolver; private final ArtifactResolver artifactResolver;
private final VersionRangeResolver versionRangeResolver;
private final MavenSession session; private final MavenSession session;
public AbstractBanConfiguration(MavenSession session, ArtifactResolver artifactResolver) { public AbstractBanConfiguration(MavenSession session, ArtifactResolver artifactResolver, VersionRangeResolver versionRangeResolver) {
this.session = session; this.session = session;
this.artifactResolver = artifactResolver; this.artifactResolver = artifactResolver;
this.versionRangeResolver = versionRangeResolver;
} }
public void init(Xpp3Dom rootDom) throws IOException, MojoFailureException { public void init(Xpp3Dom rootDom) throws IOException, MojoFailureException {
@@ -69,18 +76,33 @@ public abstract class AbstractBanConfiguration implements BanConfiguration {
for (Xpp3Dom child : importDom.getChildren()) { for (Xpp3Dom child : importDom.getChildren()) {
BanConfigurationDownloader downloader = null; BanConfigurationDownloader downloader = null;
if (child.getName().equals("url")) { if (child.getName().equals("url")) {
String url = StringUtils.trimToNull(importDom.getValue()); String url = StringUtils.trimToNull(child.getValue());
downloader = new BanConfigurationDownloader(this.session, this.artifactResolver, url); downloader = new BanConfigurationDownloader(this.session, this.artifactResolver, this.versionRangeResolver, url);
} else if (child.getName().equals("artifact")) { } else if (child.getName().equals("artifact")) {
Artifact artifact = new DefaultArtifact(child.getValue()); Artifact artifact = new DefaultArtifact(child.getValue());
ArtifactRequest request = new ArtifactRequest(artifact, this.session.getCurrentProject().getRemoteProjectRepositories(), null); if (!"xml".equals(artifact.getExtension()))
artifact = new DefaultArtifact(artifact.getGroupId(), artifact.getArtifactId(), artifact.getClassifier(), "xml", artifact.getVersion());
VersionRangeRequest vrrequest = new VersionRangeRequest(artifact, this.session.getCurrentProject().getRemoteProjectRepositories(), null);
try { try {
ArtifactResult result = this.artifactResolver.resolveArtifact(this.session.getRepositorySession(), request); VersionRangeResult vrresult = this.versionRangeResolver.resolveVersionRange(this.session.getRepositorySession(), vrrequest);
File file = result.getArtifact().getFile(); if (vrresult.getVersions().isEmpty()) {
downloader = new BanConfigurationDownloader(this.session, this.artifactResolver, file); this.logger.error("The artifact version range could not be resolved; skipping: {}", child.getValue());
} catch (ArtifactResolutionException are) { } else {
this.logger.warn("The artifact could not be resolved; skipping: {}", child.getValue()); Version version = vrresult.getHighestVersion();
artifact = artifact.setVersion(version.toString());
ArtifactRequest arequest = new ArtifactRequest(artifact, this.session.getCurrentProject().getRemoteProjectRepositories(), null);
try {
ArtifactResult aresult = this.artifactResolver.resolveArtifact(this.session.getRepositorySession(), arequest);
File file = aresult.getArtifact().getFile();
downloader = new BanConfigurationDownloader(this.session, this.artifactResolver, this.versionRangeResolver, file);
} catch (ArtifactResolutionException are) {
this.logger.warn("The artifact version could not be resolved; skipping: {}", artifact, version);
}
}
} catch (VersionRangeResolutionException vrre) {
this.logger.error("The artifact version range could not be resolved; skipping: {}", child.getValue());
} }
} }

View File

@@ -27,6 +27,7 @@ import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.codehaus.plexus.util.xml.Xpp3DomBuilder; import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException; import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
import org.eclipse.aether.impl.ArtifactResolver; import org.eclipse.aether.impl.ArtifactResolver;
import org.eclipse.aether.impl.VersionRangeResolver;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -34,8 +35,8 @@ public class BanConfigurationDownloader extends AbstractBanConfiguration {
private final Logger logger = LoggerFactory.getLogger(this.getClass()); private final Logger logger = LoggerFactory.getLogger(this.getClass());
public BanConfigurationDownloader(MavenSession session, ArtifactResolver artifactResolver, String url) throws IOException, MojoFailureException { public BanConfigurationDownloader(MavenSession session, ArtifactResolver artifactResolver, VersionRangeResolver versionRangeResolver, String url) throws IOException, MojoFailureException {
super(session, artifactResolver); super(session, artifactResolver, versionRangeResolver);
try { try {
Xpp3Dom rootDom = this.load(new URL(url)); Xpp3Dom rootDom = this.load(new URL(url));
@@ -45,8 +46,8 @@ public class BanConfigurationDownloader extends AbstractBanConfiguration {
} }
} }
public BanConfigurationDownloader(MavenSession session, ArtifactResolver artifactResolver, File file) throws IOException, MojoFailureException { public BanConfigurationDownloader(MavenSession session, ArtifactResolver artifactResolver, VersionRangeResolver versionRangeResolver, File file) throws IOException, MojoFailureException {
super(session, artifactResolver); super(session, artifactResolver, versionRangeResolver);
try { try {
Xpp3Dom rootDom = this.load(file); Xpp3Dom rootDom = this.load(file);

View File

@@ -21,11 +21,12 @@ import org.apache.maven.model.Plugin;
import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugin.MojoFailureException;
import org.codehaus.plexus.util.xml.Xpp3Dom; import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.eclipse.aether.impl.ArtifactResolver; import org.eclipse.aether.impl.ArtifactResolver;
import org.eclipse.aether.impl.VersionRangeResolver;
public class BanConfigurationParser extends AbstractBanConfiguration { public class BanConfigurationParser extends AbstractBanConfiguration {
public BanConfigurationParser(MavenSession session, ArtifactResolver artifactResolver, Plugin plugin) throws IOException, MojoFailureException { public BanConfigurationParser(MavenSession session, ArtifactResolver artifactResolver, VersionRangeResolver versionRangeResolver, Plugin plugin) throws IOException, MojoFailureException {
super(session, artifactResolver); super(session, artifactResolver, versionRangeResolver);
Xpp3Dom rootDom = (Xpp3Dom) plugin.getConfiguration(); Xpp3Dom rootDom = (Xpp3Dom) plugin.getConfiguration();
this.init(rootDom); this.init(rootDom);

View File

@@ -40,6 +40,7 @@ import org.eclipse.aether.graph.Dependency;
import org.eclipse.aether.graph.DependencyFilter; import org.eclipse.aether.graph.DependencyFilter;
import org.eclipse.aether.graph.DependencyNode; import org.eclipse.aether.graph.DependencyNode;
import org.eclipse.aether.impl.ArtifactResolver; import org.eclipse.aether.impl.ArtifactResolver;
import org.eclipse.aether.impl.VersionRangeResolver;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -56,6 +57,9 @@ public class BanExtension extends AbstractMavenLifecycleParticipant {
@Inject @Inject
private ArtifactResolver artifactResolver; private ArtifactResolver artifactResolver;
@Inject
private VersionRangeResolver versionRangeResolver;
@Inject @Inject
private ProjectDependenciesResolver projDepResolver; private ProjectDependenciesResolver projDepResolver;
@@ -113,7 +117,7 @@ public class BanExtension extends AbstractMavenLifecycleParticipant {
return null; return null;
} else { } else {
try { try {
return new BanConfigurationParser(session, this.artifactResolver, plugin); return new BanConfigurationParser(session, this.artifactResolver, this.versionRangeResolver, plugin);
} catch (IOException | MojoFailureException e) { } catch (IOException | MojoFailureException e) {
throw new MavenExecutionException(e.getMessage(), project.getFile()); throw new MavenExecutionException(e.getMessage(), project.getFile());
} }

View File

@@ -16,6 +16,7 @@ package com.inteligr8.maven.ban;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.DirectoryNotEmptyException;
import java.nio.file.FileVisitResult; import java.nio.file.FileVisitResult;
import java.nio.file.FileVisitor; import java.nio.file.FileVisitor;
import java.nio.file.Files; import java.nio.file.Files;
@@ -23,6 +24,7 @@ import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes; import java.nio.file.attribute.BasicFileAttributes;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@@ -45,6 +47,7 @@ import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.component.annotations.Component; import org.codehaus.plexus.component.annotations.Component;
import org.eclipse.aether.impl.ArtifactResolver; import org.eclipse.aether.impl.ArtifactResolver;
import org.eclipse.aether.impl.VersionRangeResolver;
import com.inteligr8.maven.model.ArtifactFilter; import com.inteligr8.maven.model.ArtifactFilter;
@@ -58,6 +61,9 @@ public class PurgeRepoMojo extends AbstractMojo {
@Inject @Inject
private ArtifactResolver artifactResolver; private ArtifactResolver artifactResolver;
@Inject
private VersionRangeResolver versionRangeResolver;
@Parameter(name = "skip", defaultValue = "false") @Parameter(name = "skip", defaultValue = "false")
private boolean skip = false; private boolean skip = false;
@@ -90,10 +96,13 @@ public class PurgeRepoMojo extends AbstractMojo {
continue; continue;
} }
Path groupPath = this.getGroupPath(afilter); Path groupPath = this.resolveGroupPath(afilter);
List<Path> artifactPaths = this.getArtifactPaths(groupPath, afilter); if (groupPath == null)
continue;
List<Path> artifactPaths = this.resolveArtifactPaths(groupPath, afilter);
for (Path artifactPath : artifactPaths) for (Path artifactPath : artifactPaths)
includePaths.addAll(this.getVersionPaths(artifactPath, afilter.getVersionRange())); includePaths.addAll(this.resolveVersionPaths(artifactPath, afilter.getVersionRange()));
} }
this.getLog().debug("May be purging all files in " + includePaths.size() + " paths"); this.getLog().debug("May be purging all files in " + includePaths.size() + " paths");
@@ -105,7 +114,7 @@ public class PurgeRepoMojo extends AbstractMojo {
StringBuilder regex = new StringBuilder(); StringBuilder regex = new StringBuilder();
if (afilter.getGroupId() != null) { if (afilter.getGroupId() != null) {
regex.append('^').append(this.getGroupPath(afilter)); regex.append('^').append(this.resolveGroupPath(afilter));
} else if (afilter.getGroupIdRegex() != null) { } else if (afilter.getGroupIdRegex() != null) {
regex.append(afilter.getGroupIdRegex().replace("\\.", regexDirectorySeparator)); regex.append(afilter.getGroupIdRegex().replace("\\.", regexDirectorySeparator));
if (regex.charAt(0) != '^') if (regex.charAt(0) != '^')
@@ -150,14 +159,14 @@ public class PurgeRepoMojo extends AbstractMojo {
this.getLog().info("DRYRUN: Would have deleted certain paths from local Maven cache: " + repoPath); this.getLog().info("DRYRUN: Would have deleted certain paths from local Maven cache: " + repoPath);
this.getLog().info("DRYRUN: Would have deleted these paths: " + includePaths); this.getLog().info("DRYRUN: Would have deleted these paths: " + includePaths);
} else { } else {
for (Path path : includePaths) { for (Path versionPath : includePaths) {
Path fullpath = repoPath.resolve(path); Path fullVersionPath = repoPath.resolve(versionPath);
if (Files.exists(fullpath)) { if (Files.exists(fullVersionPath)) {
this.getLog().info("Deleting version from Maven cache: " + path); this.getLog().info("Deleting version from Maven cache: " + versionPath);
Files.walkFileTree(fullpath, new DeleteDirectoryVisitor()); Files.walkFileTree(fullVersionPath, new DeleteNonMetadataVisitor());
} else { } else {
// this will probably never happen // this will probably never happen
this.getLog().debug("Maven cache does not exist: " + path); this.getLog().debug("Maven cache does not exist: " + versionPath);
} }
} }
} }
@@ -168,23 +177,42 @@ public class PurgeRepoMojo extends AbstractMojo {
Plugin plugin = project.getPlugin(BanExtension.THIS_PLUGIN_KEY); Plugin plugin = project.getPlugin(BanExtension.THIS_PLUGIN_KEY);
if (plugin == null) if (plugin == null)
throw new MojoFailureException("The plugin is executing but it cannot be found"); throw new MojoFailureException("The plugin is executing but it cannot be found");
return new BanConfigurationParser(this.session, this.artifactResolver, plugin); return new BanConfigurationParser(this.session, this.artifactResolver, this.versionRangeResolver, plugin);
} }
private Path getGroupPath(ArtifactFilter afilter) { private Path resolveGroupPath(ArtifactFilter afilter) {
if (afilter.getGroupId() == null)
return null;
String[] pathElements = afilter.getGroupId().split("\\."); String[] pathElements = afilter.getGroupId().split("\\.");
Path groupPath = Paths.get(""); Path groupPath = Paths.get("");
for (String pathElement : pathElements) for (String pathElement : pathElements)
groupPath = groupPath.resolve(pathElement); groupPath = groupPath.resolve(pathElement);
Path fullGroupPath = this.getRepositoryPath().resolve(groupPath);
if (!Files.exists(fullGroupPath)) {
this.getLog().debug("The group path does not exist, so nothing to purge: " + fullGroupPath);
return null;
}
return groupPath; return groupPath;
} }
private List<Path> getArtifactPaths(Path groupPath, ArtifactFilter afilter) throws IOException { private List<Path> resolveArtifactPaths(Path groupPath, ArtifactFilter afilter) throws IOException {
if (afilter.getArtifactId() != null) Path repoPath = this.getRepositoryPath();
return Arrays.asList(groupPath.resolve(afilter.getArtifactId()));
if (afilter.getArtifactId() != null) {
Path artifactPath = groupPath.resolve(afilter.getArtifactId());
Path fullArtifactPath = repoPath.resolve(artifactPath);
if (Files.exists(fullArtifactPath)) {
return Arrays.asList(artifactPath);
} else {
this.getLog().debug("The artifact path does not exist, so nothing to purge: " + fullArtifactPath);
return Collections.emptyList();
}
}
Pattern artifactPattern = afilter.getArtifactIdRegex() == null ? null : Pattern.compile(afilter.getArtifactIdRegex()); Pattern artifactPattern = afilter.getArtifactIdRegex() == null ? null : Pattern.compile(afilter.getArtifactIdRegex());
Path repoPath = this.getRepositoryPath();
List<Path> paths = new LinkedList<>(); List<Path> paths = new LinkedList<>();
if (artifactPattern == null) if (artifactPattern == null)
@@ -192,14 +220,27 @@ public class PurgeRepoMojo extends AbstractMojo {
Files.list(repoPath.resolve(groupPath)).forEach(new Consumer<Path>() { Files.list(repoPath.resolve(groupPath)).forEach(new Consumer<Path>() {
@Override @Override
public void accept(Path t) { public void accept(Path fullArtifactPath) {
if (artifactPattern == null) { if (artifactPattern == null) {
paths.add(repoPath.relativize(t)); // these may include sub-groups and not just artifacts
// which will lead to paths with artifacts as versions
// so we are looping through versions to see if it is indeed an artifact
try {
Files.list(fullArtifactPath).findFirst().ifPresent(new Consumer<Path>() {
@Override
public void accept(Path fullVersionPath) {
if (Files.exists(fullVersionPath.resolve("_remote.repositories")))
paths.add(repoPath.relativize(fullArtifactPath));
}
});
} catch (IOException ie) {
getLog().error(ie.getMessage(), ie);
}
} else { } else {
Matcher matcher = artifactPattern.matcher(t.getFileName().toString()); Matcher matcher = artifactPattern.matcher(fullArtifactPath.getFileName().toString());
if (matcher.matches()) { if (matcher.matches()) {
getLog().debug("The artifact directory '" + t.getFileName() + "' qualifies as included"); getLog().debug("The artifact directory '" + fullArtifactPath.getFileName() + "' qualifies as included");
paths.add(repoPath.relativize(t)); paths.add(repoPath.relativize(fullArtifactPath));
} }
} }
} }
@@ -208,7 +249,7 @@ public class PurgeRepoMojo extends AbstractMojo {
return paths; return paths;
} }
private List<Path> getVersionPaths(Path artifactPath, VersionRange versionRange) throws IOException { private List<Path> resolveVersionPaths(Path artifactPath, VersionRange versionRange) throws IOException {
Path repoPath = this.getRepositoryPath(); Path repoPath = this.getRepositoryPath();
List<Path> paths = new LinkedList<>(); List<Path> paths = new LinkedList<>();
@@ -239,7 +280,9 @@ public class PurgeRepoMojo extends AbstractMojo {
private class DeleteDirectoryVisitor implements FileVisitor<Path> { private class DeleteNonMetadataVisitor implements FileVisitor<Path> {
private final Pattern versionPathPattern = Pattern.compile("/([^/]+)/([^/]+)$");
@Override @Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
@@ -248,12 +291,30 @@ public class PurgeRepoMojo extends AbstractMojo {
@Override @Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
try { if (attrs.isDirectory()) {
if (!attrs.isDirectory()) getLog().warn("An unexpected directory was found: " + file);
return FileVisitResult.SKIP_SUBTREE;
}
Matcher matcher = this.versionPathPattern.matcher(file.toString());
if (!matcher.find()) {
getLog().debug("Ignoring file from purge: " + file);
return FileVisitResult.CONTINUE;
}
String artifactId = matcher.group(1);
String version = matcher.group(2);
String includeName = artifactId + "-" + version;
String excludeName = artifactId + "-" + version + ".pom";
if (file.getFileName().toString().startsWith(includeName) &&
!file.getFileName().toString().startsWith(excludeName)) {
try {
Files.delete(file); Files.delete(file);
} catch (IOException ie) { } catch (IOException ie) {
getLog().debug(ie); getLog().debug(ie);
getLog().warn("The file failed to delete: " + file); getLog().warn("The file failed to delete: " + file);
return FileVisitResult.SKIP_SIBLINGS;
}
} }
return FileVisitResult.CONTINUE; return FileVisitResult.CONTINUE;
@@ -268,6 +329,8 @@ public class PurgeRepoMojo extends AbstractMojo {
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
try { try {
Files.delete(dir); Files.delete(dir);
} catch (DirectoryNotEmptyException dnee) {
getLog().debug("The folder will not be deleted as it is not empty: " + dir);
} catch (IOException ie) { } catch (IOException ie) {
getLog().debug(ie); getLog().debug(ie);
getLog().warn("The folder failed to delete: " + dir); getLog().warn("The folder failed to delete: " + dir);