diff --git a/ReleaseNotes.md b/ReleaseNotes.md
index 0f17e8fdb4..2043632f18 100644
--- a/ReleaseNotes.md
+++ b/ReleaseNotes.md
@@ -2,6 +2,11 @@
## 2.5 (NOT YET RELEASED)
+ * [Fixed Issue 187][issue-187]
+
+ create target directory when run dependency update report.
+ Thanks to Ilja Dubinin.
+
* [Pull Request #189][pull-189]
Fixed inccorect links. Thanks to Anton Johansson.
@@ -68,4 +73,5 @@
[issue-167]: https://github.com/mojohaus/versions-maven-plugin/issues/167
[issue-168]: https://github.com/mojohaus/versions-maven-plugin/issues/168
[issue-177]: https://github.com/mojohaus/versions-maven-plugin/issues/177
+[issue-187]: https://github.com/mojohaus/versions-maven-plugin/issues/187
[pull-189]: https://github.com/mojohaus/versions-maven-plugin/pull/189
diff --git a/src/it/it-rules-via-classpath-001/invoker.properties b/src/it/it-rules-via-classpath-001/invoker.properties
new file mode 100644
index 0000000000..681243c8ef
--- /dev/null
+++ b/src/it/it-rules-via-classpath-001/invoker.properties
@@ -0,0 +1,2 @@
+invoker.goals=${project.groupId}:${project.artifactId}:${project.version}:use-latest-releases
+invoker.buildResult = failure
diff --git a/src/it/it-rules-via-classpath-001/pom.xml b/src/it/it-rules-via-classpath-001/pom.xml
new file mode 100644
index 0000000000..6a52cfba4a
--- /dev/null
+++ b/src/it/it-rules-via-classpath-001/pom.xml
@@ -0,0 +1,32 @@
+
+ 4.0.0
+
+ localhost
+ it-rules-via-classpath-001
+ 1.0
+ pom
+ GH-193: Fail if resource is not found
+
+
+
+ localhost
+ version-rules
+ 3.0.1
+
+
+
+
+
+
+ @project.groupId@
+ @project.artifactId@
+ @project.version@
+
+ classpath:///package/foo/bar/rule-set.xml
+
+
+
+
+
+
diff --git a/src/it/it-rules-via-classpath-001/verify.bsh b/src/it/it-rules-via-classpath-001/verify.bsh
new file mode 100644
index 0000000000..e79df00228
--- /dev/null
+++ b/src/it/it-rules-via-classpath-001/verify.bsh
@@ -0,0 +1,22 @@
+import java.io.*;
+import org.codehaus.plexus.util.FileUtils;
+
+try
+{
+ File file = new File( basedir, "build.log" );
+ String buf = FileUtils.fileRead( file, "UTF-8" );
+ String expectedMessage = "Resource \"classpath:///package/foo/bar/rule-set.xml\" not found in classpath.";
+
+ if ( buf.indexOf( expectedMessage ) < 0 )
+ {
+ System.err.println( "Build should have failed as the requested resource is not present." );
+ return false;
+ }
+}
+catch( Throwable t )
+{
+ t.printStackTrace();
+ return false;
+}
+
+return true;
diff --git a/src/it/it-rules-via-classpath-002/invoker.properties b/src/it/it-rules-via-classpath-002/invoker.properties
new file mode 100644
index 0000000000..8d6b718473
--- /dev/null
+++ b/src/it/it-rules-via-classpath-002/invoker.properties
@@ -0,0 +1,2 @@
+invoker.goals=clean install ${project.groupId}:${project.artifactId}:${project.version}:use-latest-releases
+invoker.buildResult = success
diff --git a/src/it/it-rules-via-classpath-002/pom.xml b/src/it/it-rules-via-classpath-002/pom.xml
new file mode 100644
index 0000000000..c4177f37c4
--- /dev/null
+++ b/src/it/it-rules-via-classpath-002/pom.xml
@@ -0,0 +1,46 @@
+
+ 4.0.0
+
+ localhost
+ it-rules-via-classpath-002
+ 1.0
+ pom
+ GH-193: Succeed if resource is found
+
+
+
+ localhost
+ version-rules
+ 3.0.1
+
+
+ localhost
+ setup-provide-rules-in-jar
+ 1.0
+
+
+
+
+
+
+
+ @project.groupId@
+ @project.artifactId@
+ @project.version@
+
+ classpath:///package/foo/bar/rules.xml
+
+
+
+ localhost
+ setup-provide-rules-in-jar
+ 1.0
+
+
+
+
+
+
+
+
diff --git a/src/it/it-rules-via-classpath-002/verify.bsh b/src/it/it-rules-via-classpath-002/verify.bsh
new file mode 100644
index 0000000000..23c386d10d
--- /dev/null
+++ b/src/it/it-rules-via-classpath-002/verify.bsh
@@ -0,0 +1,22 @@
+import java.io.*;
+import org.codehaus.plexus.util.FileUtils;
+
+try
+{
+ File file = new File( basedir, "build.log" );
+ String buf = FileUtils.fileRead( file, "UTF-8" );
+ String expectedMessage = "Resource \"classpath:///package/foo/bar/rules.xml\" not found in classpath.";
+
+ if ( buf.indexOf( expectedMessage ) >= 0 )
+ {
+ System.err.println( "File resource rules.xml should have been found in the classpath." );
+ return false;
+ }
+}
+catch( Throwable t )
+{
+ t.printStackTrace();
+ return false;
+}
+
+return true;
diff --git a/src/it/it-rules-via-classpath-003/invoker.properties b/src/it/it-rules-via-classpath-003/invoker.properties
new file mode 100644
index 0000000000..8d6b718473
--- /dev/null
+++ b/src/it/it-rules-via-classpath-003/invoker.properties
@@ -0,0 +1,2 @@
+invoker.goals=clean install ${project.groupId}:${project.artifactId}:${project.version}:use-latest-releases
+invoker.buildResult = success
diff --git a/src/it/it-rules-via-classpath-003/pom.xml b/src/it/it-rules-via-classpath-003/pom.xml
new file mode 100644
index 0000000000..54eadccdbd
--- /dev/null
+++ b/src/it/it-rules-via-classpath-003/pom.xml
@@ -0,0 +1,45 @@
+
+ 4.0.0
+
+ localhost
+ it-rules-via-classpath-003
+ 1.0
+ pom
+ GH-193: Found rules file is used by the plugin
+
+
+
+ localhost
+ version-rules
+ 3.0.1
+
+
+ localhost
+ setup-provide-rules-in-jar
+ 1.0
+
+
+
+
+
+
+
+ @project.groupId@
+ @project.artifactId@
+ @project.version@
+
+ classpath:///package/foo/bar/rules.xml
+
+
+
+ localhost
+ setup-provide-rules-in-jar
+ 1.0
+
+
+
+
+
+
+
diff --git a/src/it/it-rules-via-classpath-003/verify.bsh b/src/it/it-rules-via-classpath-003/verify.bsh
new file mode 100644
index 0000000000..470b14115e
--- /dev/null
+++ b/src/it/it-rules-via-classpath-003/verify.bsh
@@ -0,0 +1,21 @@
+import java.io.*;
+import org.codehaus.plexus.util.FileUtils;
+
+try
+{
+ File file = new File( basedir, "pom.xml" );
+ String buf = FileUtils.fileRead( file, "UTF-8" );
+
+ if ( buf.indexOf( "3.0.1-1.1" ) < 0 )
+ {
+ System.err.println( "Version of version-rules not bumped to 3.0.1-1.1" );
+ return false;
+ }
+}
+catch( Throwable t )
+{
+ t.printStackTrace();
+ return false;
+}
+
+return true;
diff --git a/src/it/setup-provide-rules-in-jar/invoker.properties b/src/it/setup-provide-rules-in-jar/invoker.properties
new file mode 100644
index 0000000000..4b89532743
--- /dev/null
+++ b/src/it/setup-provide-rules-in-jar/invoker.properties
@@ -0,0 +1 @@
+invoker.goals=clean install
diff --git a/src/it/setup-provide-rules-in-jar/pom.xml b/src/it/setup-provide-rules-in-jar/pom.xml
new file mode 100644
index 0000000000..5c35f8f61e
--- /dev/null
+++ b/src/it/setup-provide-rules-in-jar/pom.xml
@@ -0,0 +1,12 @@
+
+ 4.0.0
+
+ localhost
+ setup-provide-rules-in-jar
+ 1.0
+ jar
+ GH-193: Provide a rules file within a jar
+
+
+
diff --git a/src/it/setup-provide-rules-in-jar/src/main/resources/package/foo/bar/rules.xml b/src/it/setup-provide-rules-in-jar/src/main/resources/package/foo/bar/rules.xml
new file mode 100644
index 0000000000..3e7699c7fe
--- /dev/null
+++ b/src/it/setup-provide-rules-in-jar/src/main/resources/package/foo/bar/rules.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/src/main/java/org/codehaus/mojo/versions/AbstractVersionsReport.java b/src/main/java/org/codehaus/mojo/versions/AbstractVersionsReport.java
index 7ba3fa7753..7841d9f6ba 100644
--- a/src/main/java/org/codehaus/mojo/versions/AbstractVersionsReport.java
+++ b/src/main/java/org/codehaus/mojo/versions/AbstractVersionsReport.java
@@ -160,7 +160,9 @@ public abstract class AbstractVersionsReport
private String serverId;
/**
- * The Wagon URI of a ruleSet file containing the rules that control how to compare version numbers.
+ * URI of a ruleSet file containing the rules that control how to compare
+ * version numbers. The URI could be either a Wagon URI or a classpath URI
+ * (e.g. classpath:///package/sub/package/rules.xml
).
*
* @since 1.0-alpha-3
*/
diff --git a/src/main/java/org/codehaus/mojo/versions/AbstractVersionsUpdaterMojo.java b/src/main/java/org/codehaus/mojo/versions/AbstractVersionsUpdaterMojo.java
index 2483188c7b..f5b3c65ce1 100644
--- a/src/main/java/org/codehaus/mojo/versions/AbstractVersionsUpdaterMojo.java
+++ b/src/main/java/org/codehaus/mojo/versions/AbstractVersionsUpdaterMojo.java
@@ -148,7 +148,9 @@ public abstract class AbstractVersionsUpdaterMojo
private String serverId;
/**
- * The Wagon URI of a ruleSet file containing the rules that control how to compare version numbers.
+ * URI of a ruleSet file containing the rules that control how to compare
+ * version numbers. The URI could be either a Wagon URI or a classpath URI
+ * (e.g. classpath:///package/sub/package/rules.xml
).
*
* @since 1.0-alpha-3
*/
diff --git a/src/main/java/org/codehaus/mojo/versions/api/DefaultVersionsHelper.java b/src/main/java/org/codehaus/mojo/versions/api/DefaultVersionsHelper.java
index f6f80120fe..7459113f6e 100644
--- a/src/main/java/org/codehaus/mojo/versions/api/DefaultVersionsHelper.java
+++ b/src/main/java/org/codehaus/mojo/versions/api/DefaultVersionsHelper.java
@@ -66,10 +66,8 @@
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
+import java.io.*;
+import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -99,6 +97,8 @@
public class DefaultVersionsHelper
implements VersionsHelper
{
+ private static final String CLASSPATH_PROTOCOL = "classpath";
+
private static final String TYPE_EXACT = "exact";
private static final String TYPE_REGEX = "regex";
@@ -222,38 +222,16 @@ private static RuleSet getRuleSet( Wagon wagon, String remoteURI )
try
{
wagon.get( remoteURI, tempFile );
- RuleXpp3Reader reader = new RuleXpp3Reader();
- FileInputStream fis = new FileInputStream( tempFile );
+ InputStream is = new FileInputStream(tempFile );
try
{
- BufferedInputStream bis = new BufferedInputStream( fis );
- try
- {
- return reader.read( bis );
- }
- catch ( XmlPullParserException e )
- {
- final IOException ioe = new IOException();
- ioe.initCause( e );
- throw ioe;
- }
- finally
- {
- try
- {
- bis.close();
- }
- catch ( IOException e )
- {
- // ignore
- }
- }
+ return readRulesFromStream(is);
}
finally
{
try
{
- fis.close();
+ is.close();
}
catch ( IOException e )
{
@@ -271,6 +249,34 @@ private static RuleSet getRuleSet( Wagon wagon, String remoteURI )
}
}
+ private static RuleSet readRulesFromStream(InputStream stream)
+ throws IOException {
+ RuleXpp3Reader reader = new RuleXpp3Reader();
+ BufferedInputStream bis = new BufferedInputStream( stream );
+
+ try
+ {
+ return reader.read( bis );
+ }
+ catch ( XmlPullParserException e )
+ {
+ final IOException ioe = new IOException();
+ ioe.initCause( e );
+ throw ioe;
+ }
+ finally
+ {
+ try
+ {
+ bis.close();
+ }
+ catch ( IOException e )
+ {
+ // ignore
+ }
+ }
+ }
+
static boolean exactMatch( String wildcardRule, String value )
{
Pattern p = Pattern.compile( RegexUtils.convertWildcardsToRegex( wildcardRule, true ) );
@@ -285,86 +291,118 @@ static boolean match( String wildcardRule, String value )
private static RuleSet loadRuleSet( String serverId, Settings settings, WagonManager wagonManager, String rulesUri,
Log logger )
- throws MojoExecutionException
- {
+ throws MojoExecutionException {
RuleSet ruleSet = new RuleSet();
- if ( rulesUri != null && rulesUri.trim().length() != 0 )
- {
- try
- {
- int split = rulesUri.lastIndexOf( '/' );
- String baseUri;
- String fileUri;
- if ( split != -1 )
- {
- baseUri = rulesUri.substring( 0, split ) + '/';
- fileUri = split + 1 < rulesUri.length() ? rulesUri.substring( split + 1 ) : "";
- }
- else
- {
- baseUri = rulesUri;
- fileUri = "";
- }
- try
- {
- Wagon wagon = WagonUtils.createWagon( serverId, baseUri, wagonManager, settings, logger );
- try
- {
- logger.debug( "Trying to load ruleset from file \"" + fileUri + "\" in " + baseUri );
- final RuleSet loaded = getRuleSet( wagon, fileUri );
- ruleSet.setRules( loaded.getRules() );
- ruleSet.setIgnoreVersions( loaded.getIgnoreVersions() );
- logger.debug( "Rule set loaded" );
- }
- finally
- {
- if ( wagon != null )
- {
- try
- {
- wagon.disconnect();
- }
- catch ( ConnectionException e )
- {
- logger.warn( "Could not disconnect wagon!", e );
- }
- }
+ boolean rulesUriGiven = isRulesUriNotBlank(rulesUri);
+
+ if (rulesUriGiven) {
+ RuleSet loadedRules;
+ if (isClasspathUri(rulesUri)) {
+ loadedRules = getRulesFromClasspath(rulesUri, logger);
+ } else {
+ loadedRules = getRulesViaWagon(rulesUri, logger, serverId, serverId, wagonManager,
+ settings);
+ }
+
+ ruleSet.setIgnoreVersions(loadedRules.getIgnoreVersions());
+ ruleSet.setRules(loadedRules.getRules());
+ }
+
+ return ruleSet;
+ }
+
+ private static RuleSet getRulesFromClasspath(String uri, Log logger)
+ throws MojoExecutionException {
+ logger.debug("Going to load rules from \"" + uri + "\"");
+
+ String choppedUrl = uri.substring(CLASSPATH_PROTOCOL.length() + 3);
+
+ URL url = DefaultVersionsHelper.class.getResource(choppedUrl);
+
+ if (null == url) {
+ String message = "Resource \"" + uri + "\" not found in classpath.";
+
+ throw new MojoExecutionException(message);
+ }
+
+ try {
+ RuleSet rules = readRulesFromStream(url.openStream());
+ logger.debug("Loaded rules from \"" + uri + "\" successfully");
+ return rules;
+ }
+ catch (IOException e) {
+ throw new MojoExecutionException("Could not load specified rules from " + uri, e);
+ }
+ }
+
+ private static boolean isRulesUriNotBlank(String rulesUri) {
+ return rulesUri != null && rulesUri.trim().length() != 0;
+ }
+
+ private static RuleSet getRulesViaWagon(String rulesUri, Log logger, String serverId, String id,
+ WagonManager wagonManager, Settings settings)
+ throws MojoExecutionException {
+ RuleSet loadedRules = new RuleSet();
+
+ int split = rulesUri.lastIndexOf('/');
+ String baseUri = rulesUri;
+ String fileUri = "";
+
+ if (split != -1) {
+ baseUri = rulesUri.substring(0, split) + '/';
+ fileUri = split + 1 < rulesUri.length() ? rulesUri.substring(split + 1) : "";
+ }
+
+ try {
+ Wagon wagon = WagonUtils.createWagon(serverId, baseUri, wagonManager, settings, logger);
+ try {
+ logger.debug("Trying to load ruleset from file \"" + fileUri + "\" in " + baseUri);
+ loadedRules = getRuleSet(wagon, fileUri);
+ }
+ finally {
+ logger.debug("Rule set loaded");
+
+ if (wagon != null) {
+ try {
+ wagon.disconnect();
+ }
+ catch (ConnectionException e) {
+ logger.warn("Could not disconnect wagon!", e);
}
}
- catch ( TransferFailedException e )
- {
- throw new MojoExecutionException( "Could not transfer rules from " + rulesUri, e );
- }
- catch ( AuthorizationException e )
- {
- throw new MojoExecutionException( "Authorization failure trying to load rules from " + rulesUri,
- e );
- }
- catch ( ResourceDoesNotExistException e )
- {
- throw new MojoExecutionException( "Could not load specified rules from " + rulesUri, e );
- }
- catch ( AuthenticationException e )
- {
- throw new MojoExecutionException( "Authentication failure trying to load rules from " + rulesUri,
- e );
- }
- catch ( UnsupportedProtocolException e )
- {
- throw new MojoExecutionException( "Unsupported protocol for " + rulesUri, e );
- }
- catch ( ConnectionException e )
- {
- throw new MojoExecutionException( "Could not establish connection to " + rulesUri, e );
- }
- }
- catch ( IOException e )
- {
- throw new MojoExecutionException( "Could not load specified rules from " + rulesUri, e );
}
}
- return ruleSet;
+ catch (TransferFailedException e) {
+ throw new MojoExecutionException("Could not transfer rules from " + rulesUri, e);
+ }
+ catch (AuthorizationException e) {
+ throw new MojoExecutionException("Authorization failure trying to load rules from " + rulesUri, e);
+ }
+ catch (ResourceDoesNotExistException e) {
+ throw new MojoExecutionException("Could not load specified rules from " + rulesUri, e);
+ }
+ catch (AuthenticationException e) {
+ throw new MojoExecutionException("Authentication failure trying to load rules from " + rulesUri, e);
+ }
+ catch (UnsupportedProtocolException e) {
+ throw new MojoExecutionException("Unsupported protocol for " + rulesUri, e);
+ }
+ catch (ConnectionException e) {
+ throw new MojoExecutionException("Could not establish connection to " + rulesUri, e);
+ }
+ catch (IOException e) {
+ throw new MojoExecutionException("Could not load specified rules from " + rulesUri, e);
+ }
+
+ return loadedRules;
+ }
+
+ static boolean isClasspathUri(String uri) {
+ boolean startsWithProtocol = null != uri && uri.startsWith(CLASSPATH_PROTOCOL);
+ boolean hasColonNext = null != uri && uri.charAt(CLASSPATH_PROTOCOL.length()) == ':';
+
+ return startsWithProtocol && hasColonNext;
}
/**
diff --git a/src/site/apt/version-rules.apt.vm b/src/site/apt/version-rules.apt.vm
index bbb6a06b9d..d098749e06 100644
--- a/src/site/apt/version-rules.apt.vm
+++ b/src/site/apt/version-rules.apt.vm
@@ -134,3 +134,40 @@ Version number rules
...
---
+
+ You can provide your ruleset xml file also within a jar, if you want to distribute
+ your ruleset xml as Maven artifact. Therefore you have to declare the containing
+ jar as direct dependency of the <> and to use classpath
+ as protocol.
+
+---
+
+ ...
+
+ ...
+
+ ...
+
+ org.codehaus.mojo
+ versions-maven-plugin
+ ${pluginVersion}
+
+ ...
+ classpath:///package/foo/bar/rules.xml
+ ...
+
+
+
+ com.mycompany
+ version-rules
+ 1.0
+
+
+
+ ...
+
+ ...
+
+ ...
+
+---
\ No newline at end of file
diff --git a/src/test/java/org/codehaus/mojo/versions/api/DefaultVersionsHelperTest.java b/src/test/java/org/codehaus/mojo/versions/api/DefaultVersionsHelperTest.java
index 0b03df3d01..a8dc413d9c 100644
--- a/src/test/java/org/codehaus/mojo/versions/api/DefaultVersionsHelperTest.java
+++ b/src/test/java/org/codehaus/mojo/versions/api/DefaultVersionsHelperTest.java
@@ -45,6 +45,7 @@
import org.apache.maven.execution.MavenSession;
import org.codehaus.mojo.versions.Property;
import org.codehaus.mojo.versions.ordering.VersionComparators;
+import org.hamcrest.CoreMatchers;
import java.util.ArrayList;
import java.util.List;
@@ -175,22 +176,36 @@ public void testMVERSIONS159_ExcludedAndNotIncluded()
assertTrue( result.isEmpty() );
}
+ public void testIsClasspathUriDetectsClassPathProtocol() throws MojoExecutionException {
+ DefaultVersionsHelper helper = createHelper();
+ String uri = "classpath:/p/a/c/k/a/g/e/resource.res";
- private VersionsHelper createHelper()
+ assertThat(DefaultVersionsHelper.isClasspathUri(uri), CoreMatchers.is(true));
+ }
+
+ public void testIsClasspathUriDetectsThatItIsDifferentProtocol() throws MojoExecutionException {
+ DefaultVersionsHelper helper = createHelper();
+ String uri = "http://10.10.10.10/p/a/c/k/a/g/e/resource.res";
+
+ assertThat(DefaultVersionsHelper.isClasspathUri(uri), CoreMatchers.is(false));
+ }
+
+
+ private DefaultVersionsHelper createHelper()
throws MojoExecutionException
{
return createHelper( new MavenMetadataSource() );
}
- private VersionsHelper createHelper( ArtifactMetadataSource metadataSource ) throws MojoExecutionException
+ private DefaultVersionsHelper createHelper( ArtifactMetadataSource metadataSource ) throws MojoExecutionException
{
final String resourcePath = "/" + getClass().getPackage().getName().replace( '.', '/' ) + "/rules.xml";
final String rulesUri = getClass().getResource( resourcePath ).toExternalForm();
- VersionsHelper helper = createHelper( rulesUri, metadataSource );
+ DefaultVersionsHelper helper = createHelper( rulesUri, metadataSource );
return helper;
}
- private VersionsHelper createHelper( String rulesUri, ArtifactMetadataSource metadataSource )
+ private DefaultVersionsHelper createHelper( String rulesUri, ArtifactMetadataSource metadataSource )
throws MojoExecutionException
{
final DefaultWagonManager wagonManager = new DefaultWagonManager()
@@ -202,7 +217,7 @@ public Wagon getWagon( Repository repository )
}
};
- VersionsHelper helper =
+ DefaultVersionsHelper helper =
new DefaultVersionsHelper( new DefaultArtifactFactory(), new DefaultArtifactResolver(), metadataSource, new ArrayList(),
new ArrayList(),
new DefaultArtifactRepository( "", "", new DefaultRepositoryLayout() ),