From ab74975babed3a232e8e36ceb1f161a60d9fc94d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Soto=20Valero?= Date: Tue, 17 Jan 2023 11:06:09 +0100 Subject: [PATCH] Fix #151 --- .../ProjectDependencyAnalysisBuilder.java | 34 +++++++- .../depclean/core/model/ProjectContext.java | 14 +++- .../java/se/kth/depclean/DepCleanMojoIT.java | 32 ++++++++ .../DepCleanMojoIT/ignored_scopes/pom.xml | 77 +++++++++++++++++++ .../ignored_scopes/src/main/java/Main.java | 3 + 5 files changed, 156 insertions(+), 4 deletions(-) create mode 100644 depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/ignored_scopes/pom.xml create mode 100644 depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/ignored_scopes/src/main/java/Main.java 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 b25a8219..f3eb382b 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 @@ -5,6 +5,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.Iterator; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; @@ -13,6 +14,7 @@ import se.kth.depclean.core.model.ClassName; import se.kth.depclean.core.model.Dependency; import se.kth.depclean.core.model.ProjectContext; +import se.kth.depclean.core.model.Scope; /** * Builds the analysis given the declared dependencies and the one actually used. @@ -60,6 +62,12 @@ public ProjectDependencyAnalysis analyse() { ignoreDependency(usedInheritedDirectDependencies, unusedInheritedDirectDependencies, dependencyToIgnore); ignoreDependency(usedInheritedTransitiveDependencies, unusedInheritedTransitiveDependencies, dependencyToIgnore); }); + // ignore scopes + ignoreDependencyWithIgnoredScope(usedDirectDependencies, unusedDirectDependencies, context.getIgnoredScopes()); + ignoreDependencyWithIgnoredScope(usedTransitiveDependencies, unusedTransitiveDependencies, context.getIgnoredScopes()); + ignoreDependencyWithIgnoredScope(usedInheritedDirectDependencies, unusedInheritedDirectDependencies, context.getIgnoredScopes()); + ignoreDependencyWithIgnoredScope(usedInheritedTransitiveDependencies, unusedInheritedTransitiveDependencies, context.getIgnoredScopes()); + return new ProjectDependencyAnalysis( usedDirectDependencies, usedTransitiveDependencies, @@ -138,8 +146,8 @@ private Set getUnusedDependencies(Set baseDependencies, } /** - * 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. + * 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. @@ -155,4 +163,26 @@ private void ignoreDependency(Set usedDependencies, Set } } } + + /** + * If the scope of the unused dependency is to be ignored, then add the dependency to the set of used dependencies and remove it from the used set. + * + * @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 ignoredScopes The set of scopes to ignore. + */ + private void ignoreDependencyWithIgnoredScope(Set usedDependencies, Set unusedDependencies, Set ignoredScopes) { + for (Iterator i = unusedDependencies.iterator(); i.hasNext(); ) { + Dependency unusedDependency = i.next(); + List scopesToIgnore = ignoredScopes.stream().map(Scope::getValue).collect(Collectors.toList()); + log.debug("Scopes to ignore: {}", scopesToIgnore); + log.debug("Unused dependency scope: {}", unusedDependency.getScope()); + if (scopesToIgnore.contains(unusedDependency.getScope())) { + log.debug("Ignoring dependency {} with scope {}", unusedDependency, unusedDependency.getScope()); + usedDependencies.add(unusedDependency); + i.remove(); + } + } + } + } 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 1a6b82ba..9b8806b7 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 @@ -117,15 +117,25 @@ public boolean ignoreTests() { private void populateDependenciesAndClassesMap(Set dependencies) { dependencies.stream() - .filter(this::excludeScopes) + .filter(this::excludeDependenciesBasedOnIgnoredScopes) .forEach(dc -> { log.debug("Adding dependency {} with related classes: {}", dc, dc.getRelatedClasses()); classesPerDependency.putAll(dc, dc.getRelatedClasses()); }); + + } - private boolean excludeScopes(Dependency dc) { + /** + * Exclude dependencies based on the scopes. + * + * @param dc the dependency to check + * @return true if the dependency should be excluded, false otherwise + */ + private boolean excludeDependenciesBasedOnIgnoredScopes(Dependency dc) { final String declaredScope = dc.getScope(); + log.debug("ignoreScopes: " + ignoredScopes); + log.debug("dc = " + dc + " declaredScope = " + declaredScope); return ignoredScopes.stream() .map(Scope::getValue) .noneMatch(declaredScope::equalsIgnoreCase); 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 c07564eb..cabfc04f 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 @@ -220,5 +220,37 @@ void unused_inherited_exists(MavenExecutionResult result) { " org.apiguardian:apiguardian-api:1.1.2:test (6 KB)" ); } + + + @MavenTest + @Disabled + void ignored_scopes(MavenExecutionResult result) { + log.trace("Test that DepClean ignores dependencies (considers them as used) with the ignored scopes"); + 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 [2]: ", + " com.fasterxml.jackson.core:jackson-core:2.12.2:compile (356 KB)", + " commons-io:commons-io:2.11.0:test (319 KB)", + "USED TRANSITIVE DEPENDENCIES [2]: ", + " com.fasterxml.jackson.core:jackson-core:2.12.2:provided (356 KB)", + " com.fasterxml.jackson.core:jackson-annotations:2.12.2:provided (73 KB)", + "USED INHERITED DIRECT DEPENDENCIES [0]: ", + "USED INHERITED TRANSITIVE DEPENDENCIES [0]: ", + "POTENTIALLY UNUSED DIRECT DEPENDENCIES [1]: ", + " com.google.guava:guava:31.0.1-jre:compile (2 MB)", + "POTENTIALLY UNUSED TRANSITIVE DEPENDENCIES [6]: ", + " org.checkerframework:checker-qual:3.12.0:compile (203 KB)", + " 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:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava:compile (2 KB)", + "POTENTIALLY UNUSED INHERITED DIRECT DEPENDENCIES [0]: ", + "POTENTIALLY UNUSED INHERITED TRANSITIVE DEPENDENCIES [0]: " + ); + } } diff --git a/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/ignored_scopes/pom.xml b/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/ignored_scopes/pom.xml new file mode 100644 index 00000000..18619a87 --- /dev/null +++ b/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/ignored_scopes/pom.xml @@ -0,0 +1,77 @@ + + + 4.0.0 + + org.foo.bar + foobar + 1.0.0-SNAPSHOT + jar + foobar + + + UTF-8 + UTF-8 + 11 + 11 + + + + + + com.fasterxml.jackson.core + jackson-databind + 2.12.2 + provided + + + + com.google.guava + guava + 31.0.1-jre + + + + + commons-io + commons-io + 2.11.0 + test + + + + + + + com.soebes.itf.jupiter.extension + itf-failure-plugin + 0.9.0 + + + first_very_simple + initialize + + failure + + + + + + se.kth.castor + depclean-maven-plugin + 2.0.5 + + + + depclean + + + test,provided,import,runtime + true + + + + + + + diff --git a/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/ignored_scopes/src/main/java/Main.java b/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/ignored_scopes/src/main/java/Main.java new file mode 100644 index 00000000..6ac01ed0 --- /dev/null +++ b/depclean-maven-plugin/src/test/resources-its/se/kth/depclean/DepCleanMojoIT/ignored_scopes/src/main/java/Main.java @@ -0,0 +1,3 @@ +public class Main { + int field = 42; +} \ No newline at end of file