From 468a9951b0ced8fe132414a01d570e1d12a8d498 Mon Sep 17 00:00:00 2001 From: Martin Vitez Date: Wed, 30 Apr 2014 11:35:14 +0200 Subject: [PATCH] BUG-114: added artifact version check in yang-maven-plugin. This patch bypasses use of maven aether due to version incompatibility between maven 3.0.x and 3.1.x. Signed-off-by: Martin Vitez Change-Id: If1c09a59353ef32a320131f7cbdbe92aa66acae2 --- .../plugin/it/YangToSourcesPluginTestIT.java | 7 ++ .../src/test/resources/InvalidVersion/pom.xml | 82 ++++++++++++++ .../yangtools/yang2sources/plugin/Util.java | 104 ++++++++++++++++++ .../plugin/YangToSourcesMojo.java | 21 +++- .../plugin/GenerateSourcesTest.java | 7 ++ 5 files changed, 218 insertions(+), 3 deletions(-) create mode 100644 yang/yang-maven-plugin-it/src/test/resources/InvalidVersion/pom.xml diff --git a/yang/yang-maven-plugin-it/src/test/java/org/opendaylight/yangtools/yang2sources/plugin/it/YangToSourcesPluginTestIT.java b/yang/yang-maven-plugin-it/src/test/java/org/opendaylight/yangtools/yang2sources/plugin/it/YangToSourcesPluginTestIT.java index 72796c6752..daf737089d 100644 --- a/yang/yang-maven-plugin-it/src/test/java/org/opendaylight/yangtools/yang2sources/plugin/it/YangToSourcesPluginTestIT.java +++ b/yang/yang-maven-plugin-it/src/test/java/org/opendaylight/yangtools/yang2sources/plugin/it/YangToSourcesPluginTestIT.java @@ -109,6 +109,13 @@ public class YangToSourcesPluginTestIT { v.verifyTextInLog("[WARNING] yang-to-sources: No code generators provided"); } + @Test + public void testInvalidVersion() throws Exception { + Verifier v = setUp("InvalidVersion/", false); + v.verifyErrorFreeLog(); + v.verifyTextInLog("[WARNING] yang-to-sources: Dependency resolution conflict:"); + } + @Test public void testUnknownGenerator() throws Exception { Verifier v = setUp("UnknownGenerator/", true); diff --git a/yang/yang-maven-plugin-it/src/test/resources/InvalidVersion/pom.xml b/yang/yang-maven-plugin-it/src/test/resources/InvalidVersion/pom.xml new file mode 100644 index 0000000000..d33ca7d77f --- /dev/null +++ b/yang/yang-maven-plugin-it/src/test/resources/InvalidVersion/pom.xml @@ -0,0 +1,82 @@ + + + + + 4.0.0 + + org.opendaylight.yangtools + 0.5-SNAPSHOT + test + + + + + + opendaylight-mirror + opendaylight-mirror + http://nexus.opendaylight.org/content/groups/public/ + + false + + + true + never + + + + + + org.opendaylight.yangtools + yang-common + 0.6.1 + + + + + + + + org.opendaylight.yangtools + yang-maven-plugin + ${it-project.version} + + + + generate-sources + + + ../files + false + + + + + + org.opendaylight.yangtools.yang2sources.spi.ResourceProviderTestImpl + + + outDir/ + + + + + + + + + org.opendaylight.yangtools + yang-maven-plugin-spi + ${it-project.version} + test-jar + + + + + + diff --git a/yang/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/Util.java b/yang/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/Util.java index b1dee91efe..a3c2110b8c 100644 --- a/yang/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/Util.java +++ b/yang/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/Util.java @@ -17,6 +17,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Enumeration; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; @@ -25,12 +26,18 @@ import java.util.zip.ZipFile; import org.apache.commons.io.FileUtils; import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.repository.ArtifactRepository; +import org.apache.maven.artifact.resolver.ArtifactResolutionRequest; +import org.apache.maven.artifact.resolver.ArtifactResolutionResult; +import org.apache.maven.model.Dependency; +import org.apache.maven.model.Plugin; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugin.logging.Log; import org.apache.maven.project.MavenProject; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.parser.util.NamedFileInputStream; +import org.apache.maven.repository.RepositorySystem; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; @@ -146,6 +153,103 @@ final class Util { return dependencies; } + /** + * Read current project dependencies and check if it don't grab incorrect + * artifacts versions which could be in conflict with plugin dependencies. + * + * @param project + * current project + * @param repoSystem + * repository system + * @param localRepo + * local repository + * @param remoteRepos + * remote repositories + * @param log + * logger + */ + static void checkClasspath(MavenProject project, RepositorySystem repoSystem, ArtifactRepository localRepo, + List remoteRepos, Log log) { + Plugin plugin = project.getPlugin(YangToSourcesMojo.PLUGIN_NAME); + if (plugin == null) { + log.warn(message("%s not found, dependencies version check skipped", YangToSourcesProcessor.LOG_PREFIX, + YangToSourcesMojo.PLUGIN_NAME)); + } else { + Map> pluginDependencies = new HashMap<>(); + getPluginTransitiveDependencies(plugin, pluginDependencies, repoSystem, localRepo, remoteRepos, log); + + Set projectDependencies = project.getDependencyArtifacts(); + for (Map.Entry> entry : pluginDependencies.entrySet()) { + checkArtifact(entry.getKey(), projectDependencies, log); + for (Artifact dependency : entry.getValue()) { + checkArtifact(dependency, projectDependencies, log); + } + } + } + } + + /** + * Read transitive dependencies of given plugin and store them in map. + * + * @param plugin + * plugin to read + * @param map + * map, where founded transitive dependencies will be stored + * @param repoSystem + * repository system + * @param localRepository + * local repository + * @param remoteRepos + * list of remote repositories + * @param log + * logger + */ + private static void getPluginTransitiveDependencies(Plugin plugin, Map> map, + RepositorySystem repoSystem, ArtifactRepository localRepository, List remoteRepos, + Log log) { + + List pluginDependencies = plugin.getDependencies(); + for (Dependency dep : pluginDependencies) { + Artifact artifact = repoSystem.createDependencyArtifact(dep); + + ArtifactResolutionRequest request = new ArtifactResolutionRequest(); + request.setArtifact(artifact); + request.setResolveTransitively(true); + request.setLocalRepository(localRepository); + request.setRemoteRepositories(remoteRepos); + + ArtifactResolutionResult result = repoSystem.resolve(request); + Set pluginDependencyDependencies = result.getArtifacts(); + map.put(artifact, pluginDependencyDependencies); + } + } + + /** + * Check artifact against collection of dependencies. If collection contains + * artifact with same groupId and artifactId, but different version, logs a + * warning. + * + * @param artifact + * artifact to check + * @param dependencies + * collection of dependencies + * @param log + * logger + */ + private static void checkArtifact(Artifact artifact, Collection dependencies, Log log) { + for (org.apache.maven.artifact.Artifact d : dependencies) { + if (artifact.getGroupId().equals(d.getGroupId()) && artifact.getArtifactId().equals(d.getArtifactId())) { + if (!(artifact.getVersion().equals(d.getVersion()))) { + log.warn(message("Dependency resolution conflict:", YangToSourcesProcessor.LOG_PREFIX)); + log.warn(message("'%s' dependency [%s] has different version than one " + + "declared in current project [%s]. It is recommended to fix this problem " + + "because it may cause compilation errors.", YangToSourcesProcessor.LOG_PREFIX, + YangToSourcesMojo.PLUGIN_NAME, artifact, d)); + } + } + } + } + private static final String JAR_SUFFIX = ".jar"; private static boolean isJar(File element) { diff --git a/yang/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/YangToSourcesMojo.java b/yang/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/YangToSourcesMojo.java index 174e2acf5f..1f678a0223 100644 --- a/yang/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/YangToSourcesMojo.java +++ b/yang/yang-maven-plugin/src/main/java/org/opendaylight/yangtools/yang2sources/plugin/YangToSourcesMojo.java @@ -13,6 +13,7 @@ import java.util.Collections; import java.util.List; import java.util.Set; +import org.apache.maven.artifact.repository.ArtifactRepository; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; @@ -22,6 +23,7 @@ import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; import org.apache.maven.project.MavenProject; +import org.apache.maven.repository.RepositorySystem; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl; import org.opendaylight.yangtools.yang2sources.plugin.ConfigArg.CodeGeneratorArg; @@ -46,6 +48,7 @@ import com.google.common.annotations.VisibleForTesting; */ @Mojo(name = "generate-sources", defaultPhase = LifecyclePhase.GENERATE_SOURCES, requiresDependencyResolution = ResolutionScope.COMPILE, requiresProject = true) public final class YangToSourcesMojo extends AbstractMojo { + public static final String PLUGIN_NAME = "org.opendaylight.yangtools:yang-maven-plugin"; /** * Classes implementing {@link CodeGenerator} interface. An instance will be @@ -78,8 +81,17 @@ public final class YangToSourcesMojo extends AbstractMojo { private YangToSourcesProcessor yangToSourcesProcessor; - public YangToSourcesMojo() { + @Component + private RepositorySystem repoSystem; + + @Parameter( readonly = true, defaultValue = "${localRepository}" ) + private ArtifactRepository localRepository; + + @Parameter( readonly = true, defaultValue = "${project.remoteArtifactRepositories}" ) + private List remoteRepos; + + public YangToSourcesMojo() { } public void setProject(MavenProject project) { @@ -94,6 +106,9 @@ public final class YangToSourcesMojo extends AbstractMojo { @Override public void execute() throws MojoExecutionException, MojoFailureException { StaticLoggerBinder.getSingleton().setMavenLog(this.getLog()); + + Util.checkClasspath(project, repoSystem, localRepository, remoteRepos, getLog()); + if (yangToSourcesProcessor == null) { List codeGeneratorArgs = processCodeGenerators(codeGenerators); @@ -101,8 +116,8 @@ public final class YangToSourcesMojo extends AbstractMojo { File yangFilesRootFile = processYangFilesRootDir(yangFilesRootDir, project.getBasedir()); File[] excludedFiles = processExcludeFiles(excludeFiles, yangFilesRootFile); - yangToSourcesProcessor = new YangToSourcesProcessor(buildContext, getLog(), yangFilesRootFile, excludedFiles, - codeGeneratorArgs, project, inspectDependencies); + yangToSourcesProcessor = new YangToSourcesProcessor(buildContext, getLog(), yangFilesRootFile, + excludedFiles, codeGeneratorArgs, project, inspectDependencies); } yangToSourcesProcessor.execute(); } diff --git a/yang/yang-maven-plugin/src/test/java/org/opendaylight/yangtools/yang2sources/plugin/GenerateSourcesTest.java b/yang/yang-maven-plugin/src/test/java/org/opendaylight/yangtools/yang2sources/plugin/GenerateSourcesTest.java index 3ab8a8c228..3389839e32 100644 --- a/yang/yang-maven-plugin/src/test/java/org/opendaylight/yangtools/yang2sources/plugin/GenerateSourcesTest.java +++ b/yang/yang-maven-plugin/src/test/java/org/opendaylight/yangtools/yang2sources/plugin/GenerateSourcesTest.java @@ -16,9 +16,12 @@ import static org.mockito.Mockito.*; import java.io.File; import java.io.IOException; import java.util.Collection; +import java.util.Collections; import java.util.Map; import java.util.Set; +import org.apache.maven.model.Plugin; +import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugin.logging.Log; import org.apache.maven.project.MavenProject; import org.junit.Before; @@ -40,6 +43,8 @@ public class GenerateSourcesTest { private File outDir; @Mock private MavenProject project; + @Mock + private Plugin plugin; @Before public void setUp() throws Exception { @@ -56,6 +61,8 @@ public class GenerateSourcesTest { mock); mojo = new YangToSourcesMojo(processor); doReturn(new File("")).when(project).getBasedir(); + doReturn(Collections.emptyList()).when(plugin).getDependencies(); + doReturn(plugin).when(project).getPlugin(YangToSourcesMojo.PLUGIN_NAME); mojo.setProject(project); } -- 2.36.6