Skip to content

Commit

Permalink
mojohaus#342: Adding the possibility of adding new scm tags
Browse files Browse the repository at this point in the history
  • Loading branch information
andrzejj0 committed Sep 16, 2022
1 parent cc86df7 commit f894462
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 104 deletions.
13 changes: 9 additions & 4 deletions src/main/java/org/codehaus/mojo/versions/SetScmTagMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -93,23 +93,27 @@ protected void update( ModifiedPomXMLEventReader pom )
List<String> failures = new ArrayList<>();
if ( !isBlank( newTag ) )
{
getLog().info( "Updating tag: " + scm.getTag() + " -> " + newTag );
getLog().info( "Updating tag: " + ( scm != null && scm.getTag() != null
? scm.getTag() : "(empty)" ) + " -> " + newTag );
if ( !PomHelper.setElementValue( pom, "/project/scm", "tag", newTag ) )
{
failures.add( "tag: " + newTag );
}
}
if ( !isBlank( connection ) )
{
getLog().info( "Updating connection: " + scm.getConnection() + " -> " + connection );
getLog().info( "Updating connection: " + ( scm != null && scm.getConnection() != null
? scm.getConnection() : "(empty)" ) + " -> " + connection );
if ( !PomHelper.setElementValue( pom, "/project/scm", "connection", connection ) )
{
failures.add( "connection: " + connection );
}
}
if ( !isBlank( developerConnection ) )
{
getLog().info( "Updating developerConnection: " + scm.getDeveloperConnection() + " -> "
getLog().info( "Updating developerConnection: "
+ ( scm != null && scm.getDeveloperConnection() != null
? scm.getDeveloperConnection() : "(empty)" ) + " -> "
+ developerConnection );
if ( !PomHelper.setElementValue( pom, "/project/scm", "developerConnection",
developerConnection ) )
Expand All @@ -119,7 +123,8 @@ protected void update( ModifiedPomXMLEventReader pom )
}
if ( !isBlank( url ) )
{
getLog().info( "Updating url: " + scm.getUrl() + " -> " + url );
getLog().info( "Updating url: " + ( scm != null && scm.getUrl() != null
? scm.getUrl() : "(empty)" ) + " -> " + url );
if ( !PomHelper.setElementValue( pom, "/project/scm", "url", url ) )
{
failures.add( "url: " + url );
Expand Down
177 changes: 81 additions & 96 deletions src/main/java/org/codehaus/mojo/versions/api/PomHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -278,127 +278,112 @@ public static boolean setElementValue( ModifiedPomXMLEventReader pom, String par
{
class ElementValueInternal
{
private final String parentName;
private final String superParentPath;

private static final int MARK_CHILD_BEGIN = 0;
private static final int MARK_OPTION = 1;
private static final int PARENT_BEGIN = 2;

}

pom.rewind();
int lastDelimeterIndex = parentPath.lastIndexOf( '/' );
try
{
return setElementValueInternal( "",
parentPath.substring( lastDelimeterIndex + 1 ),
parentPath.substring( 0, lastDelimeterIndex ),
pom, parentPath, elementName, value, shouldCreate );
}
finally
{
range( 0, 3 ).forEach( pom::clearMark );
}
}

/**
* Sets the value of the given element given its parent element path.
* If the element is not found in the parent element, the method will create the element.
*
* @param currentPath path currently being considered
* @param parentName name of the parent element
* @param superParentPath path leading to the parent element
* @param pom pom to modify
* @param parentPath path of the parent element
* @param elementName name of the element to set or create
* @param value the new value of the element
* @param shouldCreate should the element be created if it's not found in the first encountered parent element
* matching the parentPath
* @return {@code true} if the element was created or replaced
* @throws XMLStreamException if something went wrong
*/
private static boolean setElementValueInternal( String currentPath, String parentName,
String superParentPath,
ModifiedPomXMLEventReader pom,
String parentPath, String elementName, String value,
boolean shouldCreate )
throws XMLStreamException
{
boolean replacementMade = false;
while ( !replacementMade && pom.hasNext() )
{
XMLEvent event = pom.nextEvent();
if ( event.isStartElement() )
ElementValueInternal()
{
String currentElementName = event.asStartElement().getName().getLocalPart();

// start of the "elementName" element
if ( currentPath.equals( parentPath ) && elementName.equals( currentElementName ) )
{
assert !pom.hasMark( 0 );
pom.mark( 0 );
}
// start of the parent
else if ( currentPath.equals( superParentPath ) && currentElementName.equals( parentName ) )
{
assert !pom.hasMark( 2 );
pom.mark( 2 );
}

// process child element
replacementMade = setElementValueInternal( currentPath + "/" + currentElementName,
parentName, superParentPath,
pom, parentPath, elementName, value, shouldCreate );
int lastDelimeterIndex = parentPath.lastIndexOf( '/' );
parentName = parentPath.substring( lastDelimeterIndex + 1 );
superParentPath = parentPath.substring( 0, lastDelimeterIndex );
}
else if ( event.isEndElement() )

boolean process( String currentPath ) throws XMLStreamException
{
// end of the "elementName" element
if ( currentPath.equals( parentPath + "/" + elementName ) )
boolean replacementMade = false;
while ( !replacementMade && pom.hasNext() )
{
assert pom.hasMark( 0 );
assert !pom.hasMark( 1 );
pom.mark( 1 );

if ( pom.getBetween( 0, 1 ).length() > 0 )
XMLEvent event = pom.nextEvent();
if ( event.isStartElement() )
{
pom.replaceBetween( 0, 1, value );
String currentElementName = event.asStartElement().getName().getLocalPart();

// here, we will only mark the beginning of the child or the parent element
if ( currentPath.equals( parentPath ) && elementName.equals( currentElementName ) )
{
pom.mark( MARK_CHILD_BEGIN );
}
else if ( currentPath.equals( superParentPath ) && currentElementName.equals( parentName ) )
{
pom.mark( PARENT_BEGIN );
}
// process child element
replacementMade = process( currentPath + "/" + currentElementName );
}
else
else if ( event.isEndElement() )
{
pom.replace( String.format( "<%1$s>%2$s</%1$s>", elementName, value ) );
// here we're doing the replacement
if ( currentPath.equals( parentPath + "/" + elementName ) )
{
// end of the child
replaceValueInChild();
replacementMade = true;
}
else if ( shouldCreate && currentPath.equals( parentPath ) )
{
// end of the parent
replaceValueInParent();
replacementMade = true;
}
else
{
return false;
}
}
}
return replacementMade;
}

replacementMade = true;
private void replaceValueInChild()
{
pom.mark( MARK_OPTION );
if ( pom.getBetween( MARK_CHILD_BEGIN, MARK_OPTION ).length() > 0 )
{
pom.replaceBetween( 0, 1, value );
}
// end of the parent
else if ( shouldCreate && currentPath.equals( parentPath ) )
else
{
assert !pom.hasMark( 1 );
pom.mark( 1 );
pom.replace( String.format( "<%1$s>%2$s</%1$s>", elementName, value ) );
}
}

if ( pom.hasMark( 2 ) )
private void replaceValueInParent()
{
pom.mark( MARK_OPTION );
if ( pom.hasMark( PARENT_BEGIN ) )
{
if ( pom.getBetween( PARENT_BEGIN, MARK_OPTION ).length() > 0 )
{
if ( pom.getBetween( 2, 1 ).length() > 0 )
{
pom.replace( String.format( "<%2$s>%3$s</%2$s></%1$s>",
parentName, elementName, value ) );
}
else
{
pom.replace( String.format( "<%1$s><%2$s>%3$s</%2$s></%1$s>",
parentName, elementName, value ) );
}
pom.replace( String.format( "<%2$s>%3$s</%2$s></%1$s>",
parentName, elementName, value ) );
}
else
{
pom.replace( String.format( "<%1$s><%2$s>%3$s</%2$s></%1$s>",
parentName, elementName, value ) );
}

replacementMade = true;
}

break;
else
{
pom.replace( String.format( "<%1$s><%2$s>%3$s</%2$s></%1$s>",
parentName, elementName, value ) );
}
}
}

return replacementMade;
try
{
pom.rewind();
return new ElementValueInternal().process( "" );
}
finally
{
range( 0, 3 ).forEach( pom::clearMark );
}
}

/**
Expand Down
25 changes: 21 additions & 4 deletions src/test/java/org/codehaus/mojo/versions/SetScmTagMojoTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,17 @@
* under the License.
*/

import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import org.codehaus.mojo.versions.utils.BaseMojoTestCase;
import org.junit.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.matchesPattern;

/**
* Basic tests for {@linkplain SetPropertyMojoTest}.
*
Expand All @@ -32,9 +40,18 @@ public class SetScmTagMojoTest extends BaseMojoTestCase
@Test
public void testNewScmValues() throws Exception
{
SetScmTagMojo mojo =
createMojo( "set-scm-tag",
"src/test/resources/org/codehaus/mojo/set-scm-tag/issue-342-pom.xml" );
mojo.execute();
Path pomFile = Paths.get("target/test-classes/org/codehaus/mojo/set-scm-tag/issue-342-pom.xml");
createMojo( "set-scm-tag", pomFile.toString() )
.execute();
String output = String.join( "", Files.readAllLines( pomFile ) )
.replaceAll( "\\s*", "" );
assertThat( output, allOf(
matchesPattern( ".*<scm>.*<tag>\\s*newTag\\s*</tag>.*</scm>.*" ),
matchesPattern( ".*<scm>.*<url>\\s*url\\s*</url>.*</scm>.*" ),
matchesPattern( ".*<scm>.*<connection>\\s*connection\\s*</connection>.*</scm>.*" ),
matchesPattern( ".*<scm>.*<developerConnection>\\s*"
+ "developerConnection\\s*</developerConnection>.*</scm>.*" )
)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
<version>1.0</version>
<packaging>pom</packaging>

<scm/>

<build>
<plugins>
<plugin>
Expand Down
24 changes: 24 additions & 0 deletions src/test/resources/org/codehaus/mojo/set-scm-tag/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>default-group</groupId>
<artifactId>default-artifact</artifactId>
<version>1.0</version>
<packaging>pom</packaging>

<scm/>

<build>
<plugins>
<plugin>
<artifactId>versions-maven-plugin</artifactId>
<configuration>
<newTag>newTag</newTag>
<connection>connection</connection>
<developerConnection>developerConnection</developerConnection>
<url>url</url>
</configuration>
</plugin>
</plugins>
</build>
</project>

0 comments on commit f894462

Please sign in to comment.