Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Regex support for VersionGenerator #606

Merged
merged 8 commits into from
Apr 14, 2015
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ public class ManifestMerger
*/
protected Boolean versionCodeUpdateFromVersion;

/**
* Mirror of {@link com.jayway.maven.plugins.android.standalonemojos.ManifestMergerMojo
* #manifestVersionNamingPattern}.
*/
protected String versionNamingPattern;

/**
* Mirror of {@link com.jayway.maven.plugins.android.standalonemojos.ManifestMergerMojo
* #manifestVersionDigits}.
Expand Down Expand Up @@ -71,6 +77,11 @@ public Boolean getVersionCodeUpdateFromVersion()
return versionCodeUpdateFromVersion;
}

public String getVersionNamingPattern()
{
return versionNamingPattern;
}

public String getVersionDigits()
{
return versionDigits;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.jayway.maven.plugins.android.configuration;

import static java.lang.String.format;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.maven.plugin.MojoExecutionException;

/**
* Regex-based VersionElementParser implementation.
*
* @author Wang Xuerui <[email protected]>
*
*/
public class RegexVersionElementParser implements VersionElementParser
{

private Pattern namingPattern;

public RegexVersionElementParser( String pattern )
{
namingPattern = Pattern.compile( pattern );
}

@Override
public int[] parseVersionElements( final String versionName ) throws MojoExecutionException
{
final Matcher matcher = namingPattern.matcher( versionName );
if ( ! matcher.find() )
{
throw new MojoExecutionException( format(
"The version naming pattern failed to match version name: %s against %s",
namingPattern, versionName ) );
}

int elementCount = matcher.groupCount();
int[] result = new int[elementCount];

for ( int i = 0; i < elementCount; i++ )
{
// Capturing groups start at index 1
try
{
result[i] = Integer.valueOf( matcher.group( i + 1 ) );
}
catch ( NumberFormatException ignored )
{
// Either the group is not present, or cannot be cast to integer.
result[i] = 0;
}
}

return result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.jayway.maven.plugins.android.configuration;

import org.apache.maven.plugin.MojoExecutionException;

/**
* VersionElementParser implementing the old version generator behavior.
*
* @author Wang Xuerui <[email protected]>
*
*/
public class SimpleVersionElementParser implements VersionElementParser
{

@Override
public int[] parseVersionElements( final String versionName ) throws MojoExecutionException
{
final String[] versionNameElements = versionName.replaceAll( "[^0-9.]", "" ).split( "\\." );
int[] result = new int[versionNameElements.length];

for ( int i = 0; i < versionNameElements.length; i++ )
{
result[i] = Integer.valueOf( versionNameElements[i] );
}

return result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.jayway.maven.plugins.android.configuration;

import org.apache.maven.plugin.MojoExecutionException;

/**
* Interface for parsing version names into version elements.
*
* @author Wang Xuerui <[email protected]>
*
*/
public interface VersionElementParser
{
int[] parseVersionElements( final String versionName ) throws MojoExecutionException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

/**
* @author Pappy STĂNESCU <a href="mailto:pappy.stanescu&#64;gmail.com">&lt;pappy.stanescu&#64;gmail.com&gt;</a>
* @author Wang Xuerui <[email protected]>
*/
public class VersionGenerator
{
Expand All @@ -15,12 +16,19 @@ public class VersionGenerator

private final int[] multipliers;

private final VersionElementParser elementParser;

public VersionGenerator()
{
this( "4,3,3" );
this( "4,3,3", "" );
}

public VersionGenerator( String versionDigits )
{
this( versionDigits, "" );
}

public VersionGenerator( String versionDigits, String versionNamingPattern )
{
final String[] digits = versionDigits.split( "[,;]" );

Expand All @@ -42,22 +50,32 @@ public VersionGenerator( String versionDigits )
{
throw new IllegalArgumentException( format( "Invalid number of digits, got %d", total ) );
}

// Choose a version element parser implementation based on the naming pattern
// passed in; an empty pattern triggers the old behavior.
if ( ! versionNamingPattern.isEmpty() )
{
this.elementParser = new RegexVersionElementParser( versionNamingPattern );
}
else
{
this.elementParser = new SimpleVersionElementParser();
}
}

public int generate( String versionName ) throws MojoExecutionException
{
final String[] versionNameElements = versionName.replaceAll( "[^0-9.]", "" ).split( "\\." );
final int[] versionElements = elementParser.parseVersionElements( versionName );

long versionCode = 0;

for ( int k = 0; k < this.elementsCount; k++ )
{
versionCode *= this.multipliers[k];

if ( k < versionNameElements.length )
if ( k < versionElements.length )
{
final String versionElement = versionNameElements[k];
final int elementValue = Integer.valueOf( versionElement );
final int elementValue = versionElements[k];

if ( elementValue >= this.multipliers[k] )
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ public class ManifestMergerMojo extends AbstractAndroidMojo
* &lt;versionName&gt;&lt;/versionName&gt;
* &lt;versionCode&gt;123&lt;/versionCode&gt;
* &lt;versionCodeUpdateFromVersion&gt;true|false&lt;/versionCodeUpdateFromVersion&gt;
* &lt;versionNamingPattern&gt;&lt;/versionNamingPattern&gt;
* &lt;mergeLibraries&gt;true|false&lt;/mergeLibraries&gt;
* &lt;mergeReportFile&gt;${project.build.directory}/ManifestMergeReport.txt&lt;/mergeReportFile&gt;
* &lt;usesSdk&gt;
Expand Down Expand Up @@ -112,6 +113,20 @@ public class ManifestMergerMojo extends AbstractAndroidMojo
@Parameter( property = "android.manifest.versionCodeUpdateFromVersion", defaultValue = "false" )
protected Boolean manifestVersionCodeUpdateFromVersion = false;

/**
* Optionally use a pattern to match version elements for automatic generation of version codes,
* useful in case of complex version naming schemes. The new behavior is disabled by default;
* set the pattern to a non-empty string to activate. Otherwise, continue using the old
* behavior of separating version elements by dots and ignoring all non-digit characters.
* The pattern is standard Java regex. Capturing groups in the pattern are sequentially passed
* to the version code generator, while other parts are ignored. Be sure to properly escape
* your pattern string, in case you use characters that have special meaning in XML.
* Exposed via the project property
* <code>android.manifestMerger.versionNamingPattern</code>.
*/
@Parameter( property = "android.manifestMerger.versionNamingPattern", defaultValue = "" )
protected String manifestVersionNamingPattern;

/**
* The number of digits per version element. Must be specified as a comma/semicolon separated list of
* digits, one for each version element, Exposed via the project property
Expand Down Expand Up @@ -140,6 +155,7 @@ public class ManifestMergerMojo extends AbstractAndroidMojo
*/
protected UsesSdk manifestUsesSdk;
private Boolean parsedVersionCodeUpdateFromVersion;
private String parsedVersionNamingPattern;
private String parsedVersionDigits;
private Boolean parsedMergeLibraries;
private String parsedVersionName;
Expand Down Expand Up @@ -172,6 +188,7 @@ public void execute() throws MojoExecutionException, MojoFailureException
getLog().debug( " versionCode=" + parsedVersionCode );
getLog().debug( " usesSdk=" + parsedUsesSdk );
getLog().debug( " versionCodeUpdateFromVersion=" + parsedVersionCodeUpdateFromVersion );
getLog().debug( " versionNamingPattern=" + parsedVersionNamingPattern );
getLog().debug( " versionDigits=" + parsedVersionDigits );
getLog().debug( " mergeLibraries=" + parsedMergeLibraries );
getLog().debug( " mergeReportFile=" + parsedMergeReportFile );
Expand Down Expand Up @@ -214,6 +231,14 @@ private void parseConfiguration()
{
parsedVersionCodeUpdateFromVersion = manifestVersionCodeUpdateFromVersion;
}
if ( manifestMerger.getVersionNamingPattern() != null )
{
parsedVersionNamingPattern = manifestMerger.getVersionNamingPattern();
}
else
{
parsedVersionNamingPattern = manifestVersionNamingPattern;
}
if ( manifestMerger.getVersionDigits() != null )
{
parsedVersionDigits = manifestMerger.getVersionDigits();
Expand Down Expand Up @@ -253,6 +278,7 @@ private void parseConfiguration()
parsedVersionCode = manifestVersionCode;
parsedUsesSdk = manifestUsesSdk;
parsedVersionCodeUpdateFromVersion = manifestVersionCodeUpdateFromVersion;
parsedVersionNamingPattern = manifestVersionNamingPattern;
parsedVersionDigits = manifestVersionDigits;
parsedMergeLibraries = manifestMergeLibraries;
parsedMergeReportFile = manifestMergeReportFile;
Expand All @@ -275,8 +301,8 @@ public void manifestMergerV2() throws MojoExecutionException, MojoFailureExcepti
}
if ( parsedVersionCodeUpdateFromVersion )
{
VersionGenerator gen = new VersionGenerator( parsedVersionDigits );
VersionGenerator gen = new VersionGenerator( parsedVersionDigits, parsedVersionNamingPattern );

versionCode = gen.generate( parsedVersionName );
}
else
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.jayway.maven.plugins.android.configuration;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.fail;

import org.apache.maven.plugin.MojoExecutionException;
import org.junit.Test;

/**
* @author Wang Xuerui <[email protected]>
*/
public class RegexVersionElementParserTest
{

@Test
public void prefixMatch() throws MojoExecutionException
{
assertArrayEquals( new int[] { 4, 1, 16, 8 }, new RegexVersionElementParser( "^(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)" ).parseVersionElements( "4.1.16.8-SNAPSHOT.1946" ) );
assertArrayEquals( new int[] { 0, 0, 38 }, new RegexVersionElementParser( "^(\\d+)\\.(\\d+)-(\\d+)" ).parseVersionElements( "0.0-38-g493f883" ) );
assertArrayEquals( new int[] { 5, 0, 1 }, new RegexVersionElementParser( "^(\\d+)\\.(\\d+)\\.(\\d+)" ).parseVersionElements( "5.0.1 (1642443)" ) );
assertArrayEquals( new int[] { 6, 1, 0, 66 }, new RegexVersionElementParser( "^(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)" ).parseVersionElements( "6.1.0.66-r1062275" ) );
}

@Test
public void fullMatch() throws MojoExecutionException
{
assertArrayEquals( new int[] { 5, 0, 1, 1642443 }, new RegexVersionElementParser( "^(\\d+)\\.(\\d+)\\.(\\d+) \\((\\d+)\\)$" ).parseVersionElements( "5.0.1 (1642443)" ) );
assertArrayEquals( new int[] { 6, 1, 0, 66, 1062275 }, new RegexVersionElementParser( "^(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)-r(\\d+)$" ).parseVersionElements( "6.1.0.66-r1062275" ) );
}

@Test
public void variableLengthResult() throws MojoExecutionException
{
final String pattern1 = "^(\\d+)\\.(\\d+)(?:-(\\d+)-g[0-9a-f]+(?:-dirty)?)?$";
assertArrayEquals( new int[] { 0, 0, 38 }, new RegexVersionElementParser( pattern1 ).parseVersionElements( "0.0-38-g493f883" ) );
assertArrayEquals( new int[] { 0, 0, 38 }, new RegexVersionElementParser( pattern1 ).parseVersionElements( "0.0-38-g493f883-dirty" ) );
assertArrayEquals( new int[] { 1, 0, 0 }, new RegexVersionElementParser( pattern1 ).parseVersionElements( "1.0" ) );

final String pattern2 = "^(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)(?:-[A-Z]+\\.(\\d+))?$";
assertArrayEquals( new int[] { 4, 1, 16, 8, 1946 }, new RegexVersionElementParser( pattern2 ).parseVersionElements( "4.1.16.8-SNAPSHOT.1946" ) );
assertArrayEquals( new int[] { 4, 1, 16, 8, 0 }, new RegexVersionElementParser( pattern2 ).parseVersionElements( "4.1.16.8" ) );
}

@Test
public void failedMatch() throws MojoExecutionException
{
try
{
new RegexVersionElementParser( "^(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)" ).parseVersionElements( "4.1.16-SNAPSHOT.1946" );
fail( "Expecting MojoExecutionException" );
}
catch ( MojoExecutionException e )
{
System.err.println( "OK: " + e );
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.jayway.maven.plugins.android.configuration;

import static org.junit.Assert.assertArrayEquals;

import org.apache.maven.plugin.MojoExecutionException;
import org.junit.Test;

/**
* @author Wang Xuerui <[email protected]>
*/
public class SimpleVersionElementParserTest
{

@Test
public void simple() throws MojoExecutionException
{
assertArrayEquals( new int[] { 2, 14, 748, 3647 }, new SimpleVersionElementParser().parseVersionElements( "2.14.748.3647" ) );
assertArrayEquals( new int[] { 2147, 483, 64, 7 }, new SimpleVersionElementParser().parseVersionElements( "2147.483.64.7" ) );
assertArrayEquals( new int[] { 2, 1, 4, 7, 4, 8, 3, 6, 4, 7 }, new SimpleVersionElementParser().parseVersionElements( "2.1.4.7.4.8.3.6.4.7" ) );
}

@Test
public void mixed() throws MojoExecutionException
{
assertArrayEquals( new int[] { 4, 1, 16, 8, 1946 }, new SimpleVersionElementParser().parseVersionElements( "4.1.16.8-SNAPSHOT.1946" ) );
assertArrayEquals( new int[] { 1, 2, 15, 8, 1946 }, new SimpleVersionElementParser().parseVersionElements( "1.2.15.8-SNAPSHOT.1946" ) );
assertArrayEquals( new int[] { 2, 1, 6, 1246 }, new SimpleVersionElementParser().parseVersionElements( "2.1.6-SNAPSHOT.1246" ) );
}
}
Loading