Merge branch 'develop' into stable
This commit is contained in:
commit
e241137209
1
pom.xml
1
pom.xml
@ -146,7 +146,6 @@
|
|||||||
<configuration>
|
<configuration>
|
||||||
<projectsDirectory>${basedir}/src/it</projectsDirectory>
|
<projectsDirectory>${basedir}/src/it</projectsDirectory>
|
||||||
<cloneProjectsTo>${project.build.directory}/it</cloneProjectsTo>
|
<cloneProjectsTo>${project.build.directory}/it</cloneProjectsTo>
|
||||||
<localRepositoryPath>${project.build.directory}/it-repo</localRepositoryPath>
|
|
||||||
<mavenHome>${env.MAVEN_HOME}</mavenHome>
|
<mavenHome>${env.MAVEN_HOME}</mavenHome>
|
||||||
<debug>true</debug>
|
<debug>true</debug>
|
||||||
<ignoreFailures>true</ignoreFailures>
|
<ignoreFailures>true</ignoreFailures>
|
||||||
|
56
src/it/ban-log4j-purge/pom.xml
Normal file
56
src/it/ban-log4j-purge/pom.xml
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>com.inteligr8</groupId>
|
||||||
|
<artifactId>ban-maven-plugin-log4j-old</artifactId>
|
||||||
|
<version>@pom.version@</version>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>Log4j Ban Plugin Tests</name>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>log4j</groupId>
|
||||||
|
<artifactId>log4j</artifactId>
|
||||||
|
<version>1.2.17</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.11.0</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>ban-maven-plugin</artifactId>
|
||||||
|
<version>@pom.version@</version>
|
||||||
|
<extensions>true</extensions>
|
||||||
|
<configuration>
|
||||||
|
<includes>
|
||||||
|
<artifact>
|
||||||
|
<groupId>log4j</groupId>
|
||||||
|
<artifactId>log4j</artifactId>
|
||||||
|
</artifact>
|
||||||
|
</includes>
|
||||||
|
<excludes>
|
||||||
|
<artifact>log4j:log.+:[1.2.17,)</artifact>
|
||||||
|
</excludes>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>purge</id>
|
||||||
|
<phase>prepare-package</phase>
|
||||||
|
<goals><goal>purge-repo</goal></goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
@ -21,20 +21,16 @@ import java.util.regex.Matcher;
|
|||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
|
|
||||||
import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
|
import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
|
||||||
import org.apache.maven.artifact.versioning.VersionRange;
|
import org.apache.maven.artifact.versioning.VersionRange;
|
||||||
import org.apache.maven.model.Plugin;
|
import org.apache.maven.model.Plugin;
|
||||||
import org.codehaus.plexus.util.xml.Xpp3Dom;
|
import org.codehaus.plexus.util.xml.Xpp3Dom;
|
||||||
import org.eclipse.aether.artifact.Artifact;
|
|
||||||
import org.eclipse.aether.graph.DependencyFilter;
|
|
||||||
import org.eclipse.aether.graph.DependencyNode;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import com.inteligr8.maven.model.ArtifactFilter;
|
import com.inteligr8.maven.model.ArtifactFilter;
|
||||||
|
|
||||||
public class BanConfigurationParser implements DependencyFilter {
|
public class BanConfigurationParser {
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||||
private final Pattern artifactPattern = Pattern.compile("^([^:]+):([^:]+)(:([^:]+))?$");
|
private final Pattern artifactPattern = Pattern.compile("^([^:]+):([^:]+)(:([^:]+))?$");
|
||||||
@ -42,7 +38,6 @@ public class BanConfigurationParser implements DependencyFilter {
|
|||||||
|
|
||||||
private final List<ArtifactFilter> includeArtifacts;
|
private final List<ArtifactFilter> includeArtifacts;
|
||||||
private final List<ArtifactFilter> excludeArtifacts;
|
private final List<ArtifactFilter> excludeArtifacts;
|
||||||
private boolean failFast = false;
|
|
||||||
|
|
||||||
public BanConfigurationParser(Plugin plugin) {
|
public BanConfigurationParser(Plugin plugin) {
|
||||||
Xpp3Dom rootDom = (Xpp3Dom) plugin.getConfiguration();
|
Xpp3Dom rootDom = (Xpp3Dom) plugin.getConfiguration();
|
||||||
@ -69,8 +64,12 @@ public class BanConfigurationParser implements DependencyFilter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFailFast(boolean failFast) {
|
public List<ArtifactFilter> getIncludeArtifacts() {
|
||||||
this.failFast = failFast;
|
return this.includeArtifacts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ArtifactFilter> getExcludeArtifacts() {
|
||||||
|
return this.excludeArtifacts;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ArtifactFilter> parseArtifacts(Xpp3Dom artifactsDom) {
|
private List<ArtifactFilter> parseArtifacts(Xpp3Dom artifactsDom) {
|
||||||
@ -92,7 +91,7 @@ public class BanConfigurationParser implements DependencyFilter {
|
|||||||
filter.setGroupIdRegex(StringUtils.trimToNull(matcher.group(1)));
|
filter.setGroupIdRegex(StringUtils.trimToNull(matcher.group(1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.notRegexPattern.matcher(matcher.group(1)).matches()) {
|
if (this.notRegexPattern.matcher(matcher.group(2)).matches()) {
|
||||||
filter.setArtifactId(StringUtils.trimToNull(matcher.group(2)));
|
filter.setArtifactId(StringUtils.trimToNull(matcher.group(2)));
|
||||||
} else {
|
} else {
|
||||||
filter.setArtifactIdRegex(StringUtils.trimToNull(matcher.group(2)));
|
filter.setArtifactIdRegex(StringUtils.trimToNull(matcher.group(2)));
|
||||||
@ -129,57 +128,4 @@ public class BanConfigurationParser implements DependencyFilter {
|
|||||||
return childDom == null ? null : StringUtils.trimToNull(childDom.getValue());
|
return childDom == null ? null : StringUtils.trimToNull(childDom.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean accept(DependencyNode node, List<DependencyNode> parents) {
|
|
||||||
this.logger.debug("Evaluating dependency '{}'", node);
|
|
||||||
boolean ban = false;
|
|
||||||
|
|
||||||
for (ArtifactFilter afilter : this.includeArtifacts) {
|
|
||||||
Artifact depArtifact = node.getArtifact();
|
|
||||||
if (this.matches(afilter.getGroupId(), afilter.getGroupIdRegex(), depArtifact.getGroupId()) &&
|
|
||||||
this.matches(afilter.getArtifactId(), afilter.getArtifactIdRegex(), depArtifact.getArtifactId()) &&
|
|
||||||
this.withinRange(afilter.getVersionRange(), depArtifact.getVersion())) {
|
|
||||||
this.logger.debug("The dependency '{}' matches the ban inclusion filter", depArtifact);
|
|
||||||
ban = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ban)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
for (ArtifactFilter afilter : this.excludeArtifacts) {
|
|
||||||
Artifact depArtifact = node.getArtifact();
|
|
||||||
if (this.matches(afilter.getGroupId(), afilter.getGroupIdRegex(), depArtifact.getGroupId()) &&
|
|
||||||
this.matches(afilter.getArtifactId(), afilter.getArtifactIdRegex(), depArtifact.getArtifactId()) &&
|
|
||||||
this.withinRange(afilter.getVersionRange(), depArtifact.getVersion())) {
|
|
||||||
this.logger.debug("The dependency '{}' matches the ban exlusion filter", depArtifact);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.failFast) {
|
|
||||||
// plugin resolution downloads banned dependencies unless we fail now; not later
|
|
||||||
throw new RuntimeException("Banned dependency detected: " + node + " => " + parents);
|
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean matches(String exactFilter, String regexFilter, String value) {
|
|
||||||
if (exactFilter == null && regexFilter == null) {
|
|
||||||
return true;
|
|
||||||
} else if (exactFilter != null) {
|
|
||||||
return exactFilter.equals(value);
|
|
||||||
} else {
|
|
||||||
Pattern filterPattern = Pattern.compile(regexFilter);
|
|
||||||
Matcher matcher = filterPattern.matcher(value);
|
|
||||||
return matcher.matches();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean withinRange(VersionRange versionRange, String version) {
|
|
||||||
return versionRange == null || versionRange.containsVersion(new DefaultArtifactVersion(version));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
102
src/main/java/com/inteligr8/maven/ban/BanDependencyFilter.java
Normal file
102
src/main/java/com/inteligr8/maven/ban/BanDependencyFilter.java
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
/*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.inteligr8.maven.ban;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
|
||||||
|
import org.apache.maven.artifact.versioning.VersionRange;
|
||||||
|
import org.eclipse.aether.artifact.Artifact;
|
||||||
|
import org.eclipse.aether.graph.DependencyFilter;
|
||||||
|
import org.eclipse.aether.graph.DependencyNode;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.inteligr8.maven.model.ArtifactFilter;
|
||||||
|
|
||||||
|
public class BanDependencyFilter implements DependencyFilter {
|
||||||
|
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
|
private final List<ArtifactFilter> includeArtifacts;
|
||||||
|
private final List<ArtifactFilter> excludeArtifacts;
|
||||||
|
private boolean failFast = false;
|
||||||
|
|
||||||
|
public BanDependencyFilter(List<ArtifactFilter> includeArtifacts, List<ArtifactFilter> excludeArtifacts) {
|
||||||
|
this.includeArtifacts = includeArtifacts;
|
||||||
|
this.excludeArtifacts = excludeArtifacts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFailFast(boolean failFast) {
|
||||||
|
this.failFast = failFast;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean accept(DependencyNode node, List<DependencyNode> parents) {
|
||||||
|
this.logger.debug("Evaluating dependency '{}'", node);
|
||||||
|
Artifact depArtifact = node.getArtifact();
|
||||||
|
boolean ban = false;
|
||||||
|
|
||||||
|
for (ArtifactFilter afilter : this.includeArtifacts) {
|
||||||
|
if (this.matches(afilter.getGroupId(), afilter.getGroupIdRegex(), depArtifact.getGroupId()) &&
|
||||||
|
this.matches(afilter.getArtifactId(), afilter.getArtifactIdRegex(), depArtifact.getArtifactId()) &&
|
||||||
|
this.withinRange(afilter.getVersionRange(), depArtifact.getVersion())) {
|
||||||
|
this.logger.debug("The dependency '{}' matches the ban inclusion filter", depArtifact);
|
||||||
|
ban = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ban)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (ArtifactFilter afilter : this.excludeArtifacts) {
|
||||||
|
if (this.matches(afilter.getGroupId(), afilter.getGroupIdRegex(), depArtifact.getGroupId()) &&
|
||||||
|
this.matches(afilter.getArtifactId(), afilter.getArtifactIdRegex(), depArtifact.getArtifactId()) &&
|
||||||
|
this.withinRange(afilter.getVersionRange(), depArtifact.getVersion())) {
|
||||||
|
this.logger.debug("The dependency '{}' matches the ban exlusion filter", depArtifact);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.failFast) {
|
||||||
|
// plugin resolution downloads banned dependencies unless we fail now; not later
|
||||||
|
throw new RuntimeException("Banned dependency detected: " + node + " => " + parents);
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean matches(String exactFilter, String regexFilter, String value) {
|
||||||
|
if (exactFilter == null && regexFilter == null) {
|
||||||
|
return true;
|
||||||
|
} else if (exactFilter != null) {
|
||||||
|
return exactFilter.equals(value);
|
||||||
|
} else {
|
||||||
|
Pattern filterPattern = Pattern.compile(regexFilter);
|
||||||
|
Matcher matcher = filterPattern.matcher(value);
|
||||||
|
return matcher.matches();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean withinRange(VersionRange versionRange, String version) {
|
||||||
|
boolean within = versionRange == null || versionRange.containsVersion(new DefaultArtifactVersion(version));
|
||||||
|
this.logger.debug("Tested version range: {} <=> {}: {}", versionRange, version, within);
|
||||||
|
return within;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -44,9 +44,9 @@ import org.slf4j.LoggerFactory;
|
|||||||
@Singleton
|
@Singleton
|
||||||
public class BanExtension extends AbstractMavenLifecycleParticipant {
|
public class BanExtension extends AbstractMavenLifecycleParticipant {
|
||||||
|
|
||||||
private static final String THIS_PLUGIN_GROUP_ID = "com.inteligr8";
|
public static final String THIS_PLUGIN_GROUP_ID = "com.inteligr8";
|
||||||
private static final String THIS_PLUGIN_ARTIFACT_ID = "ban-maven-plugin";
|
public static final String THIS_PLUGIN_ARTIFACT_ID = "ban-maven-plugin";
|
||||||
private static final String THIS_PLUGIN_KEY = THIS_PLUGIN_GROUP_ID + ":" + THIS_PLUGIN_ARTIFACT_ID;
|
public static final String THIS_PLUGIN_KEY = THIS_PLUGIN_GROUP_ID + ":" + THIS_PLUGIN_ARTIFACT_ID;
|
||||||
|
|
||||||
private Logger logger = LoggerFactory.getLogger(this.getClass());
|
private Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
@ -62,15 +62,17 @@ public class BanExtension extends AbstractMavenLifecycleParticipant {
|
|||||||
BanConfigurationParser config = this.getConfiguration(project);
|
BanConfigurationParser config = this.getConfiguration(project);
|
||||||
if (config == null)
|
if (config == null)
|
||||||
return;
|
return;
|
||||||
config.setFailFast(true);
|
|
||||||
|
BanDependencyFilter depFilter = new BanDependencyFilter(config.getIncludeArtifacts(), config.getExcludeArtifacts());
|
||||||
|
depFilter.setFailFast(true);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (Plugin plugin : project.getBuildPlugins()) {
|
for (Plugin plugin : project.getBuildPlugins()) {
|
||||||
this.logger.debug("Evaluating plugin dependencies: {}", plugin);
|
this.logger.debug("Evaluating plugin dependencies: {}", plugin);
|
||||||
|
|
||||||
Artifact artifact = new DefaultArtifact(plugin.getId());
|
Artifact artifact = new DefaultArtifact(plugin.getId());
|
||||||
DependencyNode depNodeRoot = this.pluginDepResolver.resolve(plugin, artifact, config, project.getRemotePluginRepositories(), session.getRepositorySession());
|
DependencyNode depNodeRoot = this.pluginDepResolver.resolve(plugin, artifact, depFilter, project.getRemotePluginRepositories(), session.getRepositorySession());
|
||||||
List<Dependency> bannedDependencies = this.crawlDependencyTree(depNodeRoot, config);
|
List<Dependency> bannedDependencies = this.crawlDependencyTree(depNodeRoot, depFilter);
|
||||||
if (!bannedDependencies.isEmpty())
|
if (!bannedDependencies.isEmpty())
|
||||||
throw new MavenExecutionException("Banned dependencies were detected in plugin '" + plugin + "': " + bannedDependencies, project.getFile());
|
throw new MavenExecutionException("Banned dependencies were detected in plugin '" + plugin + "': " + bannedDependencies, project.getFile());
|
||||||
}
|
}
|
||||||
@ -78,10 +80,10 @@ public class BanExtension extends AbstractMavenLifecycleParticipant {
|
|||||||
throw new MavenExecutionException(pre.getMessage(), pre);
|
throw new MavenExecutionException(pre.getMessage(), pre);
|
||||||
}
|
}
|
||||||
|
|
||||||
config.setFailFast(false);
|
depFilter.setFailFast(false);
|
||||||
|
|
||||||
DefaultDependencyResolutionRequest request = new DefaultDependencyResolutionRequest(project, session.getRepositorySession());
|
DefaultDependencyResolutionRequest request = new DefaultDependencyResolutionRequest(project, session.getRepositorySession());
|
||||||
request.setResolutionFilter(config);
|
request.setResolutionFilter(depFilter);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
DependencyResolutionResult result = this.projDepResolver.resolve(request);
|
DependencyResolutionResult result = this.projDepResolver.resolve(request);
|
||||||
|
263
src/main/java/com/inteligr8/maven/ban/PurgeRepoMojo.java
Normal file
263
src/main/java/com/inteligr8/maven/ban/PurgeRepoMojo.java
Normal file
@ -0,0 +1,263 @@
|
|||||||
|
/*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||||
|
* more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.inteligr8.maven.ban;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.FileVisitResult;
|
||||||
|
import java.nio.file.FileVisitor;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.nio.file.attribute.BasicFileAttributes;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import org.apache.maven.artifact.versioning.ArtifactVersion;
|
||||||
|
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
|
||||||
|
import org.apache.maven.artifact.versioning.VersionRange;
|
||||||
|
import org.apache.maven.execution.MavenSession;
|
||||||
|
import org.apache.maven.model.Plugin;
|
||||||
|
import org.apache.maven.plugin.AbstractMojo;
|
||||||
|
import org.apache.maven.plugin.MojoExecutionException;
|
||||||
|
import org.apache.maven.plugin.MojoFailureException;
|
||||||
|
import org.apache.maven.plugins.annotations.Mojo;
|
||||||
|
import org.apache.maven.plugins.annotations.Parameter;
|
||||||
|
import org.apache.maven.project.MavenProject;
|
||||||
|
import org.codehaus.plexus.component.annotations.Component;
|
||||||
|
|
||||||
|
import com.inteligr8.maven.model.ArtifactFilter;
|
||||||
|
|
||||||
|
@Mojo( name = "purge-repo", threadSafe = true )
|
||||||
|
@Component( role = org.apache.maven.plugin.Mojo.class )
|
||||||
|
public class PurgeRepoMojo extends AbstractMojo {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private MavenSession session;
|
||||||
|
|
||||||
|
@Parameter(name = "skip", defaultValue = "false")
|
||||||
|
private boolean skip = false;
|
||||||
|
|
||||||
|
@Parameter(name = "dryRun", defaultValue = "false")
|
||||||
|
private boolean dryRun = false;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute() throws MojoExecutionException, MojoFailureException {
|
||||||
|
if (this.skip) {
|
||||||
|
this.getLog().debug("Skipping purge of banned artifacts");
|
||||||
|
} else {
|
||||||
|
this.getLog().info("Purging banned artifacts from local repository: " + this.session.getLocalRepository().getBasedir());
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.purge();
|
||||||
|
} catch (IOException ie) {
|
||||||
|
throw new MojoFailureException(ie.getMessage(), ie);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void purge() throws MojoFailureException, IOException {
|
||||||
|
List<Path> includePaths = new LinkedList<>();
|
||||||
|
|
||||||
|
BanConfigurationParser config = this.getConfiguration(this.session.getCurrentProject());
|
||||||
|
|
||||||
|
for (ArtifactFilter afilter : config.getIncludeArtifacts()) {
|
||||||
|
if (afilter.getGroupId() == null) {
|
||||||
|
this.getLog().warn("The purge does not support wildcard group ID specifications, so skipping it: " + afilter);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Path groupPath = this.getGroupPath(afilter);
|
||||||
|
List<Path> artifactPaths = this.getArtifactPaths(groupPath, afilter);
|
||||||
|
for (Path artifactPath : artifactPaths)
|
||||||
|
includePaths.addAll(this.getVersionPaths(artifactPath, afilter.getVersionRange()));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.getLog().debug("May be purging all files in " + includePaths.size() + " paths");
|
||||||
|
String regexDirectorySeparator = String.valueOf(File.separatorChar);
|
||||||
|
if (File.separatorChar == '\\')
|
||||||
|
regexDirectorySeparator += "\\";
|
||||||
|
|
||||||
|
for (ArtifactFilter afilter : config.getExcludeArtifacts()) {
|
||||||
|
StringBuilder regex = new StringBuilder();
|
||||||
|
|
||||||
|
if (afilter.getGroupId() != null) {
|
||||||
|
regex.append('^').append(this.getGroupPath(afilter));
|
||||||
|
} else if (afilter.getGroupIdRegex() != null) {
|
||||||
|
regex.append(afilter.getGroupIdRegex().replace("\\.", regexDirectorySeparator));
|
||||||
|
if (regex.charAt(0) != '^')
|
||||||
|
regex.insert(0, '^');
|
||||||
|
} else {
|
||||||
|
regex.append("^.+");
|
||||||
|
}
|
||||||
|
|
||||||
|
regex.append(regexDirectorySeparator);
|
||||||
|
|
||||||
|
if (afilter.getArtifactId() != null) {
|
||||||
|
regex.append(afilter.getArtifactId());
|
||||||
|
} else if (afilter.getArtifactIdRegex() != null) {
|
||||||
|
regex.append(afilter.getArtifactIdRegex());
|
||||||
|
} else {
|
||||||
|
regex.append("[^").append(regexDirectorySeparator).append("]+");
|
||||||
|
}
|
||||||
|
|
||||||
|
Pattern pattern = Pattern.compile(regex.toString());
|
||||||
|
|
||||||
|
Iterator<Path> i = includePaths.iterator();
|
||||||
|
while (i.hasNext()) {
|
||||||
|
Path path = i.next();
|
||||||
|
|
||||||
|
Matcher matcher = pattern.matcher(path.toString());
|
||||||
|
if (!matcher.find())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// group/artifact match; now for version
|
||||||
|
if (afilter.getVersionRange() == null) {
|
||||||
|
i.remove();
|
||||||
|
} else {
|
||||||
|
String version = path.getFileName().toString();
|
||||||
|
if (afilter.getVersionRange().containsVersion(new DefaultArtifactVersion(version)))
|
||||||
|
i.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Path repoPath = this.getRepositoryPath();
|
||||||
|
if (this.dryRun) {
|
||||||
|
this.getLog().info("DRYRUN: Would have deleted certain paths from local Maven cache: " + repoPath);
|
||||||
|
this.getLog().info("DRYRUN: Would have deleted these paths: " + includePaths);
|
||||||
|
} else {
|
||||||
|
for (Path path : includePaths) {
|
||||||
|
Path fullpath = repoPath.resolve(path);
|
||||||
|
if (Files.exists(fullpath)) {
|
||||||
|
this.getLog().info("Deleting version from Maven cache: " + path);
|
||||||
|
Files.walkFileTree(fullpath, new DeleteDirectoryVisitor());
|
||||||
|
} else {
|
||||||
|
// this will probably never happen
|
||||||
|
this.getLog().debug("Maven cache does not exist: " + path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private BanConfigurationParser getConfiguration(MavenProject project) throws MojoFailureException {
|
||||||
|
Plugin plugin = project.getPlugin(BanExtension.THIS_PLUGIN_KEY);
|
||||||
|
if (plugin == null)
|
||||||
|
throw new MojoFailureException("The plugin is executing but it cannot be found");
|
||||||
|
return new BanConfigurationParser(plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Path getGroupPath(ArtifactFilter afilter) {
|
||||||
|
String[] pathElements = afilter.getGroupId().split("\\.");
|
||||||
|
Path groupPath = Paths.get("");
|
||||||
|
for (String pathElement : pathElements)
|
||||||
|
groupPath = groupPath.resolve(pathElement);
|
||||||
|
return groupPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Path> getArtifactPaths(Path groupPath, ArtifactFilter afilter) throws IOException {
|
||||||
|
if (afilter.getArtifactId() != null)
|
||||||
|
return Arrays.asList(groupPath.resolve(afilter.getArtifactId()));
|
||||||
|
|
||||||
|
Pattern artifactPattern = afilter.getArtifactIdRegex() == null ? null : Pattern.compile(afilter.getArtifactIdRegex());
|
||||||
|
Path repoPath = this.getRepositoryPath();
|
||||||
|
List<Path> paths = new LinkedList<>();
|
||||||
|
|
||||||
|
if (artifactPattern == null)
|
||||||
|
this.getLog().debug("All artifact directories in '" + groupPath + "' qualify as included");
|
||||||
|
|
||||||
|
Files.list(repoPath.resolve(groupPath)).forEach(new Consumer<Path>() {
|
||||||
|
@Override
|
||||||
|
public void accept(Path t) {
|
||||||
|
if (artifactPattern == null) {
|
||||||
|
paths.add(repoPath.relativize(t));
|
||||||
|
} else {
|
||||||
|
Matcher matcher = artifactPattern.matcher(t.getFileName().toString());
|
||||||
|
if (matcher.matches()) {
|
||||||
|
getLog().debug("The artifact directory '" + t.getFileName() + "' qualifies as included");
|
||||||
|
paths.add(repoPath.relativize(t));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return paths;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Path> getVersionPaths(Path artifactPath, VersionRange versionRange) throws IOException {
|
||||||
|
Path repoPath = this.getRepositoryPath();
|
||||||
|
List<Path> paths = new LinkedList<>();
|
||||||
|
|
||||||
|
if (versionRange == null)
|
||||||
|
this.getLog().debug("All artifact version directories in '" + artifactPath + "' qualify as included");
|
||||||
|
|
||||||
|
Files.list(repoPath.resolve(artifactPath)).forEach(new Consumer<Path>() {
|
||||||
|
@Override
|
||||||
|
public void accept(Path t) {
|
||||||
|
if (versionRange == null) {
|
||||||
|
paths.add(repoPath.relativize(t));
|
||||||
|
} else {
|
||||||
|
ArtifactVersion artifactVersion = new DefaultArtifactVersion(t.getFileName().toString());
|
||||||
|
if (versionRange.containsVersion(artifactVersion)) {
|
||||||
|
getLog().debug("The artifact version directory '" + t.getFileName() + "' qualifies as included");
|
||||||
|
paths.add(repoPath.relativize(t));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return paths;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Path getRepositoryPath() {
|
||||||
|
return new File(this.session.getLocalRepository().getBasedir()).toPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private class DeleteDirectoryVisitor implements FileVisitor<Path> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
|
||||||
|
return FileVisitResult.CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
|
||||||
|
Files.delete(file);
|
||||||
|
return FileVisitResult.CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
|
||||||
|
return FileVisitResult.CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
|
||||||
|
Files.delete(dir);
|
||||||
|
return FileVisitResult.CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user