diff --git a/depclean-core/src/main/java/se/kth/depclean/core/analysis/DefaultProjectDependencyAnalyzer.java b/depclean-core/src/main/java/se/kth/depclean/core/analysis/DefaultProjectDependencyAnalyzer.java
index 63ffa14e..206b6446 100644
--- a/depclean-core/src/main/java/se/kth/depclean/core/analysis/DefaultProjectDependencyAnalyzer.java
+++ b/depclean-core/src/main/java/se/kth/depclean/core/analysis/DefaultProjectDependencyAnalyzer.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (c) 2020, CASTOR Software Research Centre (www.castor.kth.se)
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
+ * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
package se.kth.depclean.core.analysis;
import java.io.File;
diff --git a/depclean-core/src/main/java/se/kth/depclean/core/analysis/graph/ClassMembersVisitorCounter.java b/depclean-core/src/main/java/se/kth/depclean/core/analysis/graph/ClassMembersVisitorCounter.java
index 1c90274a..f577078b 100644
--- a/depclean-core/src/main/java/se/kth/depclean/core/analysis/graph/ClassMembersVisitorCounter.java
+++ b/depclean-core/src/main/java/se/kth/depclean/core/analysis/graph/ClassMembersVisitorCounter.java
@@ -1,18 +1,5 @@
/*
* Copyright (c) 2020, CASTOR Software Research Centre (www.castor.kth.se)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met: 1) Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer. 2) Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution. 3) Neither the name of the Qulice.com nor
- * the names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
diff --git a/depclean-core/src/main/java/se/kth/depclean/core/analysis/graph/DefaultCallGraph.java b/depclean-core/src/main/java/se/kth/depclean/core/analysis/graph/DefaultCallGraph.java
index 805cd2c2..ed9ee91f 100644
--- a/depclean-core/src/main/java/se/kth/depclean/core/analysis/graph/DefaultCallGraph.java
+++ b/depclean-core/src/main/java/se/kth/depclean/core/analysis/graph/DefaultCallGraph.java
@@ -1,18 +1,5 @@
/*
* Copyright (c) 2020, CASTOR Software Research Centre (www.castor.kth.se)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met: 1) Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer. 2) Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution. 3) Neither the name of the Qulice.com nor
- * the names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
@@ -27,7 +14,6 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-
package se.kth.depclean.core.analysis.graph;
import java.util.HashSet;
diff --git a/depclean-maven-plugin/src/main/java/se/kth/depclean/DepCleanMojo.java b/depclean-maven-plugin/src/main/java/se/kth/depclean/DepCleanMojo.java
index a2aeac77..4415526a 100644
--- a/depclean-maven-plugin/src/main/java/se/kth/depclean/DepCleanMojo.java
+++ b/depclean-maven-plugin/src/main/java/se/kth/depclean/DepCleanMojo.java
@@ -1,18 +1,5 @@
/*
* Copyright (c) 2020, CASTOR Software Research Centre (www.castor.kth.se)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met: 1) Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer. 2) Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution. 3) Neither the name of the Qulice.com nor
- * the names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
@@ -74,342 +61,370 @@
import se.kth.depclean.util.MavenInvoker;
/**
- * This Maven mojo produces a clean copy of the project's pom file without bloated dependencies.
- * It is built on top of the maven-dependency-analyzer component.
+ * This Maven mojo is the main class of DepClean.
+ * DepClean is built on top of the maven-dependency-analyzer component.
+ * It produces a clean copy of the project's pom file, without bloated dependencies.
*
* @see
* @see
*/
@Mojo(name = "depclean", defaultPhase = LifecyclePhase.PACKAGE,
- requiresDependencyCollection = ResolutionScope.TEST,
- requiresDependencyResolution = ResolutionScope.TEST, threadSafe = true)
+ requiresDependencyCollection = ResolutionScope.TEST,
+ requiresDependencyResolution = ResolutionScope.TEST, threadSafe = true)
public class DepCleanMojo extends AbstractMojo
{
- /**
- * The Maven project to analyze.
- */
- @Parameter(defaultValue = "${project}", readonly = true)
- private MavenProject project;
-
- /**
- * The Maven session to analyze.
- */
- @Parameter(defaultValue = "${session}", readonly = true)
- private MavenSession session;
-
- /**
- * If this is true, DepClean creates a debloated version of the pom without unused dependencies,
- * called "debloated-pom.xml", in root of the project.
- */
- @Parameter(property = "create.pom.debloated", defaultValue = "false")
- private boolean createPomDebloated;
-
- /**
- * Add a list of dependencies, identified by their coordinates, to be ignored by DepClean during the analysis and
- * considered as used dependencies. Useful to override incomplete result caused by bytecode-level analysis
- * Dependency format is groupId:artifactId:version
.
- */
- @Parameter(property = "ignore.dependencies")
- private Set ignoreDependencies;
-
- /**
- * If this is true, and DepClean reported any unused dependency in the dependency tree,
- * the build fails immediately after running DepClean.
- */
- @Parameter(defaultValue = "false")
- private boolean failIfUnusedDependency;
-
- /**
- * Skip plugin execution completely.
- */
- @Parameter(defaultValue = "false")
- private boolean skipDepClean;
-
- @Component
- private ProjectBuilder mavenProjectBuilder;
-
- @Component
- private RepositorySystem repositorySystem;
-
- @Component(hint = "default")
- private DependencyGraphBuilder dependencyGraphBuilder;
-
- @Override
- public void execute() throws MojoExecutionException, MojoFailureException
- {
-
- if (skipDepClean) {
- getLog().info("Skipping DepClean plugin execution");
- return;
- }
-
- System.out.println("-------------------------------------------------------");
- getLog().info("Starting DepClean dependency analysis");
-
- File pomFile = new File(project.getBasedir().getAbsolutePath() + "/" + "pom.xml");
-
- String packaging = project.getPackaging();
- if (packaging.equals("pom")) {
- getLog().info("Skipping because packaging type " + packaging + ".");
- return;
- }
-
- String pathToPutDebloatedPom = project.getBasedir().getAbsolutePath() + "/" + "pom-debloated.xml";
-
- /* Build maven model to manipulate the pom */
- Model model;
- FileReader reader;
- MavenXpp3Reader mavenReader = new MavenXpp3Reader();
- try {
- reader = new FileReader(pomFile);
- model = mavenReader.read(reader);
- model.setPomFile(pomFile);
- } catch (Exception ex) {
- getLog().error("Unable to build the maven project.");
- return;
- }
-
- /* Copy direct dependencies locally */
- try {
- MavenInvoker.runCommand("mvn dependency:copy-dependencies");
- } catch (IOException e) {
- getLog().error("Unable resolve all the dependencies.");
- return;
- }
-
- /* Decompress dependencies */
- JarUtils.decompressJars(project.getBuild().getDirectory() + "/" + "dependency");
-
- /* Analyze dependencies usage status */
- ProjectDependencyAnalysis projectDependencyAnalysis;
- try {
- ProjectDependencyAnalyzer dependencyAnalyzer = new DefaultProjectDependencyAnalyzer();
- projectDependencyAnalysis = dependencyAnalyzer.analyze(project);
- } catch (ProjectDependencyAnalyzerException e) {
- getLog().error("Unable to analyze dependencies.");
- return;
- }
-
- Set usedUndeclaredArtifacts = projectDependencyAnalysis.getUsedUndeclaredArtifacts();
- Set usedDeclaredArtifacts = projectDependencyAnalysis.getUsedDeclaredArtifacts();
- Set unusedDeclaredArtifacts = projectDependencyAnalysis.getUnusedDeclaredArtifacts();
-
- Set unusedUndeclaredArtifacts = project.getArtifacts();
- unusedUndeclaredArtifacts.removeAll(usedDeclaredArtifacts);
- unusedUndeclaredArtifacts.removeAll(usedUndeclaredArtifacts);
- unusedUndeclaredArtifacts.removeAll(unusedDeclaredArtifacts);
-
- /* Use artifacts coordinates for the report instead of the Artifact object */
- Set usedDeclaredArtifactsCoordinates = new HashSet<>();
- usedDeclaredArtifacts.forEach(s -> usedDeclaredArtifactsCoordinates.add(s.getGroupId() + ":" + s.getArtifactId() + ":" + s.getVersion()));
-
- Set usedUndeclaredArtifactsCoordinates = new HashSet<>();
- usedUndeclaredArtifacts.forEach(s -> usedUndeclaredArtifactsCoordinates.add(s.getGroupId() + ":" + s.getArtifactId() + ":" + s.getVersion()));
-
- Set unusedDeclaredArtifactsCoordinates = new HashSet<>();
- unusedDeclaredArtifacts.forEach(s -> unusedDeclaredArtifactsCoordinates.add(s.getGroupId() + ":" + s.getArtifactId() + ":" + s.getVersion()));
-
- Set unusedUndeclaredArtifactsCoordinates = new HashSet<>();
- unusedUndeclaredArtifacts.forEach(s -> unusedUndeclaredArtifactsCoordinates.add(s.getGroupId() + ":" + s.getArtifactId() + ":" + s.getVersion()));
-
- /* Ignoring dependencies from analysis */
- if (ignoreDependencies != null) {
- for (String ignoredDependency : ignoreDependencies) {
- // if the ignored dependency is an unused declared dependency then add it to the set of used declared
- // and remove it from the set of unused declared
- for (Iterator i = unusedDeclaredArtifactsCoordinates.iterator(); i.hasNext(); ) {
- String unusedDeclaredArtifact = i.next();
- if (ignoredDependency.equals(unusedDeclaredArtifact)) {
- usedDeclaredArtifactsCoordinates.add(unusedDeclaredArtifact);
- i.remove();
- break;
- }
+ /**
+ * The Maven project to analyze.
+ */
+ @Parameter(defaultValue = "${project}", readonly = true)
+ private MavenProject project;
+
+ /**
+ * The Maven session to analyze.
+ */
+ @Parameter(defaultValue = "${session}", readonly = true)
+ private MavenSession session;
+
+ /**
+ * If this is true, DepClean creates a debloated version of the pom without unused dependencies,
+ * called "debloated-pom.xml", in root of the project.
+ */
+ @Parameter(property = "create.pom.debloated", defaultValue = "false")
+ private boolean createPomDebloated;
+
+ /**
+ * Add a list of dependencies, identified by their coordinates, to be ignored by DepClean during the analysis and
+ * considered as used dependencies. Useful to override incomplete result caused by bytecode-level analysis
+ * Dependency format is groupId:artifactId:version
.
+ */
+ @Parameter(property = "ignore.dependencies")
+ private Set ignoreDependencies;
+
+ /**
+ * Exclude dependencies with specific scopes from the DepClean analysis.
+ */
+ @Parameter(property = "exclude.scopes")
+ private Set excludeScope;
+
+ /**
+ * If this is true, and DepClean reported any unused dependency in the dependency tree,
+ * the build fails immediately after running DepClean.
+ */
+ @Parameter(defaultValue = "false")
+ private boolean failIfUnusedDependency;
+
+ /**
+ * Skip plugin execution completely.
+ */
+ @Parameter(defaultValue = "false")
+ private boolean skipDepClean;
+
+ @Component
+ private ProjectBuilder mavenProjectBuilder;
+
+ @Component
+ private RepositorySystem repositorySystem;
+
+ @Component(hint = "default")
+ private DependencyGraphBuilder dependencyGraphBuilder;
+
+ @Override
+ public void execute() throws MojoExecutionException, MojoFailureException
+ {
+
+ if (skipDepClean) {
+ getLog().info("Skipping DepClean plugin execution");
+ return;
+ }
+
+ System.out.println("-------------------------------------------------------");
+ getLog().info("Starting DepClean dependency analysis");
+
+ File pomFile = new File(project.getBasedir().getAbsolutePath() + "/" + "pom.xml");
+
+ String packaging = project.getPackaging();
+ if (packaging.equals("pom")) {
+ getLog().info("Skipping because packaging type " + packaging + ".");
+ return;
+ }
+
+ String pathToPutDebloatedPom = project.getBasedir().getAbsolutePath() + "/" + "pom-debloated.xml";
+
+ /* Build maven model to manipulate the pom */
+ Model model;
+ FileReader reader;
+ MavenXpp3Reader mavenReader = new MavenXpp3Reader();
+ try {
+ reader = new FileReader(pomFile);
+ model = mavenReader.read(reader);
+ model.setPomFile(pomFile);
+ } catch (Exception ex) {
+ getLog().error("Unable to build the maven project.");
+ return;
+ }
+
+ /* Copy direct dependencies locally */
+ try {
+ MavenInvoker.runCommand("mvn dependency:copy-dependencies");
+ } catch (IOException e) {
+ getLog().error("Unable resolve all the dependencies.");
+ return;
+ }
+
+ /* Decompress dependencies */
+ JarUtils.decompressJars(project.getBuild().getDirectory() + "/" + "dependency");
+
+ /* Analyze dependencies usage status */
+ ProjectDependencyAnalysis projectDependencyAnalysis;
+ try {
+ ProjectDependencyAnalyzer dependencyAnalyzer = new DefaultProjectDependencyAnalyzer();
+ projectDependencyAnalysis = dependencyAnalyzer.analyze(project);
+ } catch (ProjectDependencyAnalyzerException e) {
+ getLog().error("Unable to analyze dependencies.");
+ return;
+ }
+
+ Set usedUndeclaredArtifacts = projectDependencyAnalysis.getUsedUndeclaredArtifacts();
+ Set usedDeclaredArtifacts = projectDependencyAnalysis.getUsedDeclaredArtifacts();
+ Set unusedDeclaredArtifacts = projectDependencyAnalysis.getUnusedDeclaredArtifacts();
+ Set unusedUndeclaredArtifacts = project.getArtifacts();
+
+ unusedUndeclaredArtifacts.removeAll(usedDeclaredArtifacts);
+ unusedUndeclaredArtifacts.removeAll(usedUndeclaredArtifacts);
+ unusedUndeclaredArtifacts.removeAll(unusedDeclaredArtifacts);
+
+ /* Exclude dependencies with specific scopes from the DepClean analysis */
+ if (excludeScope.size() >= 1) {
+ usedUndeclaredArtifacts = excludeScope(usedUndeclaredArtifacts);
+ usedDeclaredArtifacts = excludeScope(usedDeclaredArtifacts);
+ unusedDeclaredArtifacts = excludeScope(unusedDeclaredArtifacts);
+ unusedUndeclaredArtifacts = excludeScope(unusedUndeclaredArtifacts);
+ }
+
+
+ /* Use artifacts coordinates for the report instead of the Artifact object */
+ Set usedDeclaredArtifactsCoordinates = new HashSet<>();
+ usedDeclaredArtifacts.forEach(s -> usedDeclaredArtifactsCoordinates.add(s.getGroupId() + ":" + s.getArtifactId() + ":" + s.getVersion() + ":" + s.getScope()));
+
+ Set usedUndeclaredArtifactsCoordinates = new HashSet<>();
+ usedUndeclaredArtifacts.forEach(s -> usedUndeclaredArtifactsCoordinates.add(s.getGroupId() + ":" + s.getArtifactId() + ":" + s.getVersion() + ":" + s.getScope()));
+
+ Set unusedDeclaredArtifactsCoordinates = new HashSet<>();
+ unusedDeclaredArtifacts.forEach(s -> unusedDeclaredArtifactsCoordinates.add(s.getGroupId() + ":" + s.getArtifactId() + ":" + s.getVersion() + ":" + s.getScope()));
+
+ Set unusedUndeclaredArtifactsCoordinates = new HashSet<>();
+ unusedUndeclaredArtifacts.forEach(s -> unusedUndeclaredArtifactsCoordinates.add(s.getGroupId() + ":" + s.getArtifactId() + ":" + s.getVersion() + ":" + s.getScope()));
+
+ /* Ignoring dependencies from analysis */
+ if (ignoreDependencies != null) {
+ for (String ignoredDependency : ignoreDependencies) {
+ // if the ignored dependency is an unused declared dependency then add it to the set of used declared
+ // and remove it from the set of unused declared
+ for (Iterator i = unusedDeclaredArtifactsCoordinates.iterator(); i.hasNext(); ) {
+ String unusedDeclaredArtifact = i.next();
+ if (ignoredDependency.equals(unusedDeclaredArtifact)) {
+ usedDeclaredArtifactsCoordinates.add(unusedDeclaredArtifact);
+ i.remove();
+ break;
+ }
+ }
+ // if the ignored dependency is an unused undeclared dependency then add it to the set of used undeclared
+ // and remove it from the set of unused undeclared
+ for (Iterator j = unusedUndeclaredArtifactsCoordinates.iterator(); j.hasNext(); ) {
+ String unusedUndeclaredArtifact = j.next();
+ if (ignoredDependency.equals(unusedUndeclaredArtifact)) {
+ usedUndeclaredArtifactsCoordinates.add(unusedUndeclaredArtifact);
+ j.remove();
+ break;
+ }
+ }
}
- // if the ignored dependency is an unused undeclared dependency then add it to the set of used undeclared
- // and remove it from the set of unused undeclared
- for (Iterator j = unusedUndeclaredArtifactsCoordinates.iterator(); j.hasNext(); ) {
- String unusedUndeclaredArtifact = j.next();
- if (ignoredDependency.equals(unusedUndeclaredArtifact)) {
- usedUndeclaredArtifactsCoordinates.add(unusedUndeclaredArtifact);
- j.remove();
- break;
- }
+ }
+
+ /* Printing the results to the console */
+ System.out.println(" D E P C L E A N A N A L Y S I S R E S U L T S");
+ System.out.println("-------------------------------------------------------");
+
+ System.out.println("Used direct dependencies" + " [" + usedDeclaredArtifactsCoordinates.size() + "]" + ": ");
+ usedDeclaredArtifactsCoordinates.stream().forEach(s -> System.out.println("\t" + s));
+
+ System.out.println("Used transitive dependencies" + " [" + usedUndeclaredArtifactsCoordinates.size() + "]" + ": ");
+ usedUndeclaredArtifactsCoordinates.stream().forEach(s -> System.out.println("\t" + s));
+
+ System.out.println("Potentially unused direct dependencies" + " [" + unusedDeclaredArtifactsCoordinates.size() + "]" + ": ");
+ unusedDeclaredArtifactsCoordinates.stream().forEach(s -> System.out.println("\t" + s));
+
+ System.out.println("Potentially unused transitive dependencies" + " [" + unusedUndeclaredArtifactsCoordinates.size() + "]" + ": ");
+ unusedUndeclaredArtifactsCoordinates.stream().forEach(s -> System.out.println("\t" + s));
+
+ if (!ignoreDependencies.isEmpty()) {
+ System.out.println("-------------------------------------------------------");
+ System.out.println("Dependencies ignored in the analysis by the user" + " [" + ignoreDependencies.size() + "]" + ": ");
+ ignoreDependencies.stream().forEach(s -> System.out.println("\t" + s));
+ }
+
+ /* Fail the build if there are unused dependencies */
+ if (failIfUnusedDependency && (unusedDeclaredArtifactsCoordinates.size() > 0 || unusedUndeclaredArtifactsCoordinates.size() > 0)) {
+ throw new MojoExecutionException("Build failed due to unused dependencies in the dependency tree.");
+ }
+
+ /* Writing the debloated version of the pom */
+ if (createPomDebloated) {
+ getLog().info("Starting debloating POM");
+
+ /* add used transitive as direct dependencies */
+ try {
+ if (!usedUndeclaredArtifacts.isEmpty()) {
+ getLog().info("Adding " + usedUndeclaredArtifacts.size() + " used transitive dependencies as direct dependencies.");
+ for (Artifact usedUndeclaredArtifact : usedUndeclaredArtifacts) {
+ model.addDependency(createDependency(usedUndeclaredArtifact));
+ }
+ }
+ } catch (Exception e) {
+ throw new MojoExecutionException(e.getMessage(), e);
}
- }
- }
-
- /* Printing the results to the console */
- System.out.println(" D E P C L E A N A N A L Y S I S R E S U L T S");
- System.out.println("-------------------------------------------------------");
-
- System.out.println("Used direct dependencies" + " [" + usedDeclaredArtifactsCoordinates.size() + "]" + ": ");
- usedDeclaredArtifactsCoordinates.stream().forEach(s -> System.out.println("\t" + s));
-
- System.out.println("Used transitive dependencies" + " [" + usedUndeclaredArtifactsCoordinates.size() + "]" + ": ");
- usedUndeclaredArtifactsCoordinates.stream().forEach(s -> System.out.println("\t" + s));
-
- System.out.println("Potentially unused direct dependencies" + " [" + unusedDeclaredArtifactsCoordinates.size() + "]" + ": ");
- unusedDeclaredArtifactsCoordinates.stream().forEach(s -> System.out.println("\t" + s));
-
- System.out.println("Potentially unused transitive dependencies" + " [" + unusedUndeclaredArtifactsCoordinates.size() + "]" + ": ");
- unusedUndeclaredArtifactsCoordinates.stream().forEach(s -> System.out.println("\t" + s));
- if (!ignoreDependencies.isEmpty()) {
- System.out.println("-------------------------------------------------------");
- System.out.println("Dependencies ignored in the analysis by the user" + " [" + ignoreDependencies.size() + "]" + ": ");
- ignoreDependencies.stream().forEach(s -> System.out.println("\t" + s));
- }
-
- /* Fail the build if there are unused dependencies */
- if (failIfUnusedDependency && (unusedDeclaredArtifactsCoordinates.size() > 0 || unusedUndeclaredArtifactsCoordinates.size() > 0)) {
- throw new MojoExecutionException("Build failed due to unused dependencies in the dependency tree.");
- }
+ /* remove unused direct dependencies */
+ try {
+ if (!unusedDeclaredArtifacts.isEmpty()) {
+ getLog().info("Removing " + unusedDeclaredArtifacts.size() + " unused direct dependencies.");
+ for (Artifact unusedDeclaredArtifact : unusedDeclaredArtifacts) {
+ for (Dependency dependency : model.getDependencies()) {
+ if (dependency.getGroupId().equals(unusedDeclaredArtifact.getGroupId()) &&
+ dependency.getArtifactId().equals(unusedDeclaredArtifact.getArtifactId())) {
+ model.removeDependency(dependency);
+ break;
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ throw new MojoExecutionException(e.getMessage(), e);
+ }
+ /* exclude unused transitive dependencies */
+ try {
+ if (!unusedUndeclaredArtifacts.isEmpty()) {
+ getLog().info("Excluding " + unusedUndeclaredArtifacts.size() + " unused transitive dependencies one-by-one.");
+ for (Dependency dependency : model.getDependencies()) {
+ for (Artifact artifact : unusedUndeclaredArtifacts) {
+ if (isChildren(artifact, dependency)) {
+ System.out.println("Excluding " + artifact.toString() + " from dependency " + dependency.toString());
+ Exclusion exclusion = new Exclusion();
+ exclusion.setGroupId(artifact.getGroupId());
+ exclusion.setArtifactId(artifact.getArtifactId());
+ dependency.addExclusion(exclusion);
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ throw new MojoExecutionException(e.getMessage(), e);
+ }
- /* Writing the debloated version of the pom */
- if (createPomDebloated) {
- getLog().info("Starting debloating POM");
- /* add used transitive as direct dependencies */
- try {
- if (!usedUndeclaredArtifacts.isEmpty()) {
- getLog().info("Adding " + usedUndeclaredArtifacts.size() + " used transitive dependencies as direct dependencies.");
- for (Artifact usedUndeclaredArtifact : usedUndeclaredArtifacts) {
- model.addDependency(createDependency(usedUndeclaredArtifact));
- }
+ /* write the debloated pom file */
+ try {
+ Path path = Paths.get(pathToPutDebloatedPom);
+ writePom(path, model);
+ } catch (IOException e) {
+ throw new MojoExecutionException(e.getMessage(), e);
}
- } catch (Exception e) {
- throw new MojoExecutionException(e.getMessage(), e);
- }
-
- /* remove unused direct dependencies */
- try {
- if (!unusedDeclaredArtifacts.isEmpty()) {
- getLog().info("Removing " + unusedDeclaredArtifacts.size() + " unused direct dependencies.");
- for (Artifact unusedDeclaredArtifact : unusedDeclaredArtifacts) {
- for (Dependency dependency : model.getDependencies()) {
- if (dependency.getGroupId().equals(unusedDeclaredArtifact.getGroupId()) &&
- dependency.getArtifactId().equals(unusedDeclaredArtifact.getArtifactId())) {
- model.removeDependency(dependency);
- break;
- }
- }
- }
- }
- } catch (Exception e) {
- throw new MojoExecutionException(e.getMessage(), e);
- }
-
- /* exclude unused transitive dependencies */
- try {
- if (!unusedUndeclaredArtifacts.isEmpty()) {
- getLog().info("Excluding " + unusedUndeclaredArtifacts.size() + " unused transitive dependencies one-by-one.");
- for (Dependency dependency : model.getDependencies()) {
- for (Artifact artifact : unusedUndeclaredArtifacts) {
- if (isChildren(artifact, dependency)) {
- System.out.println("Excluding " + artifact.toString() + " from dependency " + dependency.toString());
- Exclusion exclusion = new Exclusion();
- exclusion.setGroupId(artifact.getGroupId());
- exclusion.setArtifactId(artifact.getArtifactId());
- dependency.addExclusion(exclusion);
- }
- }
- }
- }
- } catch (Exception e) {
- throw new MojoExecutionException(e.getMessage(), e);
- }
-
-
- /* write the debloated pom file */
- try {
- Path path = Paths.get(pathToPutDebloatedPom);
- writePom(path, model);
- } catch (IOException e) {
- throw new MojoExecutionException(e.getMessage(), e);
- }
-
- getLog().info("POM debloated successfully");
- getLog().info("pom-debloated.xml file created in: " + pathToPutDebloatedPom);
- }
- }
-
- /**
- * Determine if an artifact is a direct or transitive child of a dependency.
- *
- * @param artifact The artifact.
- * @param dependency The dependency
- * @return true if the artifact is a child of a dependency in the dependency tree.
- * @throws DependencyGraphBuilderException If the graph cannot be constructed.
- */
- private boolean isChildren(Artifact artifact, Dependency dependency) throws DependencyGraphBuilderException
- {
- List dependencyNodes = getDependencyNodes();
- for (DependencyNode node : dependencyNodes) {
- Dependency dependencyNode = createDependency(node.getArtifact());
- if (dependency.getGroupId().equals(dependencyNode.getGroupId()) &&
- dependency.getArtifactId().equals(dependencyNode.getArtifactId())) {
- // now we are in the target dependency
- for (DependencyNode child : node.getChildren()) {
- if (child.getArtifact().equals(artifact)) {
- // the dependency contains the artifact as a child node
- return true;
- }
+ getLog().info("POM debloated successfully");
+ getLog().info("pom-debloated.xml file created in: " + pathToPutDebloatedPom);
+ }
+ }
+
+ private Set excludeScope(Set artifacts)
+ {
+ Set nonExcludedArtifacts = new HashSet<>();
+ Iterator iterator = artifacts.iterator();
+ while (iterator.hasNext()) {
+ Artifact artifact = iterator.next();
+ if (!excludeScope.contains(artifact.getScope())) {
+ nonExcludedArtifacts.add(artifact);
+ }
+ }
+ return nonExcludedArtifacts;
+ }
+
+ /**
+ * Determine if an artifact is a direct or transitive child of a dependency.
+ *
+ * @param artifact The artifact.
+ * @param dependency The dependency
+ * @return true if the artifact is a child of a dependency in the dependency tree.
+ * @throws DependencyGraphBuilderException If the graph cannot be constructed.
+ */
+ private boolean isChildren(Artifact artifact, Dependency dependency) throws DependencyGraphBuilderException
+ {
+ List dependencyNodes = getDependencyNodes();
+ for (DependencyNode node : dependencyNodes) {
+ Dependency dependencyNode = createDependency(node.getArtifact());
+ if (dependency.getGroupId().equals(dependencyNode.getGroupId()) &&
+ dependency.getArtifactId().equals(dependencyNode.getArtifactId())) {
+ // now we are in the target dependency
+ for (DependencyNode child : node.getChildren()) {
+ if (child.getArtifact().equals(artifact)) {
+ // the dependency contains the artifact as a child node
+ return true;
+ }
+
+ }
}
- }
- }
- return false;
- }
-
- /**
- * This method returns a list of dependency nodes from a graph of dependency tree.
- *
- * @return The nodes in the dependency graph.
- * @throws DependencyGraphBuilderException If the graph cannot be built.
- */
- private List getDependencyNodes() throws DependencyGraphBuilderException
- {
- ProjectBuildingRequest buildingRequest = new DefaultProjectBuildingRequest(session.getProjectBuildingRequest());
- buildingRequest.setProject(project);
- DependencyNode rootNode = dependencyGraphBuilder.buildDependencyGraph(buildingRequest, null);
- CollectingDependencyNodeVisitor visitor = new CollectingDependencyNodeVisitor();
- rootNode.accept(visitor);
- return visitor.getNodes();
- }
-
- /**
- * This method creates a {@link org.apache.maven.model.Dependency} object from a
- * Maven {@link org.apache.maven.artifact.Artifact}.
- *
- * @param artifact The artifact to create the dependency.
- * @return The Dependency object.
- */
- private Dependency createDependency(final Artifact artifact)
- {
- Dependency dependency = new Dependency();
- dependency.setGroupId(artifact.getGroupId());
- dependency.setArtifactId(artifact.getArtifactId());
- dependency.setVersion(artifact.getVersion());
- if (artifact.hasClassifier()) {
- dependency.setClassifier(artifact.getClassifier());
- }
- dependency.setOptional(artifact.isOptional());
- dependency.setScope(artifact.getScope());
- dependency.setType(artifact.getType());
- return dependency;
- }
-
- /**
- * Write pom file to the filesystem.
- *
- * @param pomFile The path to the pom.
- * @param model The maven model to get the pom from.
- * @throws IOException In case of any IO issue.
- */
- private static void writePom(final Path pomFile, final Model model) throws IOException
- {
- MavenXpp3Writer writer = new MavenXpp3Writer();
- writer.write(Files.newBufferedWriter(pomFile), model);
- }
+ }
+ return false;
+ }
+
+ /**
+ * This method returns a list of dependency nodes from a graph of dependency tree.
+ *
+ * @return The nodes in the dependency graph.
+ * @throws DependencyGraphBuilderException If the graph cannot be built.
+ */
+ private List getDependencyNodes() throws DependencyGraphBuilderException
+ {
+ ProjectBuildingRequest buildingRequest = new DefaultProjectBuildingRequest(session.getProjectBuildingRequest());
+ buildingRequest.setProject(project);
+ DependencyNode rootNode = dependencyGraphBuilder.buildDependencyGraph(buildingRequest, null);
+ CollectingDependencyNodeVisitor visitor = new CollectingDependencyNodeVisitor();
+ rootNode.accept(visitor);
+ return visitor.getNodes();
+ }
+
+ /**
+ * This method creates a {@link org.apache.maven.model.Dependency} object from a
+ * Maven {@link org.apache.maven.artifact.Artifact}.
+ *
+ * @param artifact The artifact to create the dependency.
+ * @return The Dependency object.
+ */
+ private Dependency createDependency(final Artifact artifact)
+ {
+ Dependency dependency = new Dependency();
+ dependency.setGroupId(artifact.getGroupId());
+ dependency.setArtifactId(artifact.getArtifactId());
+ dependency.setVersion(artifact.getVersion());
+ if (artifact.hasClassifier()) {
+ dependency.setClassifier(artifact.getClassifier());
+ }
+ dependency.setOptional(artifact.isOptional());
+ dependency.setScope(artifact.getScope());
+ dependency.setType(artifact.getType());
+ return dependency;
+ }
+
+ /**
+ * Write pom file to the filesystem.
+ *
+ * @param pomFile The path to the pom.
+ * @param model The maven model to get the pom from.
+ * @throws IOException In case of any IO issue.
+ */
+ private static void writePom(final Path pomFile, final Model model) throws IOException
+ {
+ MavenXpp3Writer writer = new MavenXpp3Writer();
+ writer.write(Files.newBufferedWriter(pomFile), model);
+ }
}
diff --git a/depclean-maven-plugin/src/main/java/se/kth/depclean/util/FileUtils.java b/depclean-maven-plugin/src/main/java/se/kth/depclean/util/FileUtils.java
index e6d09877..54e4e7a1 100644
--- a/depclean-maven-plugin/src/main/java/se/kth/depclean/util/FileUtils.java
+++ b/depclean-maven-plugin/src/main/java/se/kth/depclean/util/FileUtils.java
@@ -1,18 +1,5 @@
/*
* Copyright (c) 2020, CASTOR Software Research Centre (www.castor.kth.se)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met: 1) Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer. 2) Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution. 3) Neither the name of the Qulice.com nor
- * the names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
diff --git a/depclean-maven-plugin/src/main/java/se/kth/depclean/util/JarUtils.java b/depclean-maven-plugin/src/main/java/se/kth/depclean/util/JarUtils.java
index 46c97a75..faae72cf 100644
--- a/depclean-maven-plugin/src/main/java/se/kth/depclean/util/JarUtils.java
+++ b/depclean-maven-plugin/src/main/java/se/kth/depclean/util/JarUtils.java
@@ -1,18 +1,5 @@
/*
* Copyright (c) 2020, CASTOR Software Research Centre (www.castor.kth.se)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met: 1) Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer. 2) Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution. 3) Neither the name of the Qulice.com nor
- * the names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
diff --git a/depclean-maven-plugin/src/main/java/se/kth/depclean/util/MavenInvoker.java b/depclean-maven-plugin/src/main/java/se/kth/depclean/util/MavenInvoker.java
index a34814ea..4544bca8 100644
--- a/depclean-maven-plugin/src/main/java/se/kth/depclean/util/MavenInvoker.java
+++ b/depclean-maven-plugin/src/main/java/se/kth/depclean/util/MavenInvoker.java
@@ -1,18 +1,5 @@
/*
* Copyright (c) 2020, CASTOR Software Research Centre (www.castor.kth.se)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met: 1) Redistributions of source code must retain the above
- * copyright notice, this list of conditions and the following
- * disclaimer. 2) Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution. 3) Neither the name of the Qulice.com nor
- * the names of its contributors may be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT