diff options
author | Julien HENRY <julien.henry@sonarsource.com> | 2014-09-08 22:12:13 +0200 |
---|---|---|
committer | Julien HENRY <julien.henry@sonarsource.com> | 2014-09-08 22:12:13 +0200 |
commit | cc3cabc3e7aa9c1467d2994ef78ae38c16f2e0dd (patch) | |
tree | 0a7a08c7e184fa2e5488ee06536a2e5cad67551c /sonar-maven-plugin | |
parent | b8a4470a8cbcfc430fcde54614f7cf31708e48d9 (diff) | |
download | sonarqube-cc3cabc3e7aa9c1467d2994ef78ae38c16f2e0dd.tar.gz sonarqube-cc3cabc3e7aa9c1467d2994ef78ae38c16f2e0dd.zip |
SONAR-5604 Design plugin should no more rely on Maven APIs
Diffstat (limited to 'sonar-maven-plugin')
-rw-r--r-- | sonar-maven-plugin/pom.xml | 4 | ||||
-rw-r--r-- | sonar-maven-plugin/src/main/java/org/sonar/maven/SonarMojo.java | 138 |
2 files changed, 141 insertions, 1 deletions
diff --git a/sonar-maven-plugin/pom.xml b/sonar-maven-plugin/pom.xml index d59510fd17b..5a93cf227ad 100644 --- a/sonar-maven-plugin/pom.xml +++ b/sonar-maven-plugin/pom.xml @@ -20,6 +20,10 @@ <artifactId>sonar-runner-api</artifactId> </dependency> <dependency> + <groupId>com.google.code.gson</groupId> + <artifactId>gson</artifactId> + </dependency> + <dependency> <groupId>org.apache.maven</groupId> <artifactId>maven-plugin-api</artifactId> <scope>provided</scope> diff --git a/sonar-maven-plugin/src/main/java/org/sonar/maven/SonarMojo.java b/sonar-maven-plugin/src/main/java/org/sonar/maven/SonarMojo.java index dfc313844a2..b3bbc9bb70b 100644 --- a/sonar-maven-plugin/src/main/java/org/sonar/maven/SonarMojo.java +++ b/sonar-maven-plugin/src/main/java/org/sonar/maven/SonarMojo.java @@ -31,19 +31,34 @@ import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProjectBuilder; +import org.apache.maven.shared.dependency.tree.DependencyNode; import org.apache.maven.shared.dependency.tree.DependencyTreeBuilder; +import org.apache.maven.shared.dependency.tree.DependencyTreeBuilderException; +import org.apache.maven.shared.dependency.tree.filter.AncestorOrSelfDependencyNodeFilter; +import org.apache.maven.shared.dependency.tree.filter.DependencyNodeFilter; +import org.apache.maven.shared.dependency.tree.filter.StateDependencyNodeFilter; +import org.apache.maven.shared.dependency.tree.traversal.BuildingDependencyNodeVisitor; +import org.apache.maven.shared.dependency.tree.traversal.CollectingDependencyNodeVisitor; +import org.apache.maven.shared.dependency.tree.traversal.DependencyNodeVisitor; +import org.apache.maven.shared.dependency.tree.traversal.FilteringDependencyNodeVisitor; import org.sonar.runner.api.EmbeddedRunner; import org.sonar.runner.api.RunnerProperties; import org.sonar.runner.api.ScanProperties; import java.io.File; import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Stack; /** * @goal sonar * @aggregator * @requiresDependencyResolution test + * @deprecated Only kept for backward compatibility with old version of SQ Maven plugin */ +@Deprecated public final class SonarMojo extends AbstractMojo { /** @@ -151,7 +166,8 @@ public final class SonarMojo extends AbstractMojo { .setProperty(ScanProperties.PROJECT_VERSION, toString(project.getVersion())) .setProperty(ScanProperties.PROJECT_NAME, toString(project.getName())) .setProperty(ScanProperties.PROJECT_DESCRIPTION, toString(project.getDescription())) - .setProperty(ScanProperties.PROJECT_SOURCE_DIRS, "."); + .setProperty(ScanProperties.PROJECT_SOURCE_DIRS, ".") + .setProperty("sonar.maven.projectDependencies", dependenciesToJson(collectProjectDependencies())); // Exclude log implementation to not conflict with Maven 3.1 logging impl runner.mask("org.slf4j.LoggerFactory") // Include slf4j Logger that is exposed by some Sonar components @@ -176,6 +192,126 @@ public final class SonarMojo extends AbstractMojo { } } + private static class Dependency { + + private final String key; + private final String version; + private String scope; + List<Dependency> dependencies = new ArrayList<SonarMojo.Dependency>(); + + public Dependency(String key, String version) { + this.key = key; + this.version = version; + } + + public String key() { + return key; + } + + public String version() { + return version; + } + + public String scope() { + return scope; + } + + public Dependency setScope(String scope) { + this.scope = scope; + return this; + } + + public List<Dependency> dependencies() { + return dependencies; + } + } + + private List<Dependency> collectProjectDependencies() { + final List<Dependency> result = new ArrayList<SonarMojo.Dependency>(); + try { + DependencyNode root = dependencyTreeBuilder.buildDependencyTree(project, localRepository, artifactFactory, artifactMetadataSource, null, artifactCollector); + + DependencyNodeVisitor visitor = new BuildingDependencyNodeVisitor(new DependencyNodeVisitor() { + + private Stack<Dependency> stack = new Stack<SonarMojo.Dependency>(); + + public boolean visit(DependencyNode node) { + if (node.getParent() != null && node.getParent() != node) { + Dependency dependency = toDependency(node); + if (stack.isEmpty()) { + result.add(dependency); + } + else { + stack.peek().dependencies().add(dependency); + } + stack.push(dependency); + } + return true; + } + + public boolean endVisit(DependencyNode node) { + if (!stack.isEmpty()) { + stack.pop(); + } + return true; + } + }); + + // mode verbose OFF : do not show the same lib many times + DependencyNodeFilter filter = StateDependencyNodeFilter.INCLUDED; + + CollectingDependencyNodeVisitor collectingVisitor = new CollectingDependencyNodeVisitor(); + DependencyNodeVisitor firstPassVisitor = new FilteringDependencyNodeVisitor(collectingVisitor, filter); + root.accept(firstPassVisitor); + + DependencyNodeFilter secondPassFilter = new AncestorOrSelfDependencyNodeFilter(collectingVisitor.getNodes()); + visitor = new FilteringDependencyNodeVisitor(visitor, secondPassFilter); + + root.accept(visitor); + + } catch (DependencyTreeBuilderException e) { + throw new IllegalStateException("Can not load the graph of dependencies of the project " + getSonarKey(project), e); + } + return result; + } + + private Dependency toDependency(DependencyNode node) { + String key = String.format("%s:%s", node.getArtifact().getGroupId(), node.getArtifact().getArtifactId()); + String version = node.getArtifact().getBaseVersion(); + return new Dependency(key, version).setScope(node.getArtifact().getScope()); + } + + private String dependenciesToJson(List<Dependency> deps) { + StringBuilder json = new StringBuilder(); + json.append('['); + serializeDeps(json, deps); + json.append(']'); + return json.toString(); + } + + private void serializeDeps(StringBuilder json, List<Dependency> deps) { + for (Iterator<Dependency> dependencyIt = deps.iterator(); dependencyIt.hasNext();) { + serializeDep(json, dependencyIt.next()); + if (dependencyIt.hasNext()) { + json.append(','); + } + } + } + + private void serializeDep(StringBuilder json, Dependency dependency) { + json.append("{"); + json.append("\"k\":"); + json.append(dependency.key()); + json.append(",\"v\":\""); + json.append(dependency.version()); + json.append("\",\"s\":\""); + json.append(dependency.scope()); + json.append("\",\"d\":["); + serializeDeps(json, dependency.dependencies()); + json.append("]"); + json.append("}"); + } + private ArtifactVersion getMavenVersion() { return runtimeInformation.getApplicationVersion(); } |