From 7ddc522aa1ecca7f115c147445cda615200a0bd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Soto=20Valero?= Date: Thu, 22 Dec 2022 22:23:56 +0100 Subject: [PATCH 01/11] First code changes --- .../se/kth/depclean/core/DepCleanManager.java | 2 +- .../ProjectDependencyAnalysisBuilder.java | 54 +++++++---- .../core/analysis/graph/DependencyGraph.java | 6 +- .../model/ProjectDependencyAnalysis.java | 94 +++++++++++-------- .../depclean/core/model/ProjectContext.java | 3 +- .../core/DepCleanManagerEnd2EndTest.java | 25 +++-- .../core/analysis/ProjectContextCreator.java | 19 +++- .../ProjectDependencyAnalysisBuilderTest.java | 4 +- .../model/ProjectDependencyAnalysisTest.java | 3 + .../core/fake/FakeDependencyGraph.java | 14 ++- .../EmptyProjectDependencyManager.java | 7 +- .../depclean/graph/MavenDependencyGraph.java | 86 +++++++++++------ .../wrapper/MavenDependencyManager.java | 11 +-- .../unused_inherited_only/pom.xml | 17 +++- .../src/main/java/{ => mypackage}/Main.java | 2 + .../src/test/java/mypackage/MainTest.java | 10 ++ 16 files changed, 234 insertions(+), 123 deletions(-) rename depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/unused_inherited_only/src/main/java/{ => mypackage}/Main.java (92%) create mode 100644 depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/unused_inherited_only/src/test/java/mypackage/MainTest.java diff --git a/depclean-core/src/main/java/se/kth/depclean/core/DepCleanManager.java b/depclean-core/src/main/java/se/kth/depclean/core/DepCleanManager.java index 11b56ee4..7daed732 100644 --- a/depclean-core/src/main/java/se/kth/depclean/core/DepCleanManager.java +++ b/depclean-core/src/main/java/se/kth/depclean/core/DepCleanManager.java @@ -84,7 +84,7 @@ public ProjectDependencyAnalysis execute() throws AnalysisFailureException { } /* Fail the build if there are unused inherited dependencies */ - if (failIfUnusedInherited && analysis.hasUnusedInheritedDependencies()) { + if (failIfUnusedInherited && analysis.hasUnusedInheritedDirectDependencies()) { throw new AnalysisFailureException( "Build failed due to unused inherited dependencies in the dependency tree of the project."); } diff --git a/depclean-core/src/main/java/se/kth/depclean/core/analysis/ProjectDependencyAnalysisBuilder.java b/depclean-core/src/main/java/se/kth/depclean/core/analysis/ProjectDependencyAnalysisBuilder.java index 3a4a4af1..2a5e2bba 100644 --- a/depclean-core/src/main/java/se/kth/depclean/core/analysis/ProjectDependencyAnalysisBuilder.java +++ b/depclean-core/src/main/java/se/kth/depclean/core/analysis/ProjectDependencyAnalysisBuilder.java @@ -38,30 +38,38 @@ public class ProjectDependencyAnalysisBuilder { * @return the analysis */ public ProjectDependencyAnalysis analyse() { + // used dependencies final Set usedDirectDependencies = getUsedDirectDependencies(); final Set usedTransitiveDependencies = getUsedTransitiveDependencies(); - final Set usedInheritedDependencies = getUsedInheritedDependencies(); + final Set usedInheritedDirectDependencies = getUsedInheritedDirectDependencies(); + final Set usedInheritedTransitiveDependencies = getUsedInheritedTransitiveDependencies(); + // unused dependencies final Set unusedDirectDependencies = getUnusedDirectDependencies(usedDirectDependencies); final Set unusedTransitiveDependencies = getUnusedTransitiveDependencies(usedTransitiveDependencies); - final Set unusedInheritedDependencies = getUnusedInheritedDependencies(usedInheritedDependencies); + final Set unusedInheritedDirectDependencies = getUnusedInheritedDirectDependencies(usedInheritedDirectDependencies); + final Set unusedInheritedTransitiveDependencies = getUnusedInheritedTransitiveDependencies(usedInheritedTransitiveDependencies); + // classes in each dependency final Map dependencyClassesMap = buildDependencyClassesMap(); - + // ignore dependencies context.getIgnoredDependencies().forEach(dependencyToIgnore -> { ignoreDependency(usedDirectDependencies, unusedDirectDependencies, dependencyToIgnore); ignoreDependency(usedTransitiveDependencies, unusedTransitiveDependencies, dependencyToIgnore); - ignoreDependency(usedInheritedDependencies, unusedInheritedDependencies, dependencyToIgnore); + ignoreDependency(usedInheritedDirectDependencies, unusedInheritedDirectDependencies, dependencyToIgnore); + ignoreDependency(usedInheritedTransitiveDependencies, unusedInheritedTransitiveDependencies, dependencyToIgnore); }); - return new ProjectDependencyAnalysis( usedDirectDependencies, usedTransitiveDependencies, - usedInheritedDependencies, + usedInheritedDirectDependencies, + usedInheritedTransitiveDependencies, unusedDirectDependencies, unusedTransitiveDependencies, - unusedInheritedDependencies, + unusedInheritedDirectDependencies, + unusedInheritedTransitiveDependencies, context.getIgnoredDependencies(), dependencyClassesMap, - context.getDependencyGraph()); + context.getDependencyGraph() + ); } private Map buildDependencyClassesMap() { @@ -76,6 +84,13 @@ private Map buildDependencyClassesMap() { return output; } + private Set getUsedInheritedDirectDependencies() { + return usedDependencies.stream() + .filter(a -> context.getDependencyGraph().inheritedDirectDependencies().contains(a)) + .peek(dependency -> log.trace("## Used Inherited Direct dependency {}", dependency)) + .collect(Collectors.toSet()); + } + private Set getUsedDirectDependencies() { return usedDependencies.stream() .filter(a -> context.getDependencyGraph().directDependencies().contains(a)) @@ -90,9 +105,9 @@ private Set getUsedTransitiveDependencies() { .collect(Collectors.toSet()); } - private Set getUsedInheritedDependencies() { + private Set getUsedInheritedTransitiveDependencies() { return usedDependencies.stream() - .filter(a -> context.getDependencyGraph().inheritedDependencies().contains(a)) + .filter(a -> context.getDependencyGraph().inheritedTransitiveDependencies().contains(a)) .peek(dependency -> log.trace("## Used Transitive dependency {}", dependency)) .collect(Collectors.toSet()); } @@ -106,9 +121,14 @@ private Set getUnusedTransitiveDependencies( return getUnusedDependencies(context.getDependencyGraph().transitiveDependencies(), usedTransitiveDependencies); } - private Set getUnusedInheritedDependencies( + private Set getUnusedInheritedDirectDependencies( Set usedInheritedDependencies) { - return getUnusedDependencies(context.getDependencyGraph().inheritedDependencies(), usedInheritedDependencies); + return getUnusedDependencies(context.getDependencyGraph().inheritedDirectDependencies(), usedInheritedDependencies); + } + + private Set getUnusedInheritedTransitiveDependencies( + Set usedInheritedDependencies) { + return getUnusedDependencies(context.getDependencyGraph().inheritedTransitiveDependencies(), usedInheritedDependencies); } private Set getUnusedDependencies( @@ -119,18 +139,14 @@ private Set getUnusedDependencies( } /** - * If the dependencyToIgnore is an unused dependency, then add it to the set of - * usedDependencyCoordinates and remove it from the set of unusedDependencyCoordinates. + * If the dependency to ignore is an unused dependency, then add it to the set of usedDependencyCoordinates + * and remove it from the set of unusedDependencyCoordinates. * * @param usedDependencies The set of used artifacts where the dependency will be added. * @param unusedDependencies The set of unused artifacts where the dependency will be removed. * @param dependencyToIgnore The dependency to ignore. */ - private void ignoreDependency( - Set usedDependencies, - Set unusedDependencies, - Dependency dependencyToIgnore) { - + private void ignoreDependency(Set usedDependencies, Set unusedDependencies, Dependency dependencyToIgnore) { for (Iterator i = unusedDependencies.iterator(); i.hasNext(); ) { Dependency unusedDependency = i.next(); if (dependencyToIgnore.equals(unusedDependency)) { diff --git a/depclean-core/src/main/java/se/kth/depclean/core/analysis/graph/DependencyGraph.java b/depclean-core/src/main/java/se/kth/depclean/core/analysis/graph/DependencyGraph.java index 1378ca98..6d97e73e 100644 --- a/depclean-core/src/main/java/se/kth/depclean/core/analysis/graph/DependencyGraph.java +++ b/depclean-core/src/main/java/se/kth/depclean/core/analysis/graph/DependencyGraph.java @@ -12,10 +12,12 @@ public interface DependencyGraph { Set directDependencies(); - Set inheritedDependencies(); - Set transitiveDependencies(); + Set inheritedDirectDependencies(); + + Set inheritedTransitiveDependencies(); + Set allDependencies(); Set getDependenciesForParent(Dependency parent); diff --git a/depclean-core/src/main/java/se/kth/depclean/core/analysis/model/ProjectDependencyAnalysis.java b/depclean-core/src/main/java/se/kth/depclean/core/analysis/model/ProjectDependencyAnalysis.java index 9d9f288f..17c4c551 100644 --- a/depclean-core/src/main/java/se/kth/depclean/core/analysis/model/ProjectDependencyAnalysis.java +++ b/depclean-core/src/main/java/se/kth/depclean/core/analysis/model/ProjectDependencyAnalysis.java @@ -45,46 +45,44 @@ @EqualsAndHashCode @Slf4j public class ProjectDependencyAnalysis { + private static final String SEPARATOR = "-------------------------------------------------------"; private final Set usedDirectDependencies; private final Set usedTransitiveDependencies; - private final Set usedInheritedDependencies; + private final Set usedInheritedDirectDependencies; + private final Set usedInheritedTransitiveDependencies; private final Set unusedDirectDependencies; private final Set unusedTransitiveDependencies; - private final Set unusedInheritedDependencies; + private final Set unusedInheritedDirectDependencies; + private final Set unusedInheritedTransitiveDependencies; private final Set ignoredDependencies; private final Map dependencyClassesMap; private final DependencyGraph dependencyGraph; /** - * The analysis result. - * - * @param usedDirectDependencies used direct dependencies - * @param usedTransitiveDependencies used transitive dependencies - * @param usedInheritedDependencies used inherited dependencies - * @param unusedDirectDependencies unused direct dependencies - * @param unusedTransitiveDependencies unused transitive dependencies - * @param unusedInheritedDependencies unused inherited dependencies - * @param ignoredDependencies ignored dependencies - * @param dependencyClassesMap the whole dependencies and their relates classes and used classes + * Creates a project dependency analysis result. */ public ProjectDependencyAnalysis( Set usedDirectDependencies, Set usedTransitiveDependencies, - Set usedInheritedDependencies, + Set usedInheritedDirectDependencies, + Set usedInheritedTransitiveDependencies, Set unusedDirectDependencies, Set unusedTransitiveDependencies, - Set unusedInheritedDependencies, + Set unusedInheritedDirectDependencies, + Set unusedInheritedTransitiveDependencies, Set ignoredDependencies, Map dependencyClassesMap, DependencyGraph dependencyGraph) { this.usedDirectDependencies = copyOf(usedDirectDependencies); this.usedTransitiveDependencies = copyOf(usedTransitiveDependencies); - this.usedInheritedDependencies = copyOf(usedInheritedDependencies); + this.usedInheritedDirectDependencies = copyOf(usedInheritedDirectDependencies); + this.usedInheritedTransitiveDependencies = copyOf(usedInheritedTransitiveDependencies); this.unusedDirectDependencies = copyOf(unusedDirectDependencies); this.unusedTransitiveDependencies = copyOf(unusedTransitiveDependencies); - this.unusedInheritedDependencies = copyOf(unusedInheritedDependencies); + this.unusedInheritedDirectDependencies = copyOf(unusedInheritedDirectDependencies); + this.unusedInheritedTransitiveDependencies = copyOf(unusedInheritedTransitiveDependencies); this.ignoredDependencies = copyOf(ignoredDependencies); this.dependencyClassesMap = dependencyClassesMap; this.dependencyGraph = dependencyGraph; @@ -102,8 +100,12 @@ public boolean hasUnusedTransitiveDependencies() { return !unusedTransitiveDependencies.isEmpty(); } - public boolean hasUnusedInheritedDependencies() { - return !unusedInheritedDependencies.isEmpty(); + public boolean hasUnusedInheritedDirectDependencies() { + return !unusedInheritedDirectDependencies.isEmpty(); + } + + public boolean hasUnusedInheritedTransitiveDependencies() { + return !unusedInheritedDirectDependencies.isEmpty(); } /** @@ -114,11 +116,13 @@ public void print() { printString(" D E P C L E A N A N A L Y S I S R E S U L T S"); printString(SEPARATOR); printInfoOfDependencies("Used direct dependencies", getUsedDirectDependencies()); - printInfoOfDependencies("Used inherited dependencies", getUsedInheritedDependencies()); printInfoOfDependencies("Used transitive dependencies", getUsedTransitiveDependencies()); + printInfoOfDependencies("Used inherited direct dependencies", getUsedInheritedDirectDependencies()); + printInfoOfDependencies("Used inherited transitive dependencies", getUsedInheritedTransitiveDependencies()); printInfoOfDependencies("Potentially unused direct dependencies", getUnusedDirectDependencies()); - printInfoOfDependencies("Potentially unused inherited dependencies", getUnusedInheritedDependencies()); printInfoOfDependencies("Potentially unused transitive dependencies", getUnusedTransitiveDependencies()); + printInfoOfDependencies("Potentially unused inherited direct dependencies", getUnusedInheritedDirectDependencies()); + printInfoOfDependencies("Potentially unused inherited transitive dependencies", getUnusedInheritedTransitiveDependencies()); if (!ignoredDependencies.isEmpty()) { printString(SEPARATOR); @@ -158,7 +162,7 @@ public DependencyAnalysisInfo getDependencyInfo(String coordinate) { */ public Set getUsedDependencies() { final Set dependencies = new HashSet<>(getUsedDirectDependencies()); - dependencies.addAll(getUsedInheritedDependencies()); + dependencies.addAll(getUsedInheritedDirectDependencies()); dependencies.addAll(getUsedTransitiveDependencies()); return dependencies.stream() .map(this::toDebloatedDependency) @@ -172,7 +176,8 @@ public Set getUsedDependencies() { */ public Set getUnusedDependencies() { final Set dependencies = new HashSet<>(getUnusedDirectDependencies()); - dependencies.addAll(getUnusedInheritedDependencies()); + dependencies.addAll(getUnusedInheritedDirectDependencies()); + dependencies.addAll(getUnusedInheritedTransitiveDependencies()); dependencies.addAll(getUnusedTransitiveDependencies()); return dependencies.stream() .map(this::toDebloatedDependency) @@ -193,21 +198,36 @@ private TreeSet toValue(Set types) { } private String getStatus(Dependency coordinates) { - return (usedDirectDependencies.contains(coordinates) || usedInheritedDependencies - .contains(coordinates) || usedTransitiveDependencies.contains(coordinates)) - ? "used" : - (unusedDirectDependencies.contains(coordinates) || unusedInheritedDependencies - .contains(coordinates) || unusedTransitiveDependencies.contains(coordinates)) - ? "bloated" : "unknown"; + if (usedDirectDependencies.contains(coordinates) + || usedInheritedDirectDependencies.contains(coordinates) + || usedInheritedTransitiveDependencies.contains(coordinates) + || usedTransitiveDependencies.contains(coordinates)) { + return "used"; + } else { + return (unusedDirectDependencies.contains(coordinates) + || unusedInheritedDirectDependencies.contains(coordinates) + || unusedInheritedTransitiveDependencies.contains(coordinates) + || unusedTransitiveDependencies.contains(coordinates)) + ? "bloated" : "unknown"; + } + } private String getType(Dependency coordinates) { - return (usedDirectDependencies.contains(coordinates) || unusedDirectDependencies - .contains(coordinates)) ? "direct" : - (usedInheritedDependencies.contains(coordinates) || unusedInheritedDependencies - .contains(coordinates)) ? "inherited" : - (usedTransitiveDependencies.contains(coordinates) || unusedTransitiveDependencies - .contains(coordinates)) ? "transitive" : "unknown"; + if (usedDirectDependencies.contains(coordinates) + || unusedDirectDependencies.contains(coordinates)) { + return "direct"; + } else if ((usedInheritedDirectDependencies.contains(coordinates) + || usedInheritedTransitiveDependencies.contains(coordinates) + || unusedInheritedDirectDependencies.contains(coordinates) + || unusedInheritedTransitiveDependencies.contains(coordinates))) { + return "inherited"; + } else { + return (usedTransitiveDependencies.contains(coordinates) + || unusedTransitiveDependencies + .contains(coordinates)) + ? "transitive" : "unknown"; + } } private void printString(final String string) { @@ -217,8 +237,8 @@ private void printString(final String string) { /** * Util function to print the information of the analyzed artifacts. * - * @param info The usage status (used or unused) and type (direct, transitive, inherited) of artifacts. - * @param dependencies The GAV of the artifact. + * @param info The usage status (used or unused) and type (direct, transitive, inherited) of artifacts. + * @param dependencies The GAV of the artifact. */ private void printInfoOfDependencies(final String info, final Set dependencies) { printString(info.toUpperCase() + " [" + dependencies.size() + "]" + ": "); @@ -228,7 +248,7 @@ private void printInfoOfDependencies(final String info, final Set de /** * Print the status of the dependencies to the standard output. The format is: "[coordinates][scope] [(size)]" * - * @param dependencies The set dependencies to print. + * @param dependencies The set dependencies to print. */ private void printDependencies(final Set dependencies) { dependencies diff --git a/depclean-core/src/main/java/se/kth/depclean/core/model/ProjectContext.java b/depclean-core/src/main/java/se/kth/depclean/core/model/ProjectContext.java index 78096583..577c6305 100644 --- a/depclean-core/src/main/java/se/kth/depclean/core/model/ProjectContext.java +++ b/depclean-core/src/main/java/se/kth/depclean/core/model/ProjectContext.java @@ -82,8 +82,9 @@ public ProjectContext(DependencyGraph dependencyGraph, ignoredScopes.forEach(scope -> log.info("Ignoring scope {}", scope)); populateDependenciesAndClassesMap(dependencyGraph.directDependencies()); - populateDependenciesAndClassesMap(dependencyGraph.inheritedDependencies()); populateDependenciesAndClassesMap(dependencyGraph.transitiveDependencies()); + populateDependenciesAndClassesMap(dependencyGraph.inheritedDirectDependencies()); + populateDependenciesAndClassesMap(dependencyGraph.inheritedTransitiveDependencies()); Multimaps.invertFrom(classesPerDependency, dependenciesPerClass); } diff --git a/depclean-core/src/test/java/se/kth/depclean/core/DepCleanManagerEnd2EndTest.java b/depclean-core/src/test/java/se/kth/depclean/core/DepCleanManagerEnd2EndTest.java index 29bff525..3e412d55 100644 --- a/depclean-core/src/test/java/se/kth/depclean/core/DepCleanManagerEnd2EndTest.java +++ b/depclean-core/src/test/java/se/kth/depclean/core/DepCleanManagerEnd2EndTest.java @@ -80,10 +80,11 @@ void shouldPassForEmptyProject() throws AnalysisFailureException { final ProjectDependencyAnalysis analysis = depCleanManager.execute(); assertThat(analysis.getUsedDirectDependencies()).isEmpty(); - assertThat(analysis.getUsedInheritedDependencies()).isEmpty(); + assertThat(analysis.getUsedInheritedDirectDependencies()).isEmpty(); assertThat(analysis.getUsedTransitiveDependencies()).isEmpty(); assertThat(analysis.getUnusedDirectDependencies()).isEmpty(); - assertThat(analysis.getUnusedInheritedDependencies()).isEmpty(); + assertThat(analysis.getUnusedInheritedDirectDependencies()).isEmpty(); + assertThat(analysis.getUnusedInheritedTransitiveDependencies()).isEmpty(); assertThat(analysis.getUnusedTransitiveDependencies()).isEmpty(); } @@ -95,10 +96,11 @@ void shouldReportAllDependencyUsed() throws AnalysisFailureException { final ProjectDependencyAnalysis analysis = depCleanManager.execute(); assertThat(analysis.getUsedDirectDependencies()).hasSize(1); - assertThat(analysis.getUsedInheritedDependencies()).hasSize(1); + assertThat(analysis.getUsedInheritedDirectDependencies()).hasSize(1); assertThat(analysis.getUsedTransitiveDependencies()).hasSize(1); assertThat(analysis.getUnusedDirectDependencies()).isEmpty(); - assertThat(analysis.getUnusedInheritedDependencies()).isEmpty(); + assertThat(analysis.getUnusedInheritedDirectDependencies()).isEmpty(); + assertThat(analysis.getUnusedInheritedTransitiveDependencies()).isEmpty(); assertThat(analysis.getUnusedTransitiveDependencies()).isEmpty(); } @@ -110,10 +112,11 @@ void shouldReportNoDependencyUsed() throws AnalysisFailureException { final ProjectDependencyAnalysis analysis = depCleanManager.execute(); assertThat(analysis.getUsedDirectDependencies()).isEmpty(); - assertThat(analysis.getUsedInheritedDependencies()).isEmpty(); + assertThat(analysis.getUsedInheritedDirectDependencies()).isEmpty(); assertThat(analysis.getUsedTransitiveDependencies()).isEmpty(); assertThat(analysis.getUnusedDirectDependencies()).hasSize(1); - assertThat(analysis.getUnusedInheritedDependencies()).hasSize(1); + assertThat(analysis.getUnusedInheritedDirectDependencies()).hasSize(1); + assertThat(analysis.getUnusedInheritedTransitiveDependencies()).hasSize(1); assertThat(analysis.getUnusedTransitiveDependencies()).hasSize(1); } @@ -125,10 +128,11 @@ void shouldReportOnlyDirectAndInheritedDependenciesUsed() throws AnalysisFailure final ProjectDependencyAnalysis analysis = depCleanManager.execute(); assertThat(analysis.getUsedDirectDependencies()).hasSize(1); - assertThat(analysis.getUsedInheritedDependencies()).hasSize(1); + assertThat(analysis.getUsedInheritedDirectDependencies()).hasSize(1); assertThat(analysis.getUsedTransitiveDependencies()).isEmpty(); assertThat(analysis.getUnusedDirectDependencies()).isEmpty(); - assertThat(analysis.getUnusedInheritedDependencies()).isEmpty(); + assertThat(analysis.getUnusedInheritedDirectDependencies()).isEmpty(); + assertThat(analysis.getUnusedInheritedTransitiveDependencies()).isEmpty(); assertThat(analysis.getUnusedTransitiveDependencies()).hasSize(1); } @@ -140,10 +144,11 @@ void shouldReportOnlyDirectDependencyUsed() throws AnalysisFailureException { final ProjectDependencyAnalysis analysis = depCleanManager.execute(); assertThat(analysis.getUsedDirectDependencies()).hasSize(1); - assertThat(analysis.getUsedInheritedDependencies()).isEmpty(); + assertThat(analysis.getUsedInheritedDirectDependencies()).isEmpty(); assertThat(analysis.getUsedTransitiveDependencies()).isEmpty(); assertThat(analysis.getUnusedDirectDependencies()).isEmpty(); - assertThat(analysis.getUnusedInheritedDependencies()).hasSize(1); + assertThat(analysis.getUnusedInheritedDirectDependencies()).hasSize(1); + assertThat(analysis.getUnusedInheritedTransitiveDependencies()).hasSize(1); assertThat(analysis.getUnusedTransitiveDependencies()).hasSize(1); } diff --git a/depclean-core/src/test/java/se/kth/depclean/core/analysis/ProjectContextCreator.java b/depclean-core/src/test/java/se/kth/depclean/core/analysis/ProjectContextCreator.java index 37d4edad..85e2dda7 100644 --- a/depclean-core/src/test/java/se/kth/depclean/core/analysis/ProjectContextCreator.java +++ b/depclean-core/src/test/java/se/kth/depclean/core/analysis/ProjectContextCreator.java @@ -23,6 +23,7 @@ public interface ProjectContextCreator { ClassName JUNIT_CLASS = new ClassName("org.junit.jupiter.engine.JupiterTestEngine"); ClassName UNKNOWN_CLASS = new ClassName("com.unknown.Unknown"); Dependency COMMONS_IO_DEPENDENCY = createDependency("commons-io"); + Dependency COMMONS_MATH_DEPENDENCY = createDependency("commons-math"); Dependency COMMONS_LANG_DEPENDENCY = createDependency("commons-lang3"); Dependency COMMONS_LOGGING_DEPENDENCY = createDependency("commons-logging-api"); Dependency JUNIT_DEPENDENCY = createTestDependency("junit-jupiter"); @@ -34,6 +35,7 @@ default ProjectContext createContext() { createDependency("ExampleClass"), of(COMMONS_IO_DEPENDENCY, JUNIT_DEPENDENCY), of(COMMONS_LANG_DEPENDENCY), + of(COMMONS_MATH_DEPENDENCY), of(COMMONS_LOGGING_DEPENDENCY) ), of(Paths.get("target/classes")), @@ -53,6 +55,7 @@ default ProjectContext createContextIgnoringTests() { createDependency("ExampleClass"), of(COMMONS_IO_DEPENDENCY, JUNIT_DEPENDENCY), of(COMMONS_LANG_DEPENDENCY), + of(COMMONS_MATH_DEPENDENCY), of(COMMONS_LOGGING_DEPENDENCY) ), of(Paths.get("target/classes")), @@ -72,6 +75,7 @@ default ProjectContext createContextIgnoringDependency() { createDependency("ExampleClass"), of(COMMONS_IO_DEPENDENCY), of(COMMONS_LANG_DEPENDENCY), + of(COMMONS_MATH_DEPENDENCY), of(COMMONS_LOGGING_DEPENDENCY) ), of(Paths.get("target/classes")), @@ -112,7 +116,8 @@ class TestDependencyGraph implements DependencyGraph { private final Dependency projectCoordinates; private final Set directDependencies; - private final Set inheritedDependencies; + private final Set inheritedDirectDependencies; + private final Set inheritedTransitiveDependencies; private final Set transitiveDependencies; @Override @@ -126,8 +131,13 @@ public Set directDependencies() { } @Override - public Set inheritedDependencies() { - return inheritedDependencies; + public Set inheritedDirectDependencies() { + return inheritedDirectDependencies; + } + + @Override + public Set inheritedTransitiveDependencies() { + return inheritedTransitiveDependencies; } @Override @@ -138,7 +148,8 @@ public Set transitiveDependencies() { @Override public Set allDependencies() { final Set dependencies = newHashSet(directDependencies); - dependencies.addAll(inheritedDependencies); + dependencies.addAll(inheritedDirectDependencies); + dependencies.addAll(inheritedTransitiveDependencies); dependencies.addAll(transitiveDependencies); return copyOf(dependencies); } diff --git a/depclean-core/src/test/java/se/kth/depclean/core/analysis/ProjectDependencyAnalysisBuilderTest.java b/depclean-core/src/test/java/se/kth/depclean/core/analysis/ProjectDependencyAnalysisBuilderTest.java index 2bc0045b..938f7ad3 100644 --- a/depclean-core/src/test/java/se/kth/depclean/core/analysis/ProjectDependencyAnalysisBuilderTest.java +++ b/depclean-core/src/test/java/se/kth/depclean/core/analysis/ProjectDependencyAnalysisBuilderTest.java @@ -28,7 +28,7 @@ void shouldFindUsedInheritedDependencies() { final ProjectDependencyAnalysisBuilder analysisBuilder = new ProjectDependencyAnalysisBuilder(context, actualUsedClasses); - assertThat(analysisBuilder.analyse().getUsedInheritedDependencies()) + assertThat(analysisBuilder.analyse().getUsedInheritedDirectDependencies()) .containsExactlyInAnyOrder(COMMONS_LANG_DEPENDENCY); } @@ -73,7 +73,7 @@ void shouldFindUnusedInheritedDependencies() { final ProjectDependencyAnalysisBuilder analysisBuilder = new ProjectDependencyAnalysisBuilder(context, actualUsedClasses); - assertThat(analysisBuilder.analyse().getUnusedInheritedDependencies()) + assertThat(analysisBuilder.analyse().getUnusedInheritedDirectDependencies()) .containsExactlyInAnyOrder(COMMONS_LANG_DEPENDENCY); } diff --git a/depclean-core/src/test/java/se/kth/depclean/core/analysis/model/ProjectDependencyAnalysisTest.java b/depclean-core/src/test/java/se/kth/depclean/core/analysis/model/ProjectDependencyAnalysisTest.java index 46d8d0b4..ca4b2739 100644 --- a/depclean-core/src/test/java/se/kth/depclean/core/analysis/model/ProjectDependencyAnalysisTest.java +++ b/depclean-core/src/test/java/se/kth/depclean/core/analysis/model/ProjectDependencyAnalysisTest.java @@ -17,6 +17,8 @@ void shouldBuildResultingDependencyGraph() { of(JUNIT_DEPENDENCY), of(), of(COMMONS_LANG_DEPENDENCY), + of(COMMONS_MATH_DEPENDENCY), + of(COMMONS_IO_DEPENDENCY), of(COMMONS_LOGGING_DEPENDENCY), of(), of(), @@ -25,6 +27,7 @@ void shouldBuildResultingDependencyGraph() { createDependency("ExampleClass"), of(COMMONS_IO_DEPENDENCY), of(COMMONS_LANG_DEPENDENCY), + of(COMMONS_MATH_DEPENDENCY), of(JUNIT_DEPENDENCY, COMMONS_LOGGING_DEPENDENCY) ) ); diff --git a/depclean-core/src/test/java/se/kth/depclean/core/fake/FakeDependencyGraph.java b/depclean-core/src/test/java/se/kth/depclean/core/fake/FakeDependencyGraph.java index 81a86501..77bb4c92 100644 --- a/depclean-core/src/test/java/se/kth/depclean/core/fake/FakeDependencyGraph.java +++ b/depclean-core/src/test/java/se/kth/depclean/core/fake/FakeDependencyGraph.java @@ -23,8 +23,9 @@ public Dependency projectCoordinates() { public Set allDependencies() { return ImmutableSet.builder() .addAll(directDependencies()) - .addAll(inheritedDependencies()) .addAll(transitiveDependencies()) + .addAll(inheritedDirectDependencies()) + .addAll(inheritedTransitiveDependencies()) .build(); } @@ -34,13 +35,18 @@ public Set directDependencies() { } @Override - public Set inheritedDependencies() { + public Set transitiveDependencies() { + return of(COMMONS_LOGGING_DEPENDENCY); + } + + @Override + public Set inheritedDirectDependencies() { return of(COMMONS_LANG_DEPENDENCY); } @Override - public Set transitiveDependencies() { - return of(COMMONS_LOGGING_DEPENDENCY); + public Set inheritedTransitiveDependencies() { + return of(COMMONS_LANG_DEPENDENCY); } @Override diff --git a/depclean-core/src/test/java/se/kth/depclean/core/fake/depmanager/EmptyProjectDependencyManager.java b/depclean-core/src/test/java/se/kth/depclean/core/fake/depmanager/EmptyProjectDependencyManager.java index 9cc7fb28..e1deac02 100644 --- a/depclean-core/src/test/java/se/kth/depclean/core/fake/depmanager/EmptyProjectDependencyManager.java +++ b/depclean-core/src/test/java/se/kth/depclean/core/fake/depmanager/EmptyProjectDependencyManager.java @@ -20,7 +20,12 @@ public Set directDependencies() { } @Override - public Set inheritedDependencies() { + public Set inheritedDirectDependencies() { + return of(); + } + + @Override + public Set inheritedTransitiveDependencies() { return of(); } diff --git a/depclean-maven-plugin/src/main/java/se/kth/depclean/graph/MavenDependencyGraph.java b/depclean-maven-plugin/src/main/java/se/kth/depclean/graph/MavenDependencyGraph.java index 9ebfb839..68343386 100644 --- a/depclean-maven-plugin/src/main/java/se/kth/depclean/graph/MavenDependencyGraph.java +++ b/depclean-maven-plugin/src/main/java/se/kth/depclean/graph/MavenDependencyGraph.java @@ -5,6 +5,7 @@ import static com.google.common.collect.Sets.newHashSet; import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.ImmutableSet; import com.google.common.collect.Multimap; import java.io.File; import java.util.Set; @@ -25,12 +26,12 @@ public class MavenDependencyGraph implements DependencyGraph { private final Set allDependencies; - private final MavenProject project; private final DependencyNode rootNode; private final Set directDependencies; - private final Set inheritedDependencies; private final Set transitiveDependencies; + private final Set inheritedDirectDependencies; + private final Set inheritedTransitiveDependencies; private final Multimap dependenciesPerDependency = ArrayListMultimap.create(); /** @@ -42,21 +43,16 @@ public class MavenDependencyGraph implements DependencyGraph { public MavenDependencyGraph(MavenProject project, Model model, DependencyNode rootNode) { this.project = project; this.rootNode = rootNode; - - this.allDependencies = project.getArtifacts().stream() - .map(this::toDepCleanDependency) - .collect(toImmutableSet()); + buildDependencyDependencies(rootNode); + this.allDependencies = getAllDependencies(project); // The model gets only the direct dependencies (not the inherited ones) - this.directDependencies = model.getDependencies().stream() - .map(this::toDepCleanDependency) - .collect(toImmutableSet()); + this.directDependencies = getDirectDependencies(model); // The project gets all the direct dependencies (with the inherited ones) //noinspection deprecation - this.inheritedDependencies = inheritedDependencies(project.getDependencyArtifacts()); + this.inheritedDirectDependencies = inheritedDirectDependencies(project.getDependencyArtifacts()); + this.inheritedTransitiveDependencies = inheritedTransitiveDependencies(inheritedDirectDependencies); this.transitiveDependencies = transitiveDependencies(allDependencies); - - buildDependencyDependencies(rootNode); - + // Logs if (log.isDebugEnabled()) { this.allDependencies.forEach(dep -> { log.debug("Found dependency {}", dep); @@ -84,27 +80,31 @@ public Dependency projectCoordinates() { } @Override - public Set allDependencies() { - return allDependencies; + public Set directDependencies() { + return directDependencies; } @Override - public Set getDependenciesForParent(Dependency parent) { - return copyOf(dependenciesPerDependency.get(parent)); + public Set transitiveDependencies() { + return transitiveDependencies; } - @Override - public Set directDependencies() { - return directDependencies; + @NotNull + private Set transitiveDependencies(Set allDependencies) { + Set allTransitiveDependencies = newHashSet(allDependencies); + allTransitiveDependencies.removeAll(this.directDependencies); + allTransitiveDependencies.removeAll(this.inheritedDirectDependencies); + allTransitiveDependencies.removeAll(this.inheritedTransitiveDependencies); + return copyOf(allTransitiveDependencies); } @Override - public Set inheritedDependencies() { - return inheritedDependencies; + public Set inheritedDirectDependencies() { + return inheritedDirectDependencies; } @NotNull - private Set inheritedDependencies(Set dependencyArtifacts) { + private Set inheritedDirectDependencies(Set dependencyArtifacts) { final Set visibleDependencies = dependencyArtifacts.stream() .map(this::toDepCleanDependency) .collect(Collectors.toSet()); @@ -113,16 +113,30 @@ private Set inheritedDependencies(Set dependencyArtifacts) } @Override - public Set transitiveDependencies() { - return transitiveDependencies; + public Set inheritedTransitiveDependencies() { + return inheritedTransitiveDependencies; } @NotNull - private Set transitiveDependencies(Set allArtifactsFound) { - final Set transitiveDependencies = newHashSet(allArtifactsFound); - transitiveDependencies.removeAll(this.directDependencies); - transitiveDependencies.removeAll(this.inheritedDependencies); - return copyOf(transitiveDependencies); + private Set inheritedTransitiveDependencies(Set inheritedDirectDependencies) { + Set allInheritedTransitiveDependencies = newHashSet(); + dependenciesPerDependency.forEach((key, value) -> { + if (inheritedDirectDependencies.contains(key)) { + allInheritedTransitiveDependencies.add(value); + } + } + ); + return copyOf(allInheritedTransitiveDependencies); + } + + @Override + public Set getDependenciesForParent(Dependency parent) { + return copyOf(dependenciesPerDependency.get(parent)); + } + + @Override + public Set allDependencies() { + return allDependencies; } private void buildDependencyDependencies(DependencyNode parentNode) { @@ -161,4 +175,16 @@ private boolean matches(Dependency dependencyCoordinate, org.apache.maven.model. return dependencyCoordinate.getGroupId().equalsIgnoreCase(dependency.getGroupId()) && dependencyCoordinate.getDependencyId().equalsIgnoreCase(dependency.getArtifactId()); } + + private ImmutableSet getAllDependencies(MavenProject project) { + return project.getArtifacts().stream() + .map(this::toDepCleanDependency) + .collect(toImmutableSet()); + } + + private ImmutableSet getDirectDependencies(Model model) { + return model.getDependencies().stream() + .map(this::toDepCleanDependency) + .collect(toImmutableSet()); + } } diff --git a/depclean-maven-plugin/src/main/java/se/kth/depclean/wrapper/MavenDependencyManager.java b/depclean-maven-plugin/src/main/java/se/kth/depclean/wrapper/MavenDependencyManager.java index ffa7880c..162333cc 100644 --- a/depclean-maven-plugin/src/main/java/se/kth/depclean/wrapper/MavenDependencyManager.java +++ b/depclean-maven-plugin/src/main/java/se/kth/depclean/wrapper/MavenDependencyManager.java @@ -100,8 +100,7 @@ public boolean isPackagingPom() { @Override @SneakyThrows public DependencyGraph dependencyGraph() { - ProjectBuildingRequest buildingRequest = new DefaultProjectBuildingRequest( - session.getProjectBuildingRequest()); + ProjectBuildingRequest buildingRequest = new DefaultProjectBuildingRequest(session.getProjectBuildingRequest()); buildingRequest.setProject(project); DependencyNode rootNode = dependencyGraphBuilder.buildDependencyGraph(buildingRequest, null); return new MavenDependencyGraph(project, model, rootNode); @@ -109,16 +108,12 @@ public DependencyGraph dependencyGraph() { @Override public Set getOutputDirectories() { - return of( - Paths.get(project.getBuild().getOutputDirectory()) - ); + return Set.of(Paths.get(project.getBuild().getOutputDirectory())); } @Override public Set getTestOutputDirectories() { - return of( - Paths.get(project.getBuild().getTestOutputDirectory()) - ); + return Set.of(Paths.get(project.getBuild().getTestOutputDirectory())); } private Model buildModel(MavenProject project) { diff --git a/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/unused_inherited_only/pom.xml b/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/unused_inherited_only/pom.xml index 323c77b0..5f7aafd6 100644 --- a/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/unused_inherited_only/pom.xml +++ b/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/unused_inherited_only/pom.xml @@ -3,6 +3,12 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 + + org.apache.commons + commons-math-parent + 4.0-beta1 + + org.foo.bar foobar 1.0.0-SNAPSHOT @@ -49,13 +55,16 @@ depclean - - - - + + org.apache.rat + apache-rat-plugin + + true + + diff --git a/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/unused_inherited_only/src/main/java/Main.java b/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/unused_inherited_only/src/main/java/mypackage/Main.java similarity index 92% rename from depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/unused_inherited_only/src/main/java/Main.java rename to depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/unused_inherited_only/src/main/java/mypackage/Main.java index 9105e3c6..499e55b9 100644 --- a/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/unused_inherited_only/src/main/java/Main.java +++ b/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/unused_inherited_only/src/main/java/mypackage/Main.java @@ -1,3 +1,4 @@ +package mypackage; // import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.core.util.Separators; @@ -6,4 +7,5 @@ public class Main { // private static final ObjectMapper converter = new ObjectMapper(); Separators separators = new Separators(); int field = 42; + } \ No newline at end of file diff --git a/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/unused_inherited_only/src/test/java/mypackage/MainTest.java b/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/unused_inherited_only/src/test/java/mypackage/MainTest.java new file mode 100644 index 00000000..d4c0209b --- /dev/null +++ b/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/unused_inherited_only/src/test/java/mypackage/MainTest.java @@ -0,0 +1,10 @@ +package mypackage; + +import org.junit.jupiter.api.Test; + +class MainTest { + + @Test + void sampleTest() { + } +} \ No newline at end of file From 5231d3ef5ccd1eafbf78476cf41c4e1ff59653fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Soto=20Valero?= Date: Fri, 23 Dec 2022 10:32:49 +0100 Subject: [PATCH 02/11] Fix bug with recursive tree navigation --- .../depclean/graph/MavenDependencyGraph.java | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/depclean-maven-plugin/src/main/java/se/kth/depclean/graph/MavenDependencyGraph.java b/depclean-maven-plugin/src/main/java/se/kth/depclean/graph/MavenDependencyGraph.java index 68343386..c848c2b0 100644 --- a/depclean-maven-plugin/src/main/java/se/kth/depclean/graph/MavenDependencyGraph.java +++ b/depclean-maven-plugin/src/main/java/se/kth/depclean/graph/MavenDependencyGraph.java @@ -44,6 +44,13 @@ public MavenDependencyGraph(MavenProject project, Model model, DependencyNode ro this.project = project; this.rootNode = rootNode; buildDependencyDependencies(rootNode); + + System.out.println("dependenciesPerDependency = " + dependenciesPerDependency); + + System.out.println("rootNode = " + rootNode); + System.out.println("Dependencies per dependency"); + dependenciesPerDependency.forEach((key, value) -> System.out.println(key + " -> " + value)); + this.allDependencies = getAllDependencies(project); // The model gets only the direct dependencies (not the inherited ones) this.directDependencies = getDirectDependencies(model); @@ -140,14 +147,10 @@ public Set allDependencies() { } private void buildDependencyDependencies(DependencyNode parentNode) { - for (DependencyNode child : parentNode.getChildren()) { - if (!child.getChildren().isEmpty()) { - child.getChildren().forEach(c -> { - dependenciesPerDependency.put(toDepCleanDependency(child), toDepCleanDependency(c)); - buildDependencyDependencies(c); - }); - } - } + parentNode.getChildren().forEach(childNode -> { + dependenciesPerDependency.put(toDepCleanDependency(parentNode.getArtifact()), toDepCleanDependency(childNode.getArtifact())); + buildDependencyDependencies(childNode); + }); } private Dependency toDepCleanDependency(Artifact artifact) { @@ -156,7 +159,8 @@ private Dependency toDepCleanDependency(Artifact artifact) { artifact.getArtifactId(), artifact.getVersion(), artifact.getScope(), - artifact.getFile()); + artifact.getFile() + ); } private Dependency toDepCleanDependency(DependencyNode node) { @@ -173,7 +177,8 @@ private Dependency toDepCleanDependency(org.apache.maven.model.Dependency depend private boolean matches(Dependency dependencyCoordinate, org.apache.maven.model.Dependency dependency) { return dependencyCoordinate.getGroupId().equalsIgnoreCase(dependency.getGroupId()) - && dependencyCoordinate.getDependencyId().equalsIgnoreCase(dependency.getArtifactId()); + && dependencyCoordinate.getDependencyId().equalsIgnoreCase(dependency.getArtifactId()) + && dependencyCoordinate.getVersion().equalsIgnoreCase(dependency.getVersion()); } private ImmutableSet getAllDependencies(MavenProject project) { From 706bd0b93524aaf66ed4194112a16a396e7069b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Soto=20Valero?= Date: Fri, 23 Dec 2022 11:18:48 +0100 Subject: [PATCH 03/11] Fix tree recursion with inherited transitive dependencies --- .../depclean/graph/MavenDependencyGraph.java | 33 +++++++++++-------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/depclean-maven-plugin/src/main/java/se/kth/depclean/graph/MavenDependencyGraph.java b/depclean-maven-plugin/src/main/java/se/kth/depclean/graph/MavenDependencyGraph.java index c848c2b0..5fb6ad19 100644 --- a/depclean-maven-plugin/src/main/java/se/kth/depclean/graph/MavenDependencyGraph.java +++ b/depclean-maven-plugin/src/main/java/se/kth/depclean/graph/MavenDependencyGraph.java @@ -8,6 +8,7 @@ import com.google.common.collect.ImmutableSet; import com.google.common.collect.Multimap; import java.io.File; +import java.util.HashSet; import java.util.Set; import java.util.stream.Collectors; import lombok.extern.slf4j.Slf4j; @@ -45,9 +46,6 @@ public MavenDependencyGraph(MavenProject project, Model model, DependencyNode ro this.rootNode = rootNode; buildDependencyDependencies(rootNode); - System.out.println("dependenciesPerDependency = " + dependenciesPerDependency); - - System.out.println("rootNode = " + rootNode); System.out.println("Dependencies per dependency"); dependenciesPerDependency.forEach((key, value) -> System.out.println(key + " -> " + value)); @@ -57,8 +55,16 @@ public MavenDependencyGraph(MavenProject project, Model model, DependencyNode ro // The project gets all the direct dependencies (with the inherited ones) //noinspection deprecation this.inheritedDirectDependencies = inheritedDirectDependencies(project.getDependencyArtifacts()); - this.inheritedTransitiveDependencies = inheritedTransitiveDependencies(inheritedDirectDependencies); + + this.inheritedTransitiveDependencies = inheritedTransitiveDependencies(inheritedDirectDependencies, new HashSet<>()); this.transitiveDependencies = transitiveDependencies(allDependencies); + + System.out.println("All dependencies" + allDependencies); + System.out.println("Direct dependencies" + directDependencies); + System.out.println("Inherited direct dependencies" + inheritedDirectDependencies); + System.out.println("Inherited transitive dependencies" + inheritedTransitiveDependencies); + System.out.println("Transitive dependencies" + transitiveDependencies); + // Logs if (log.isDebugEnabled()) { this.allDependencies.forEach(dep -> { @@ -125,15 +131,16 @@ public Set inheritedTransitiveDependencies() { } @NotNull - private Set inheritedTransitiveDependencies(Set inheritedDirectDependencies) { - Set allInheritedTransitiveDependencies = newHashSet(); - dependenciesPerDependency.forEach((key, value) -> { - if (inheritedDirectDependencies.contains(key)) { - allInheritedTransitiveDependencies.add(value); - } - } - ); - return copyOf(allInheritedTransitiveDependencies); + private Set inheritedTransitiveDependencies(Set inheritedDirectDependencies, Set inheritedTransitiveDependencies) { + // recursively add the transitive dependencies of the inherited direct dependencies + if (!inheritedDirectDependencies.isEmpty()) { + for (Dependency inheritedDirectDependency : inheritedDirectDependencies) { + Set c = new HashSet<>(dependenciesPerDependency.get(inheritedDirectDependency)); + inheritedTransitiveDependencies.addAll(c); + inheritedTransitiveDependencies(c, inheritedTransitiveDependencies); + } + } + return copyOf(inheritedTransitiveDependencies); } @Override From f8a2607178ed48e5843768c3cbc8e60406d63a66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Soto=20Valero?= Date: Fri, 23 Dec 2022 14:25:16 +0100 Subject: [PATCH 04/11] Fix nasty issue with non-reachable classes in the inherited transitive dependencies --- .../se/kth/depclean/core/DepCleanManager.java | 27 +++++++++++-------- .../core/analysis/ActualUsedClasses.java | 3 ++- .../DefaultProjectDependencyAnalyzer.java | 4 ++- .../ProjectDependencyAnalysisBuilder.java | 15 +++++------ .../model/ProjectDependencyAnalysis.java | 6 ++--- .../kth/depclean/core/model/Dependency.java | 6 +++-- .../depclean/core/model/ProjectContext.java | 26 +++++++++--------- .../core/DepCleanManagerEnd2EndTest.java | 8 +++--- .../java/se/kth/depclean/DepCleanMojo.java | 13 ++++++--- .../depclean/graph/MavenDependencyGraph.java | 26 +++++++++--------- .../unused_inherited_only/pom.xml | 10 ++++++- 11 files changed, 86 insertions(+), 58 deletions(-) diff --git a/depclean-core/src/main/java/se/kth/depclean/core/DepCleanManager.java b/depclean-core/src/main/java/se/kth/depclean/core/DepCleanManager.java index 7daed732..e4c0de09 100644 --- a/depclean-core/src/main/java/se/kth/depclean/core/DepCleanManager.java +++ b/depclean-core/src/main/java/se/kth/depclean/core/DepCleanManager.java @@ -41,7 +41,8 @@ public class DepCleanManager { private final Set ignoreDependencies; private final boolean failIfUnusedDirect; private final boolean failIfUnusedTransitive; - private final boolean failIfUnusedInherited; + private final boolean failIfUnusedInheritedDirect; + private final boolean failIfUnusedInheritedTransitive; private final boolean createPomDebloated; private final boolean createResultJson; private final boolean createCallGraphCsv; @@ -65,7 +66,7 @@ public ProjectDependencyAnalysis execute() throws AnalysisFailureException { return null; } - extractLibClasses(); + extractClassesFromDependencies(); final DefaultProjectDependencyAnalyzer projectDependencyAnalyzer = new DefaultProjectDependencyAnalyzer(); final ProjectDependencyAnalysis analysis = projectDependencyAnalyzer.analyze(buildProjectContext()); @@ -83,10 +84,16 @@ public ProjectDependencyAnalysis execute() throws AnalysisFailureException { "Build failed due to unused transitive dependencies in the dependency tree of the project."); } - /* Fail the build if there are unused inherited dependencies */ - if (failIfUnusedInherited && analysis.hasUnusedInheritedDirectDependencies()) { + /* Fail the build if there are unused inherited direct dependencies */ + if (failIfUnusedInheritedDirect && analysis.hasUnusedInheritedDirectDependencies()) { throw new AnalysisFailureException( - "Build failed due to unused inherited dependencies in the dependency tree of the project."); + "Build failed due to unused inherited direct dependencies in the dependency tree of the project."); + } + + /* Fail the build if there are unused inherited direct dependencies */ + if (failIfUnusedInheritedTransitive && analysis.hasUnusedInheritedTransitiveDependencies()) { + throw new AnalysisFailureException( + "Build failed due to unused inherited transitive dependencies in the dependency tree of the project."); } /* Writing the debloated version of the pom */ @@ -106,14 +113,13 @@ public ProjectDependencyAnalysis execute() throws AnalysisFailureException { } @SneakyThrows - private void extractLibClasses() { - final File dependencyDirectory = - dependencyManager.getBuildDirectory().resolve(DIRECTORY_TO_EXTRACT_DEPENDENCIES).toFile(); + private void extractClassesFromDependencies() { + File dependencyDirectory = dependencyManager.getBuildDirectory().resolve(DIRECTORY_TO_EXTRACT_DEPENDENCIES).toFile(); FileUtils.deleteDirectory(dependencyDirectory); dependencyManager.dependencyGraph().allDependencies() .forEach(jarFile -> copyDependencies(jarFile, dependencyDirectory)); - // TODO remove this workaround later + // Workaround for dependencies that are in located in a project's libs directory. if (dependencyManager.getBuildDirectory().resolve("libs").toFile().exists()) { try { FileUtils.copyDirectory( @@ -121,8 +127,7 @@ private void extractLibClasses() { dependencyDirectory ); } catch (IOException | NullPointerException e) { - getLog().error("Error copying directory libs to dependency"); - throw new RuntimeException(e); + getLog().error("Error copying directory libs to" + dependencyDirectory.getAbsolutePath()); } } diff --git a/depclean-core/src/main/java/se/kth/depclean/core/analysis/ActualUsedClasses.java b/depclean-core/src/main/java/se/kth/depclean/core/analysis/ActualUsedClasses.java index 89a12b0a..3c438b33 100644 --- a/depclean-core/src/main/java/se/kth/depclean/core/analysis/ActualUsedClasses.java +++ b/depclean-core/src/main/java/se/kth/depclean/core/analysis/ActualUsedClasses.java @@ -22,9 +22,10 @@ public ActualUsedClasses(ProjectContext context) { private void registerClass(ClassName className) { // Do not register class unknown to dependencies if (context.hasNoDependencyOnClass(className)) { + log.info("Class {} is not known to any dependency", className); return; } - log.trace("## Register class {}", className); + log.info("## Register class {}", className); classes.add(className); } 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 fac49c32..d8fceca0 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 @@ -57,12 +57,14 @@ public ProjectDependencyAnalysis analyze(final ProjectContext projectContext) { .forEach(folder -> actualUsedClasses.registerClasses(getProjectDependencyClasses(folder))); // analyze project's tests class files if (!projectContext.ignoreTests()) { - log.trace("Parsing test folder"); + log.info("Parsing test folder"); projectContext.getTestOutputFolders() .forEach(folder -> actualUsedClasses.registerClasses(getProjectTestDependencyClasses(folder))); } // the set of compiled classes and tests in the project Set projectClasses = new HashSet<>(DefaultCallGraph.getProjectVertices()); + log.info("Project classes: {}", projectClasses); + // analyze dependencies' class files actualUsedClasses.registerClasses(getProjectDependencyClasses(projectContext.getDependenciesFolder())); // analyze extra classes (collected through static analysis of source code) diff --git a/depclean-core/src/main/java/se/kth/depclean/core/analysis/ProjectDependencyAnalysisBuilder.java b/depclean-core/src/main/java/se/kth/depclean/core/analysis/ProjectDependencyAnalysisBuilder.java index 2a5e2bba..5a1e3805 100644 --- a/depclean-core/src/main/java/se/kth/depclean/core/analysis/ProjectDependencyAnalysisBuilder.java +++ b/depclean-core/src/main/java/se/kth/depclean/core/analysis/ProjectDependencyAnalysisBuilder.java @@ -30,6 +30,9 @@ public class ProjectDependencyAnalysisBuilder { usedDependencies = actualUsedClasses.getRegisteredClasses().stream() .flatMap(clazz -> context.getDependenciesForClass(clazz).stream()) .collect(Collectors.toSet()); + + System.out.println("Actual used classes: " + actualUsedClasses.getRegisteredClasses()); + System.out.println("Used dependencies" + usedDependencies); } /** @@ -116,23 +119,19 @@ private Set getUnusedDirectDependencies(Set usedDirectDe return getUnusedDependencies(context.getDependencyGraph().directDependencies(), usedDirectDependencies); } - private Set getUnusedTransitiveDependencies( - Set usedTransitiveDependencies) { + private Set getUnusedTransitiveDependencies(Set usedTransitiveDependencies) { return getUnusedDependencies(context.getDependencyGraph().transitiveDependencies(), usedTransitiveDependencies); } - private Set getUnusedInheritedDirectDependencies( - Set usedInheritedDependencies) { + private Set getUnusedInheritedDirectDependencies(Set usedInheritedDependencies) { return getUnusedDependencies(context.getDependencyGraph().inheritedDirectDependencies(), usedInheritedDependencies); } - private Set getUnusedInheritedTransitiveDependencies( - Set usedInheritedDependencies) { + private Set getUnusedInheritedTransitiveDependencies(Set usedInheritedDependencies) { return getUnusedDependencies(context.getDependencyGraph().inheritedTransitiveDependencies(), usedInheritedDependencies); } - private Set getUnusedDependencies( - Set baseDependencies, Set usedDependencies) { + private Set getUnusedDependencies(Set baseDependencies, Set usedDependencies) { final Set unusedInheritedDependencies = newHashSet(baseDependencies); unusedInheritedDependencies.removeAll(usedDependencies); return unusedInheritedDependencies; diff --git a/depclean-core/src/main/java/se/kth/depclean/core/analysis/model/ProjectDependencyAnalysis.java b/depclean-core/src/main/java/se/kth/depclean/core/analysis/model/ProjectDependencyAnalysis.java index 17c4c551..3dbdd700 100644 --- a/depclean-core/src/main/java/se/kth/depclean/core/analysis/model/ProjectDependencyAnalysis.java +++ b/depclean-core/src/main/java/se/kth/depclean/core/analysis/model/ProjectDependencyAnalysis.java @@ -47,7 +47,6 @@ public class ProjectDependencyAnalysis { private static final String SEPARATOR = "-------------------------------------------------------"; - private final Set usedDirectDependencies; private final Set usedTransitiveDependencies; private final Set usedInheritedDirectDependencies; @@ -105,7 +104,7 @@ public boolean hasUnusedInheritedDirectDependencies() { } public boolean hasUnusedInheritedTransitiveDependencies() { - return !unusedInheritedDirectDependencies.isEmpty(); + return !unusedInheritedTransitiveDependencies.isEmpty(); } /** @@ -123,7 +122,6 @@ public void print() { printInfoOfDependencies("Potentially unused transitive dependencies", getUnusedTransitiveDependencies()); printInfoOfDependencies("Potentially unused inherited direct dependencies", getUnusedInheritedDirectDependencies()); printInfoOfDependencies("Potentially unused inherited transitive dependencies", getUnusedInheritedTransitiveDependencies()); - if (!ignoredDependencies.isEmpty()) { printString(SEPARATOR); printString( @@ -163,6 +161,7 @@ public DependencyAnalysisInfo getDependencyInfo(String coordinate) { public Set getUsedDependencies() { final Set dependencies = new HashSet<>(getUsedDirectDependencies()); dependencies.addAll(getUsedInheritedDirectDependencies()); + dependencies.addAll(getUsedInheritedTransitiveDependencies()); dependencies.addAll(getUsedTransitiveDependencies()); return dependencies.stream() .map(this::toDebloatedDependency) @@ -210,7 +209,6 @@ private String getStatus(Dependency coordinates) { || unusedTransitiveDependencies.contains(coordinates)) ? "bloated" : "unknown"; } - } private String getType(Dependency coordinates) { diff --git a/depclean-core/src/main/java/se/kth/depclean/core/model/Dependency.java b/depclean-core/src/main/java/se/kth/depclean/core/model/Dependency.java index 80a23af9..628db16d 100644 --- a/depclean-core/src/main/java/se/kth/depclean/core/model/Dependency.java +++ b/depclean-core/src/main/java/se/kth/depclean/core/model/Dependency.java @@ -51,7 +51,7 @@ public Dependency(String groupId, String dependencyId, String version, String sc this.scope = scope; this.file = file; this.relatedClasses = findRelatedClasses(); - this.size = calculateSize(); + this.size = calculateSize(file); } /** @@ -106,10 +106,12 @@ private Iterable findRelatedClasses() { log.error(e.getMessage(), e); } } + log.trace("Finding related classes for Dependency: " + groupId + ":" + dependencyId + ":" + version + ":" + scope + ":" + file); + log.trace("Related classes: " + relatedClasses); return copyOf(relatedClasses); } - private Long calculateSize() { + private Long calculateSize(File file) { try { return FileUtils.sizeOf(file); } catch (IllegalArgumentException | NullPointerException e) { diff --git a/depclean-core/src/main/java/se/kth/depclean/core/model/ProjectContext.java b/depclean-core/src/main/java/se/kth/depclean/core/model/ProjectContext.java index 577c6305..47ef859e 100644 --- a/depclean-core/src/main/java/se/kth/depclean/core/model/ProjectContext.java +++ b/depclean-core/src/main/java/se/kth/depclean/core/model/ProjectContext.java @@ -16,8 +16,7 @@ import se.kth.depclean.core.analysis.graph.DependencyGraph; /** - * Contains all information about the project's context. - * It doesn't have any reference to a given framework (Maven, Gradle, etc.). + * Contains all information about the project's context. It doesn't have any reference to a given framework (Maven, Gradle, etc.). */ @Slf4j @ToString @@ -61,14 +60,14 @@ public final class ProjectContext { * @param extraClasses some classes we want to tell the analyser to consider used */ public ProjectContext(DependencyGraph dependencyGraph, - Set outputFolders, - Set testOutputFolders, - Path sourceFolder, - Path tesSourceFolder, - Path dependenciesFolder, - Set ignoredScopes, - Set ignoredDependencies, - Set extraClasses) { + Set outputFolders, + Set testOutputFolders, + Path sourceFolder, + Path tesSourceFolder, + Path dependenciesFolder, + Set ignoredScopes, + Set ignoredDependencies, + Set extraClasses) { this.dependencyGraph = dependencyGraph; this.outputFolders = outputFolders; this.testOutputFolders = testOutputFolders; @@ -82,9 +81,9 @@ public ProjectContext(DependencyGraph dependencyGraph, ignoredScopes.forEach(scope -> log.info("Ignoring scope {}", scope)); populateDependenciesAndClassesMap(dependencyGraph.directDependencies()); - populateDependenciesAndClassesMap(dependencyGraph.transitiveDependencies()); populateDependenciesAndClassesMap(dependencyGraph.inheritedDirectDependencies()); populateDependenciesAndClassesMap(dependencyGraph.inheritedTransitiveDependencies()); + populateDependenciesAndClassesMap(dependencyGraph.transitiveDependencies()); Multimaps.invertFrom(classesPerDependency, dependenciesPerClass); } @@ -119,7 +118,10 @@ public boolean ignoreTests() { private void populateDependenciesAndClassesMap(Set dependencies) { dependencies.stream() .filter(this::excludeScopes) - .forEach(dc -> classesPerDependency.putAll(dc, dc.getRelatedClasses())); + .forEach(dc -> { + log.info("Adding dependency {} with related classes: {}", dc, dc.getRelatedClasses()); + classesPerDependency.putAll(dc, dc.getRelatedClasses()); + }); } private boolean excludeScopes(Dependency dc) { diff --git a/depclean-core/src/test/java/se/kth/depclean/core/DepCleanManagerEnd2EndTest.java b/depclean-core/src/test/java/se/kth/depclean/core/DepCleanManagerEnd2EndTest.java index 3e412d55..8027d4cd 100644 --- a/depclean-core/src/test/java/se/kth/depclean/core/DepCleanManagerEnd2EndTest.java +++ b/depclean-core/src/test/java/se/kth/depclean/core/DepCleanManagerEnd2EndTest.java @@ -235,7 +235,8 @@ static class DepCleanManagerBuilder { private Set ignoreDependencies = of(); private boolean failIfUnusedDirect = false; private boolean failIfUnusedTransitive = false; - private boolean failIfUnusedInherited = false; + private boolean failIfUnusedInheritedDirect = false; + private boolean failIfUnusedInheritedTransitive= false; private boolean createPomDebloated = false; private boolean createResultJson = false; private boolean createClassUsageCsv = false; @@ -249,7 +250,8 @@ public DepCleanManager build() { ignoreDependencies, failIfUnusedDirect, failIfUnusedTransitive, - failIfUnusedInherited, + failIfUnusedInheritedDirect, + failIfUnusedInheritedTransitive, createPomDebloated, createResultJson, createClassUsageCsv @@ -278,7 +280,7 @@ public DepCleanManagerBuilder withFailIfUnusedDirectDependency() { } public DepCleanManagerBuilder withFailIfUnusedInheritedDependency() { - this.failIfUnusedInherited = true; + this.failIfUnusedInheritedDirect = true; return this; } 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 2d815bd8..bf56fdf7 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 @@ -121,8 +121,14 @@ public class DepCleanMojo extends AbstractMojo { * If this is true, and DepClean reported any unused inherited dependency in the dependency tree, then the project's * build fails immediately after running DepClean. */ - @Parameter(property = "failIfUnusedInherited", defaultValue = "false") - private boolean failIfUnusedInherited; + @Parameter(property = "failIfUnusedInheritedDirect", defaultValue = "false") + private boolean failIfUnusedInheritedDirect; + /** + * If this is true, and DepClean reported any unused inherited dependency in the dependency tree, then the project's + * build fails immediately after running DepClean. + */ + @Parameter(property = "failIfUnusedInheritedTransitive", defaultValue = "false") + private boolean failIfUnusedInheritedTransitive; /** * Skip plugin execution completely. @@ -153,7 +159,8 @@ public final void execute() { ignoreDependencies, failIfUnusedDirect, failIfUnusedTransitive, - failIfUnusedInherited, + failIfUnusedInheritedDirect, + failIfUnusedInheritedTransitive, createPomDebloated, createResultJson, createCallGraphCsv diff --git a/depclean-maven-plugin/src/main/java/se/kth/depclean/graph/MavenDependencyGraph.java b/depclean-maven-plugin/src/main/java/se/kth/depclean/graph/MavenDependencyGraph.java index 5fb6ad19..db642984 100644 --- a/depclean-maven-plugin/src/main/java/se/kth/depclean/graph/MavenDependencyGraph.java +++ b/depclean-maven-plugin/src/main/java/se/kth/depclean/graph/MavenDependencyGraph.java @@ -45,25 +45,19 @@ public MavenDependencyGraph(MavenProject project, Model model, DependencyNode ro this.project = project; this.rootNode = rootNode; buildDependencyDependencies(rootNode); - - System.out.println("Dependencies per dependency"); - dependenciesPerDependency.forEach((key, value) -> System.out.println(key + " -> " + value)); - this.allDependencies = getAllDependencies(project); // The model gets only the direct dependencies (not the inherited ones) this.directDependencies = getDirectDependencies(model); // The project gets all the direct dependencies (with the inherited ones) //noinspection deprecation this.inheritedDirectDependencies = inheritedDirectDependencies(project.getDependencyArtifacts()); - this.inheritedTransitiveDependencies = inheritedTransitiveDependencies(inheritedDirectDependencies, new HashSet<>()); this.transitiveDependencies = transitiveDependencies(allDependencies); - System.out.println("All dependencies" + allDependencies); - System.out.println("Direct dependencies" + directDependencies); - System.out.println("Inherited direct dependencies" + inheritedDirectDependencies); - System.out.println("Inherited transitive dependencies" + inheritedTransitiveDependencies); - System.out.println("Transitive dependencies" + transitiveDependencies); + log.info("Direct dependencies" + directDependencies); + log.info("Inherited direct dependencies" + inheritedDirectDependencies); + log.info("Inherited transitive dependencies" + inheritedTransitiveDependencies); + log.info("Transitive dependencies" + transitiveDependencies); // Logs if (log.isDebugEnabled()) { @@ -132,11 +126,19 @@ public Set inheritedTransitiveDependencies() { @NotNull private Set inheritedTransitiveDependencies(Set inheritedDirectDependencies, Set inheritedTransitiveDependencies) { - // recursively add the transitive dependencies of the inherited direct dependencies if (!inheritedDirectDependencies.isEmpty()) { for (Dependency inheritedDirectDependency : inheritedDirectDependencies) { Set c = new HashSet<>(dependenciesPerDependency.get(inheritedDirectDependency)); - inheritedTransitiveDependencies.addAll(c); + for (Dependency d : c) { + project.getArtifacts().stream() + .filter(artifact -> artifact.getGroupId().equals(d.getGroupId()) && artifact.getArtifactId().equals(d.getDependencyId())) + .findFirst() + .ifPresent(artifact -> { + if (artifact.getVersion().equals(d.getVersion())) { + inheritedTransitiveDependencies.add(toDepCleanDependency(artifact)); + } + }); + } inheritedTransitiveDependencies(c, inheritedTransitiveDependencies); } } diff --git a/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/unused_inherited_only/pom.xml b/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/unused_inherited_only/pom.xml index 5f7aafd6..1c73fa5f 100644 --- a/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/unused_inherited_only/pom.xml +++ b/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/unused_inherited_only/pom.xml @@ -1,4 +1,4 @@ - + 4.0.0 @@ -7,8 +7,16 @@ org.apache.commons commons-math-parent 4.0-beta1 + + + + + + + + org.foo.bar foobar 1.0.0-SNAPSHOT From 95f57de02c5ea7739fb70c1ef0607864fc3edde1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Soto=20Valero?= Date: Fri, 23 Dec 2022 14:35:45 +0100 Subject: [PATCH 05/11] Removing logs --- .../se/kth/depclean/core/analysis/ActualUsedClasses.java | 4 ++-- .../core/analysis/DefaultProjectDependencyAnalyzer.java | 3 +-- .../core/analysis/ProjectDependencyAnalysisBuilder.java | 4 ++-- .../depclean/core/analysis/graph/DefaultCallGraph.java | 6 ++++-- .../java/se/kth/depclean/core/model/ProjectContext.java | 2 +- .../java/se/kth/depclean/graph/MavenDependencyGraph.java | 8 ++++---- 6 files changed, 14 insertions(+), 13 deletions(-) diff --git a/depclean-core/src/main/java/se/kth/depclean/core/analysis/ActualUsedClasses.java b/depclean-core/src/main/java/se/kth/depclean/core/analysis/ActualUsedClasses.java index 3c438b33..1ed4d326 100644 --- a/depclean-core/src/main/java/se/kth/depclean/core/analysis/ActualUsedClasses.java +++ b/depclean-core/src/main/java/se/kth/depclean/core/analysis/ActualUsedClasses.java @@ -22,10 +22,10 @@ public ActualUsedClasses(ProjectContext context) { private void registerClass(ClassName className) { // Do not register class unknown to dependencies if (context.hasNoDependencyOnClass(className)) { - log.info("Class {} is not known to any dependency", className); + log.debug("Class {} is not known to any dependency", className); return; } - log.info("## Register class {}", className); + log.debug("## Registered class {}", className); classes.add(className); } 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 d8fceca0..524df268 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 @@ -57,13 +57,12 @@ public ProjectDependencyAnalysis analyze(final ProjectContext projectContext) { .forEach(folder -> actualUsedClasses.registerClasses(getProjectDependencyClasses(folder))); // analyze project's tests class files if (!projectContext.ignoreTests()) { - log.info("Parsing test folder"); projectContext.getTestOutputFolders() .forEach(folder -> actualUsedClasses.registerClasses(getProjectTestDependencyClasses(folder))); } // the set of compiled classes and tests in the project Set projectClasses = new HashSet<>(DefaultCallGraph.getProjectVertices()); - log.info("Project classes: {}", projectClasses); + log.debug("Project classes: {}", projectClasses); // analyze dependencies' class files actualUsedClasses.registerClasses(getProjectDependencyClasses(projectContext.getDependenciesFolder())); diff --git a/depclean-core/src/main/java/se/kth/depclean/core/analysis/ProjectDependencyAnalysisBuilder.java b/depclean-core/src/main/java/se/kth/depclean/core/analysis/ProjectDependencyAnalysisBuilder.java index 5a1e3805..b25a8219 100644 --- a/depclean-core/src/main/java/se/kth/depclean/core/analysis/ProjectDependencyAnalysisBuilder.java +++ b/depclean-core/src/main/java/se/kth/depclean/core/analysis/ProjectDependencyAnalysisBuilder.java @@ -31,8 +31,8 @@ public class ProjectDependencyAnalysisBuilder { .flatMap(clazz -> context.getDependenciesForClass(clazz).stream()) .collect(Collectors.toSet()); - System.out.println("Actual used classes: " + actualUsedClasses.getRegisteredClasses()); - System.out.println("Used dependencies" + usedDependencies); + log.debug("Actual used classes: " + actualUsedClasses.getRegisteredClasses()); + log.debug("Used dependencies" + usedDependencies); } /** 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 612db6b0..c20a3ae4 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 @@ -22,6 +22,7 @@ import java.util.Iterator; import java.util.Map; import java.util.Set; +import lombok.extern.slf4j.Slf4j; import org.jgrapht.graph.AbstractBaseGraph; import org.jgrapht.graph.DefaultDirectedGraph; import org.jgrapht.graph.DefaultEdge; @@ -30,6 +31,7 @@ /** * A directed graph G = (V, E) where V is a set of classes and E is a set of edges. Edges represent class member calls between the classes in V. */ +@Slf4j public class DefaultCallGraph { private static final AbstractBaseGraph directedGraph = new DefaultDirectedGraph<>(DefaultEdge.class); @@ -63,12 +65,12 @@ public static void addEdge(String clazz, Set referencedClassMembers) { * @return All the referenced classes. */ public static Set referencedClassMembers(Set projectClasses) { - //System.out.println("project classes: " + projectClasses); + log.debug("Project classes: " + projectClasses); Set allReferencedClassMembers = new HashSet<>(); for (String projectClass : projectClasses) { allReferencedClassMembers.addAll(traverse(projectClass)); } - //System.out.println("All referenced class members: " + allReferencedClassMembers); + log.debug("All referenced class members: " + allReferencedClassMembers); return allReferencedClassMembers; } diff --git a/depclean-core/src/main/java/se/kth/depclean/core/model/ProjectContext.java b/depclean-core/src/main/java/se/kth/depclean/core/model/ProjectContext.java index 47ef859e..1a6b82ba 100644 --- a/depclean-core/src/main/java/se/kth/depclean/core/model/ProjectContext.java +++ b/depclean-core/src/main/java/se/kth/depclean/core/model/ProjectContext.java @@ -119,7 +119,7 @@ private void populateDependenciesAndClassesMap(Set dependencies) { dependencies.stream() .filter(this::excludeScopes) .forEach(dc -> { - log.info("Adding dependency {} with related classes: {}", dc, dc.getRelatedClasses()); + log.debug("Adding dependency {} with related classes: {}", dc, dc.getRelatedClasses()); classesPerDependency.putAll(dc, dc.getRelatedClasses()); }); } diff --git a/depclean-maven-plugin/src/main/java/se/kth/depclean/graph/MavenDependencyGraph.java b/depclean-maven-plugin/src/main/java/se/kth/depclean/graph/MavenDependencyGraph.java index db642984..0ef066d5 100644 --- a/depclean-maven-plugin/src/main/java/se/kth/depclean/graph/MavenDependencyGraph.java +++ b/depclean-maven-plugin/src/main/java/se/kth/depclean/graph/MavenDependencyGraph.java @@ -54,10 +54,10 @@ public MavenDependencyGraph(MavenProject project, Model model, DependencyNode ro this.inheritedTransitiveDependencies = inheritedTransitiveDependencies(inheritedDirectDependencies, new HashSet<>()); this.transitiveDependencies = transitiveDependencies(allDependencies); - log.info("Direct dependencies" + directDependencies); - log.info("Inherited direct dependencies" + inheritedDirectDependencies); - log.info("Inherited transitive dependencies" + inheritedTransitiveDependencies); - log.info("Transitive dependencies" + transitiveDependencies); + log.debug("Direct dependencies" + directDependencies); + log.debug("Inherited direct dependencies" + inheritedDirectDependencies); + log.debug("Inherited transitive dependencies" + inheritedTransitiveDependencies); + log.debug("Transitive dependencies" + transitiveDependencies); // Logs if (log.isDebugEnabled()) { From 1ec5e18f510c92b0ac58814f2c7036ec0e6be522 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Soto=20Valero?= Date: Sat, 24 Dec 2022 15:02:48 +0100 Subject: [PATCH 06/11] Fix bug when Optional is empty --- .../depclean/graph/MavenDependencyGraph.java | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/depclean-maven-plugin/src/main/java/se/kth/depclean/graph/MavenDependencyGraph.java b/depclean-maven-plugin/src/main/java/se/kth/depclean/graph/MavenDependencyGraph.java index 0ef066d5..c89e4ef7 100644 --- a/depclean-maven-plugin/src/main/java/se/kth/depclean/graph/MavenDependencyGraph.java +++ b/depclean-maven-plugin/src/main/java/se/kth/depclean/graph/MavenDependencyGraph.java @@ -9,6 +9,7 @@ import com.google.common.collect.Multimap; import java.io.File; import java.util.HashSet; +import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; import lombok.extern.slf4j.Slf4j; @@ -42,6 +43,9 @@ public class MavenDependencyGraph implements DependencyGraph { * @param rootNode the graph's root node */ public MavenDependencyGraph(MavenProject project, Model model, DependencyNode rootNode) { + + log.info("Building dependency graph"); + this.project = project; this.rootNode = rootNode; buildDependencyDependencies(rootNode); @@ -54,10 +58,10 @@ public MavenDependencyGraph(MavenProject project, Model model, DependencyNode ro this.inheritedTransitiveDependencies = inheritedTransitiveDependencies(inheritedDirectDependencies, new HashSet<>()); this.transitiveDependencies = transitiveDependencies(allDependencies); - log.debug("Direct dependencies" + directDependencies); - log.debug("Inherited direct dependencies" + inheritedDirectDependencies); - log.debug("Inherited transitive dependencies" + inheritedTransitiveDependencies); - log.debug("Transitive dependencies" + transitiveDependencies); + log.info("Direct dependencies" + directDependencies); + log.info("Inherited direct dependencies" + inheritedDirectDependencies); + log.info("Inherited transitive dependencies" + inheritedTransitiveDependencies); + log.info("Transitive dependencies" + transitiveDependencies); // Logs if (log.isDebugEnabled()) { @@ -177,17 +181,18 @@ private Dependency toDepCleanDependency(DependencyNode node) { } private Dependency toDepCleanDependency(org.apache.maven.model.Dependency dependency) { - //noinspection OptionalGetWithoutIsPresent - return allDependencies.stream() - .filter(artifact -> matches(artifact, dependency)) - .findFirst() - .get(); + for (Dependency artifact : allDependencies) { + if (matches(artifact, dependency)) { + return Optional.of(artifact).get(); + } + } + // This should never happen. + return null; } private boolean matches(Dependency dependencyCoordinate, org.apache.maven.model.Dependency dependency) { return dependencyCoordinate.getGroupId().equalsIgnoreCase(dependency.getGroupId()) - && dependencyCoordinate.getDependencyId().equalsIgnoreCase(dependency.getArtifactId()) - && dependencyCoordinate.getVersion().equalsIgnoreCase(dependency.getVersion()); + && dependencyCoordinate.getDependencyId().equalsIgnoreCase(dependency.getArtifactId()); } private ImmutableSet getAllDependencies(MavenProject project) { From 66c9ae68496cd5ee0aeaa1039f7ca9d79465d856 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Soto=20Valero?= Date: Sat, 24 Dec 2022 15:46:29 +0100 Subject: [PATCH 07/11] Fix/Update integration tests --- depclean-core/src/main/resources/log4j2.xml | 2 +- .../core/DepCleanManagerEnd2EndTest.java | 2 +- .../analysis/graph/DefaultCallGraphTest.java | 2 + .../model/ProjectDependencyAnalysisTest.java | 1 + ...onsole-appender_pattern-layout_colored.xml | 5 + depclean-core/src/test/resources/log4j2.xml | 36 +++++++ .../depclean/graph/MavenDependencyGraph.java | 11 +-- .../java/se/kth/depclean/DepCleanMojoIT.java | 95 ++++++++++++++----- .../all_dependencies_unused/pom.xml | 2 +- .../all_dependencies_used/pom.xml | 2 +- .../DepCleanMojoIT/empty_project/pom.xml | 2 +- .../json_should_be_correct/pom.xml | 2 +- .../pom_should_be_correct/pom.xml | 36 ------- .../DepCleanMojoIT/processor_used/pom.xml | 2 +- .../DepCleanMojoIT/unused_direct_only/pom.xml | 2 +- .../pom.xml | 13 +-- .../src/main/java/mypackage/Main.java | 0 .../src/test/java/mypackage/MainTest.java | 0 .../unused_transitive_only/pom.xml | 2 +- .../DepCleanMojoIT/used_indirectly/pom.xml | 2 +- .../DepCleanMojoIT/used_java_record/pom.xml | 2 +- ...onsole-appender_pattern-layout_colored.xml | 5 + .../src/test/resources/log4j2.xml | 36 +++++++ 23 files changed, 172 insertions(+), 90 deletions(-) create mode 100644 depclean-core/src/test/resources/log4j2-includes/console-appender_pattern-layout_colored.xml create mode 100644 depclean-core/src/test/resources/log4j2.xml delete mode 100644 depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/pom_should_be_correct/pom.xml rename depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/{unused_inherited_only => unused_inherited_exists}/pom.xml (88%) rename depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/{unused_inherited_only => unused_inherited_exists}/src/main/java/mypackage/Main.java (100%) rename depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/{unused_inherited_only => unused_inherited_exists}/src/test/java/mypackage/MainTest.java (100%) create mode 100644 depclean-maven-plugin/src/test/resources/log4j2-includes/console-appender_pattern-layout_colored.xml create mode 100644 depclean-maven-plugin/src/test/resources/log4j2.xml diff --git a/depclean-core/src/main/resources/log4j2.xml b/depclean-core/src/main/resources/log4j2.xml index b5920e17..0b49af43 100644 --- a/depclean-core/src/main/resources/log4j2.xml +++ b/depclean-core/src/main/resources/log4j2.xml @@ -1,6 +1,6 @@ + packages="se.kth.depclean" status="WARN"> diff --git a/depclean-core/src/test/java/se/kth/depclean/core/DepCleanManagerEnd2EndTest.java b/depclean-core/src/test/java/se/kth/depclean/core/DepCleanManagerEnd2EndTest.java index 8027d4cd..a8ee8814 100644 --- a/depclean-core/src/test/java/se/kth/depclean/core/DepCleanManagerEnd2EndTest.java +++ b/depclean-core/src/test/java/se/kth/depclean/core/DepCleanManagerEnd2EndTest.java @@ -173,7 +173,7 @@ void shouldFailForUnusedInheritedDependency() { assertThatThrownBy(depCleanManager::execute) .isInstanceOf(AnalysisFailureException.class) - .hasMessage("Build failed due to unused inherited dependencies in the dependency tree of the project."); + .hasMessage("Build failed due to unused inherited direct dependencies in the dependency tree of the project."); } @Test diff --git a/depclean-core/src/test/java/se/kth/depclean/core/analysis/graph/DefaultCallGraphTest.java b/depclean-core/src/test/java/se/kth/depclean/core/analysis/graph/DefaultCallGraphTest.java index 00b71b27..84013480 100644 --- a/depclean-core/src/test/java/se/kth/depclean/core/analysis/graph/DefaultCallGraphTest.java +++ b/depclean-core/src/test/java/se/kth/depclean/core/analysis/graph/DefaultCallGraphTest.java @@ -5,11 +5,13 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; +import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +@Slf4j class DefaultCallGraphTest { @BeforeEach diff --git a/depclean-core/src/test/java/se/kth/depclean/core/analysis/model/ProjectDependencyAnalysisTest.java b/depclean-core/src/test/java/se/kth/depclean/core/analysis/model/ProjectDependencyAnalysisTest.java index ca4b2739..dba84ecc 100644 --- a/depclean-core/src/test/java/se/kth/depclean/core/analysis/model/ProjectDependencyAnalysisTest.java +++ b/depclean-core/src/test/java/se/kth/depclean/core/analysis/model/ProjectDependencyAnalysisTest.java @@ -35,6 +35,7 @@ void shouldBuildResultingDependencyGraph() { assertThat(analysis.getUsedDependencies()) .containsExactlyInAnyOrder( new DebloatedDependency(COMMONS_IO_DEPENDENCY, of(COMMONS_LOGGING_DEPENDENCY)), + new DebloatedDependency(COMMONS_LANG_DEPENDENCY, of(COMMONS_LOGGING_DEPENDENCY)), new DebloatedDependency(JUNIT_DEPENDENCY, of()) ); } diff --git a/depclean-core/src/test/resources/log4j2-includes/console-appender_pattern-layout_colored.xml b/depclean-core/src/test/resources/log4j2-includes/console-appender_pattern-layout_colored.xml new file mode 100644 index 00000000..11180eb8 --- /dev/null +++ b/depclean-core/src/test/resources/log4j2-includes/console-appender_pattern-layout_colored.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/depclean-core/src/test/resources/log4j2.xml b/depclean-core/src/test/resources/log4j2.xml new file mode 100644 index 00000000..b5920e17 --- /dev/null +++ b/depclean-core/src/test/resources/log4j2.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/depclean-maven-plugin/src/main/java/se/kth/depclean/graph/MavenDependencyGraph.java b/depclean-maven-plugin/src/main/java/se/kth/depclean/graph/MavenDependencyGraph.java index c89e4ef7..bc089385 100644 --- a/depclean-maven-plugin/src/main/java/se/kth/depclean/graph/MavenDependencyGraph.java +++ b/depclean-maven-plugin/src/main/java/se/kth/depclean/graph/MavenDependencyGraph.java @@ -43,9 +43,6 @@ public class MavenDependencyGraph implements DependencyGraph { * @param rootNode the graph's root node */ public MavenDependencyGraph(MavenProject project, Model model, DependencyNode rootNode) { - - log.info("Building dependency graph"); - this.project = project; this.rootNode = rootNode; buildDependencyDependencies(rootNode); @@ -58,10 +55,10 @@ public MavenDependencyGraph(MavenProject project, Model model, DependencyNode ro this.inheritedTransitiveDependencies = inheritedTransitiveDependencies(inheritedDirectDependencies, new HashSet<>()); this.transitiveDependencies = transitiveDependencies(allDependencies); - log.info("Direct dependencies" + directDependencies); - log.info("Inherited direct dependencies" + inheritedDirectDependencies); - log.info("Inherited transitive dependencies" + inheritedTransitiveDependencies); - log.info("Transitive dependencies" + transitiveDependencies); + log.debug("Direct dependencies" + directDependencies); + log.debug("Inherited direct dependencies" + inheritedDirectDependencies); + log.debug("Inherited transitive dependencies" + inheritedTransitiveDependencies); + log.debug("Transitive dependencies" + transitiveDependencies); // Logs if (log.isDebugEnabled()) { diff --git a/depclean-maven-plugin/src/test/java/se/kth/depclean/DepCleanMojoIT.java b/depclean-maven-plugin/src/test/java/se/kth/depclean/DepCleanMojoIT.java index ef44aa46..1f7300c6 100644 --- a/depclean-maven-plugin/src/test/java/se/kth/depclean/DepCleanMojoIT.java +++ b/depclean-maven-plugin/src/test/java/se/kth/depclean/DepCleanMojoIT.java @@ -8,9 +8,10 @@ import java.io.File; import java.io.IOException; import java.nio.charset.Charset; +import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.FileUtils; import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Disabled; import se.kth.depclean.util.OsUtils; /** @@ -21,18 +22,18 @@ * @see */ @MavenJupiterExtension +@Slf4j public class DepCleanMojoIT { @MavenTest - @DisplayName("Test that DepClean runs in an empty Maven project") void empty_project(MavenExecutionResult result) { + log.info("Test that DepClean runs in an empty Maven project"); assertThat(result).isSuccessful(); // should pass } - @MavenTest - @DisplayName("Test that DepClean identifies dependency used in Java record") void used_java_record(MavenExecutionResult result) { + log.info("Test that DepClean identifies dependency used in Java record"); assertThat(result).isSuccessful().out() .plain().contains( "-------------------------------------------------------", @@ -40,31 +41,33 @@ void used_java_record(MavenExecutionResult result) { "-------------------------------------------------------", "USED DIRECT DEPENDENCIES [1]: ", " commons-io:commons-io:2.11.0:compile (319 KB)", - "USED INHERITED DEPENDENCIES [0]: ", "USED TRANSITIVE DEPENDENCIES [0]: ", + "USED INHERITED DIRECT DEPENDENCIES [0]: ", + "USED INHERITED TRANSITIVE DEPENDENCIES [0]: ", "POTENTIALLY UNUSED DIRECT DEPENDENCIES [1]: ", " org.apache.commons:commons-compress:1.21:compile (994 KB)", - "POTENTIALLY UNUSED INHERITED DEPENDENCIES [0]: ", - "POTENTIALLY UNUSED TRANSITIVE DEPENDENCIES [0]: " + "POTENTIALLY UNUSED TRANSITIVE DEPENDENCIES [0]: ", + "POTENTIALLY UNUSED INHERITED DIRECT DEPENDENCIES [0]: ", + "POTENTIALLY UNUSED INHERITED TRANSITIVE DEPENDENCIES [0]: " ); } @MavenTest - @DisplayName("Test that DepClean identifies all dependencies as unused") void all_dependencies_unused(MavenExecutionResult result) { + log.info("Test that DepClean identifies all dependencies as unused"); assertThat(result).isSuccessful().out() .plain().contains( "-------------------------------------------------------", " D E P C L E A N A N A L Y S I S R E S U L T S", "-------------------------------------------------------", "USED DIRECT DEPENDENCIES [0]: ", - "USED INHERITED DEPENDENCIES [0]: ", "USED TRANSITIVE DEPENDENCIES [0]: ", + "USED INHERITED DIRECT DEPENDENCIES [0]: ", + "USED INHERITED TRANSITIVE DEPENDENCIES [0]: ", "POTENTIALLY UNUSED DIRECT DEPENDENCIES [3]: ", " com.google.guava:guava:31.0.1-jre:compile (2 MB)", " com.fasterxml.jackson.core:jackson-databind:2.12.2:compile (1 MB)", " commons-io:commons-io:2.11.0:compile (319 KB)", - "POTENTIALLY UNUSED INHERITED DEPENDENCIES [0]: ", "POTENTIALLY UNUSED TRANSITIVE DEPENDENCIES [8]: ", " com.fasterxml.jackson.core:jackson-core:2.12.2:compile (356 KB)", " org.checkerframework:checker-qual:3.12.0:compile (203 KB)", @@ -72,13 +75,15 @@ void all_dependencies_unused(MavenExecutionResult result) { " com.google.code.findbugs:jsr305:3.0.2:compile (19 KB)", " com.google.errorprone:error_prone_annotations:2.7.1:compile (14 KB)", " com.google.j2objc:j2objc-annotations:1.3:compile (8 KB)", - " com.google.guava:failureaccess:1.0.1:compile (4 KB)" + " com.google.guava:failureaccess:1.0.1:compile (4 KB)", + "POTENTIALLY UNUSED INHERITED DIRECT DEPENDENCIES [0]: ", + "POTENTIALLY UNUSED INHERITED TRANSITIVE DEPENDENCIES [0]: " ); } @MavenTest - @DisplayName("Test that DepClean identifies all dependencies as used") void all_dependencies_used(MavenExecutionResult result) { + log.info("Test that DepClean identifies all dependencies as used"); assertThat(result).isSuccessful().out() .plain().contains( "-------------------------------------------------------", @@ -90,17 +95,19 @@ void all_dependencies_used(MavenExecutionResult result) { " commons-codec:commons-codec:1.15:compile (345 KB)", " commons-io:commons-io:2.11.0:compile (319 KB)", " org.kohsuke.metainf-services:metainf-services:1.8:compile (7 KB)", - "USED INHERITED DEPENDENCIES [0]: ", "USED TRANSITIVE DEPENDENCIES [0]: ", + "USED INHERITED DIRECT DEPENDENCIES [0]: ", + "USED INHERITED TRANSITIVE DEPENDENCIES [0]: ", "POTENTIALLY UNUSED DIRECT DEPENDENCIES [0]: ", - "POTENTIALLY UNUSED INHERITED DEPENDENCIES [0]: ", - "POTENTIALLY UNUSED TRANSITIVE DEPENDENCIES [0]: " + "POTENTIALLY UNUSED TRANSITIVE DEPENDENCIES [0]: ", + "POTENTIALLY UNUSED INHERITED DIRECT DEPENDENCIES [0]: ", + "POTENTIALLY UNUSED INHERITED TRANSITIVE DEPENDENCIES [0]: " ); } @MavenTest - @DisplayName("Test that dependencies used indirectly (org.tukaani:xz is used indirectly)") void used_indirectly(MavenExecutionResult result) { + log.info("Test that dependencies used indirectly (org.tukaani:xz is used indirectly)"); assertThat(result).isSuccessful().out() .plain().contains( "-------------------------------------------------------", @@ -109,17 +116,19 @@ void used_indirectly(MavenExecutionResult result) { "USED DIRECT DEPENDENCIES [2]: ", " org.apache.commons:commons-compress:1.21:compile (994 KB)", " org.tukaani:xz:1.9:compile (113 KB)", - "USED INHERITED DEPENDENCIES [0]: ", "USED TRANSITIVE DEPENDENCIES [0]: ", + "USED INHERITED DIRECT DEPENDENCIES [0]: ", + "USED INHERITED TRANSITIVE DEPENDENCIES [0]: ", "POTENTIALLY UNUSED DIRECT DEPENDENCIES [0]: ", - "POTENTIALLY UNUSED INHERITED DEPENDENCIES [0]: ", - "POTENTIALLY UNUSED TRANSITIVE DEPENDENCIES [0]: " + "POTENTIALLY UNUSED TRANSITIVE DEPENDENCIES [0]: ", + "POTENTIALLY UNUSED INHERITED DIRECT DEPENDENCIES [0]: ", + "POTENTIALLY UNUSED INHERITED TRANSITIVE DEPENDENCIES [0]: " ); } @MavenTest - @DisplayName("Test that DepClean runs in a Maven project with processors") void processor_used(MavenExecutionResult result) { + log.info("Test that DepClean runs in a Maven project with processors"); assertThat(result).isSuccessful().out() .plain().contains( "-------------------------------------------------------", @@ -127,21 +136,23 @@ void processor_used(MavenExecutionResult result) { "-------------------------------------------------------", "USED DIRECT DEPENDENCIES [1]: ", " org.mapstruct:mapstruct-processor:1.4.2.Final:provided (1 MB)", - "USED INHERITED DEPENDENCIES [0]: ", "USED TRANSITIVE DEPENDENCIES [1]: ", " com.fasterxml.jackson.core:jackson-core:2.12.2:compile (356 KB)", + "USED INHERITED DIRECT DEPENDENCIES [0]: ", + "USED INHERITED TRANSITIVE DEPENDENCIES [0]: ", "POTENTIALLY UNUSED DIRECT DEPENDENCIES [1]: ", " com.fasterxml.jackson.core:jackson-databind:2.12.2:compile (1 MB)", - "POTENTIALLY UNUSED INHERITED DEPENDENCIES [0]: ", "POTENTIALLY UNUSED TRANSITIVE DEPENDENCIES [1]: ", - " com.fasterxml.jackson.core:jackson-annotations:2.12.2:compile (73 KB)" + " com.fasterxml.jackson.core:jackson-annotations:2.12.2:compile (73 KB)", + "POTENTIALLY UNUSED INHERITED DIRECT DEPENDENCIES [0]: ", + "POTENTIALLY UNUSED INHERITED TRANSITIVE DEPENDENCIES [0]: " ); } @MavenTest - @DisplayName("Test that DepClean creates a proper depclean-results.json file") void json_should_be_correct(MavenExecutionResult result) throws IOException { if (OsUtils.isUnix()) { + log.info("Test that DepClean creates a proper depclean-results.json file"); File expectedJsonFile = new File("src/test/resources/DepCleanMojoResources/depclean-results.json"); String expectedJsonContent = FileUtils.readFileToString(expectedJsonFile, Charset.defaultCharset()); assertThat(result).isSuccessful() @@ -153,8 +164,8 @@ void json_should_be_correct(MavenExecutionResult result) throws IOException { } @MavenTest - @DisplayName("Test that DepClean creates a proper pom-debloated.xml file") void debloated_pom_is_correct(MavenExecutionResult result) { + log.info("Test that DepClean creates a proper pom-debloated.xml file"); String path = "target/maven-it/se/kth/depclean/DepCleanMojoIT/debloated_pom_is_correct/project/pom-debloated.xml"; File generated_pom_debloated = new File(path); assertThat(result).isSuccessful() @@ -175,5 +186,39 @@ void debloated_pom_is_correct(MavenExecutionResult result) { hasSameTextualContentAs(new File( "src/test/resources/DepCleanMojoResources/pom-debloated.xml")); } + + @MavenTest + @Disabled + void unused_inherited_exists(MavenExecutionResult result) { + log.info("Test that DepClean detects unused inherited dependencies in a Maven project with a parent"); + assertThat(result).isSuccessful().out() + .plain().contains( + "-------------------------------------------------------", + " D E P C L E A N A N A L Y S I S R E S U L T S", + "-------------------------------------------------------", + "USED DIRECT DEPENDENCIES [0]: ", + "USED TRANSITIVE DEPENDENCIES [1]: ", + " com.fasterxml.jackson.core:jackson-core:2.12.2:compile (356 KB)", + "USED INHERITED DIRECT DEPENDENCIES [0]: ", + "USED INHERITED TRANSITIVE DEPENDENCIES [1]: ", + " org.junit.jupiter:junit-jupiter-api:5.9.1:test (202 KB)", + "POTENTIALLY UNUSED DIRECT DEPENDENCIES [1]: ", + " com.fasterxml.jackson.core:jackson-databind:2.12.2:compile (1 MB)", + "POTENTIALLY UNUSED TRANSITIVE DEPENDENCIES [1]: ", + " com.fasterxml.jackson.core:jackson-annotations:2.12.2:compile (73 KB)", + "POTENTIALLY UNUSED INHERITED DIRECT DEPENDENCIES [2]: ", + " org.junit.vintage:junit-vintage-engine:5.9.1:test (65 KB)", + " org.junit.jupiter:junit-jupiter:5.9.1:test (6 KB)", + "POTENTIALLY UNUSED INHERITED TRANSITIVE DEPENDENCIES [8]: ", + " org.junit.jupiter:junit-jupiter-params:5.9.1:test (565 KB)", + " junit:junit:4.13.2:test (375 KB)", + " org.junit.jupiter:junit-jupiter-engine:5.9.1:test (240 KB)", + " org.junit.platform:junit-platform-engine:1.9.1:test (183 KB)", + " org.junit.platform:junit-platform-commons:1.9.1:test (100 KB)", + " org.hamcrest:hamcrest-core:1.3:test (43 KB)", + " org.opentest4j:opentest4j:1.2.0:test (7 KB)", + " org.apiguardian:apiguardian-api:1.1.2:test (6 KB)" + ); + } } diff --git a/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/all_dependencies_unused/pom.xml b/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/all_dependencies_unused/pom.xml index d7b41c54..c8222bfa 100644 --- a/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/all_dependencies_unused/pom.xml +++ b/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/all_dependencies_unused/pom.xml @@ -53,7 +53,7 @@ se.kth.castor depclean-maven-plugin - 2.0.3 + 2.0.4-SNAPSHOT diff --git a/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/all_dependencies_used/pom.xml b/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/all_dependencies_used/pom.xml index 4c9761fc..c4f2ed7d 100644 --- a/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/all_dependencies_used/pom.xml +++ b/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/all_dependencies_used/pom.xml @@ -58,7 +58,7 @@ se.kth.castor depclean-maven-plugin - 2.0.2 + 2.0.4-SNAPSHOT diff --git a/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/empty_project/pom.xml b/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/empty_project/pom.xml index 01dfb304..ac5f09ad 100644 --- a/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/empty_project/pom.xml +++ b/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/empty_project/pom.xml @@ -21,7 +21,7 @@ se.kth.castor depclean-maven-plugin - 2.0.3 + 2.0.4-SNAPSHOT diff --git a/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/json_should_be_correct/pom.xml b/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/json_should_be_correct/pom.xml index f734695e..0bcb7ccc 100644 --- a/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/json_should_be_correct/pom.xml +++ b/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/json_should_be_correct/pom.xml @@ -45,7 +45,7 @@ se.kth.castor depclean-maven-plugin - 2.0.3 + 2.0.4-SNAPSHOT diff --git a/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/pom_should_be_correct/pom.xml b/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/pom_should_be_correct/pom.xml deleted file mode 100644 index 01dfb304..00000000 --- a/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/pom_should_be_correct/pom.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - 4.0.0 - - org.foo.bar - foobar - 1.0.0-SNAPSHOT - jar - foobar - - - UTF-8 - UTF-8 - 11 - 11 - - - - - - se.kth.castor - depclean-maven-plugin - 2.0.3 - - - - depclean - - - - - - - - diff --git a/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/processor_used/pom.xml b/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/processor_used/pom.xml index ebea8708..364df891 100644 --- a/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/processor_used/pom.xml +++ b/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/processor_used/pom.xml @@ -72,7 +72,7 @@ se.kth.castor depclean-maven-plugin - 2.0.3 + 2.0.4-SNAPSHOT diff --git a/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/unused_direct_only/pom.xml b/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/unused_direct_only/pom.xml index e5ed7028..8c4256b3 100644 --- a/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/unused_direct_only/pom.xml +++ b/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/unused_direct_only/pom.xml @@ -43,7 +43,7 @@ se.kth.castor depclean-maven-plugin - 2.0.3 + 2.0.4-SNAPSHOT diff --git a/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/unused_inherited_only/pom.xml b/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/unused_inherited_exists/pom.xml similarity index 88% rename from depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/unused_inherited_only/pom.xml rename to depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/unused_inherited_exists/pom.xml index 1c73fa5f..5d97c04b 100644 --- a/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/unused_inherited_only/pom.xml +++ b/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/unused_inherited_exists/pom.xml @@ -1,4 +1,4 @@ - + 4.0.0 @@ -15,8 +15,6 @@ - - org.foo.bar foobar 1.0.0-SNAPSHOT @@ -57,7 +55,7 @@ se.kth.castor depclean-maven-plugin - 2.0.3 + 2.0.4-SNAPSHOT @@ -66,13 +64,6 @@ - - org.apache.rat - apache-rat-plugin - - true - - diff --git a/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/unused_inherited_only/src/main/java/mypackage/Main.java b/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/unused_inherited_exists/src/main/java/mypackage/Main.java similarity index 100% rename from depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/unused_inherited_only/src/main/java/mypackage/Main.java rename to depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/unused_inherited_exists/src/main/java/mypackage/Main.java diff --git a/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/unused_inherited_only/src/test/java/mypackage/MainTest.java b/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/unused_inherited_exists/src/test/java/mypackage/MainTest.java similarity index 100% rename from depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/unused_inherited_only/src/test/java/mypackage/MainTest.java rename to depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/unused_inherited_exists/src/test/java/mypackage/MainTest.java diff --git a/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/unused_transitive_only/pom.xml b/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/unused_transitive_only/pom.xml index 323c77b0..422dad30 100644 --- a/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/unused_transitive_only/pom.xml +++ b/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/unused_transitive_only/pom.xml @@ -43,7 +43,7 @@ se.kth.castor depclean-maven-plugin - 2.0.3 + 2.0.4-SNAPSHOT diff --git a/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/used_indirectly/pom.xml b/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/used_indirectly/pom.xml index 28375134..68e42619 100644 --- a/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/used_indirectly/pom.xml +++ b/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/used_indirectly/pom.xml @@ -48,7 +48,7 @@ se.kth.castor depclean-maven-plugin - 2.0.3 + 2.0.4-SNAPSHOT diff --git a/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/used_java_record/pom.xml b/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/used_java_record/pom.xml index 16edf11e..db5a0f63 100644 --- a/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/used_java_record/pom.xml +++ b/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/used_java_record/pom.xml @@ -49,7 +49,7 @@ se.kth.castor depclean-maven-plugin - 2.0.3 + 2.0.4-SNAPSHOT diff --git a/depclean-maven-plugin/src/test/resources/log4j2-includes/console-appender_pattern-layout_colored.xml b/depclean-maven-plugin/src/test/resources/log4j2-includes/console-appender_pattern-layout_colored.xml new file mode 100644 index 00000000..11180eb8 --- /dev/null +++ b/depclean-maven-plugin/src/test/resources/log4j2-includes/console-appender_pattern-layout_colored.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/depclean-maven-plugin/src/test/resources/log4j2.xml b/depclean-maven-plugin/src/test/resources/log4j2.xml new file mode 100644 index 00000000..0b49af43 --- /dev/null +++ b/depclean-maven-plugin/src/test/resources/log4j2.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From e0d7256f518c8c1b53ec430a356d7a0c25962ca6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Soto=20Valero?= Date: Sat, 24 Dec 2022 15:51:00 +0100 Subject: [PATCH 08/11] Fix #124 completed --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index a0e84220..54057cf3 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ Configure the `pom.xml` file of your Maven project to use DepClean as part of th se.kth.castor depclean-maven-plugin - 2.0.3 + {DEPCLEAN_LATEST_VERSION} @@ -47,10 +47,10 @@ Configure the `pom.xml` file of your Maven project to use DepClean as part of th Or you can run DepClean directly from the command line. ```bash -cd PATH_TO_MAVEN_PROJECT -mvn compile +cd {PATH_TO_MAVEN_PROJECT} +mvn compile mvn compiler:testCompile -mvn se.kth.castor:depclean-maven-plugin:2.0.3:depclean +mvn se.kth.castor:depclean-maven-plugin:{DEPCLEAN_LATEST_VERSION}:depclean ``` Let's see an example of running DepClean version 2.0.1 in the project [Apache Commons Numbers](https://github.com/apache/commons-numbers/tree/master/commons-numbers-examples/examples-jmh)! @@ -84,7 +84,7 @@ For example, if you want to fail the build in the presence of unused direct depe se.kth.castor depclean-maven-plugin - 2.0.3 + {DEPCLEAN_LATEST_VERSION} @@ -102,7 +102,7 @@ For example, if you want to fail the build in the presence of unused direct depe Of course, it is also possible to execute DepClean with parameters directly from the command line. The previous example can be executed directly as follows: ```bash -mvn se.kth.castor:depclean-maven-plugin:2.0.3:depclean -DfailIfUnusedDirect=true -DignoreScopes=provided,test,runtime,system,import +mvn se.kth.castor:depclean-maven-plugin:{DEPCLEAN_LATEST_VERSION}:depclean -DfailIfUnusedDirect=true -DignoreScopes=provided,test,runtime,system,import ``` ## How does DepClean works? From e3f68072541bf20921d34b02c8fef5c5f5b286db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Soto=20Valero?= Date: Sat, 24 Dec 2022 16:19:01 +0100 Subject: [PATCH 09/11] Fix small issue with integration tests --- .../java/se/kth/depclean/DepCleanMojoIT.java | 18 +++++++++--------- .../depclean-results.json | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/depclean-maven-plugin/src/test/java/se/kth/depclean/DepCleanMojoIT.java b/depclean-maven-plugin/src/test/java/se/kth/depclean/DepCleanMojoIT.java index 1f7300c6..c07564eb 100644 --- a/depclean-maven-plugin/src/test/java/se/kth/depclean/DepCleanMojoIT.java +++ b/depclean-maven-plugin/src/test/java/se/kth/depclean/DepCleanMojoIT.java @@ -27,13 +27,13 @@ public class DepCleanMojoIT { @MavenTest void empty_project(MavenExecutionResult result) { - log.info("Test that DepClean runs in an empty Maven project"); + log.trace("Test that DepClean runs in an empty Maven project"); assertThat(result).isSuccessful(); // should pass } @MavenTest void used_java_record(MavenExecutionResult result) { - log.info("Test that DepClean identifies dependency used in Java record"); + log.trace("Test that DepClean identifies dependency used in Java record"); assertThat(result).isSuccessful().out() .plain().contains( "-------------------------------------------------------", @@ -54,7 +54,7 @@ void used_java_record(MavenExecutionResult result) { @MavenTest void all_dependencies_unused(MavenExecutionResult result) { - log.info("Test that DepClean identifies all dependencies as unused"); + log.trace("Test that DepClean identifies all dependencies as unused"); assertThat(result).isSuccessful().out() .plain().contains( "-------------------------------------------------------", @@ -83,7 +83,7 @@ void all_dependencies_unused(MavenExecutionResult result) { @MavenTest void all_dependencies_used(MavenExecutionResult result) { - log.info("Test that DepClean identifies all dependencies as used"); + log.trace("Test that DepClean identifies all dependencies as used"); assertThat(result).isSuccessful().out() .plain().contains( "-------------------------------------------------------", @@ -107,7 +107,7 @@ void all_dependencies_used(MavenExecutionResult result) { @MavenTest void used_indirectly(MavenExecutionResult result) { - log.info("Test that dependencies used indirectly (org.tukaani:xz is used indirectly)"); + log.trace("Test that dependencies used indirectly (org.tukaani:xz is used indirectly)"); assertThat(result).isSuccessful().out() .plain().contains( "-------------------------------------------------------", @@ -128,7 +128,7 @@ void used_indirectly(MavenExecutionResult result) { @MavenTest void processor_used(MavenExecutionResult result) { - log.info("Test that DepClean runs in a Maven project with processors"); + log.trace("Test that DepClean runs in a Maven project with processors"); assertThat(result).isSuccessful().out() .plain().contains( "-------------------------------------------------------", @@ -152,7 +152,7 @@ void processor_used(MavenExecutionResult result) { @MavenTest void json_should_be_correct(MavenExecutionResult result) throws IOException { if (OsUtils.isUnix()) { - log.info("Test that DepClean creates a proper depclean-results.json file"); + log.trace("Test that DepClean creates a proper depclean-results.json file"); File expectedJsonFile = new File("src/test/resources/DepCleanMojoResources/depclean-results.json"); String expectedJsonContent = FileUtils.readFileToString(expectedJsonFile, Charset.defaultCharset()); assertThat(result).isSuccessful() @@ -165,7 +165,7 @@ void json_should_be_correct(MavenExecutionResult result) throws IOException { @MavenTest void debloated_pom_is_correct(MavenExecutionResult result) { - log.info("Test that DepClean creates a proper pom-debloated.xml file"); + log.trace("Test that DepClean creates a proper pom-debloated.xml file"); String path = "target/maven-it/se/kth/depclean/DepCleanMojoIT/debloated_pom_is_correct/project/pom-debloated.xml"; File generated_pom_debloated = new File(path); assertThat(result).isSuccessful() @@ -190,7 +190,7 @@ void debloated_pom_is_correct(MavenExecutionResult result) { @MavenTest @Disabled void unused_inherited_exists(MavenExecutionResult result) { - log.info("Test that DepClean detects unused inherited dependencies in a Maven project with a parent"); + log.trace("Test that DepClean detects unused inherited dependencies in a Maven project with a parent"); assertThat(result).isSuccessful().out() .plain().contains( "-------------------------------------------------------", diff --git a/depclean-maven-plugin/src/test/resources/DepCleanMojoResources/depclean-results.json b/depclean-maven-plugin/src/test/resources/DepCleanMojoResources/depclean-results.json index 242a4c66..08e5fc2b 100644 --- a/depclean-maven-plugin/src/test/resources/DepCleanMojoResources/depclean-results.json +++ b/depclean-maven-plugin/src/test/resources/DepCleanMojoResources/depclean-results.json @@ -6,7 +6,7 @@ "version": "1.0.0-SNAPSHOT", "packaging": "jar", "omitted": false, - "size": 2861, + "size": 2862, "type": "unknown", "status": "unknown", "parent": "unknown", From e0f16c1fb0e1f8f38e06b7be183016d1fe08588f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Soto=20Valero?= Date: Sat, 24 Dec 2022 16:31:01 +0100 Subject: [PATCH 10/11] Set back change --- .../main/java/se/kth/depclean/graph/MavenDependencyGraph.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depclean-maven-plugin/src/main/java/se/kth/depclean/graph/MavenDependencyGraph.java b/depclean-maven-plugin/src/main/java/se/kth/depclean/graph/MavenDependencyGraph.java index bc089385..fac06ebe 100644 --- a/depclean-maven-plugin/src/main/java/se/kth/depclean/graph/MavenDependencyGraph.java +++ b/depclean-maven-plugin/src/main/java/se/kth/depclean/graph/MavenDependencyGraph.java @@ -167,7 +167,7 @@ private Dependency toDepCleanDependency(Artifact artifact) { return new Dependency( artifact.getGroupId(), artifact.getArtifactId(), - artifact.getVersion(), + artifact.getBaseVersion(), artifact.getScope(), artifact.getFile() ); From f67d268f0b8b23e7e9f9925c149099dedd3ea719 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Soto=20Valero?= Date: Sat, 24 Dec 2022 16:44:44 +0100 Subject: [PATCH 11/11] Add version in lombok for IT --- .../kth/depclean/DepCleanMojoIT/all_dependencies_used/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/all_dependencies_used/pom.xml b/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/all_dependencies_used/pom.xml index c4f2ed7d..1b18fd47 100644 --- a/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/all_dependencies_used/pom.xml +++ b/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/all_dependencies_used/pom.xml @@ -48,7 +48,7 @@ org.projectlombok lombok - RELEASE + 1.18.24 compile