Author: dennisl Date: Fri Sep 25 06:59:45 2015 New Revision: 1705226 URL: http://svn.apache.org/viewvc?rev=1705226&view=rev Log: [MCHANGELOG-79] Add support for "tag" type report of Subversion. Submitted by: Jerome Lacoste and Samuel Van Reeth Reviewed by: Dennis Lundberg
After removing all the whitespace changed I applied the patch from Samuel, which was based in part on the one from Jerome. I also added some error handling in case you configure a non-existing tag. Added: maven/plugins/trunk/maven-changelog-plugin/src/main/java/org/apache/maven/scm/ maven/plugins/trunk/maven-changelog-plugin/src/main/java/org/apache/maven/scm/provider/ maven/plugins/trunk/maven-changelog-plugin/src/main/java/org/apache/maven/scm/provider/svn/ maven/plugins/trunk/maven-changelog-plugin/src/main/java/org/apache/maven/scm/provider/svn/svnexe/ maven/plugins/trunk/maven-changelog-plugin/src/main/java/org/apache/maven/scm/provider/svn/svnexe/command/ maven/plugins/trunk/maven-changelog-plugin/src/main/java/org/apache/maven/scm/provider/svn/svnexe/command/info/ maven/plugins/trunk/maven-changelog-plugin/src/main/java/org/apache/maven/scm/provider/svn/svnexe/command/info/SvnInfoCommandExpanded.java (with props) Modified: maven/plugins/trunk/maven-changelog-plugin/src/main/java/org/apache/maven/plugin/changelog/ChangeLogReport.java Modified: maven/plugins/trunk/maven-changelog-plugin/src/main/java/org/apache/maven/plugin/changelog/ChangeLogReport.java URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-changelog-plugin/src/main/java/org/apache/maven/plugin/changelog/ChangeLogReport.java?rev=1705226&r1=1705225&r2=1705226&view=diff ============================================================================== --- maven/plugins/trunk/maven-changelog-plugin/src/main/java/org/apache/maven/plugin/changelog/ChangeLogReport.java (original) +++ maven/plugins/trunk/maven-changelog-plugin/src/main/java/org/apache/maven/plugin/changelog/ChangeLogReport.java Fri Sep 25 06:59:45 2015 @@ -38,11 +38,15 @@ import org.apache.maven.scm.ScmResult; import org.apache.maven.scm.ScmRevision; import org.apache.maven.scm.command.changelog.ChangeLogScmResult; import org.apache.maven.scm.command.changelog.ChangeLogSet; +import org.apache.maven.scm.command.info.InfoItem; +import org.apache.maven.scm.command.info.InfoScmResult; +import org.apache.maven.scm.log.DefaultLog; import org.apache.maven.scm.manager.ScmManager; import org.apache.maven.scm.provider.ScmProvider; import org.apache.maven.scm.provider.ScmProviderRepository; import org.apache.maven.scm.provider.ScmProviderRepositoryWithHost; import org.apache.maven.scm.provider.svn.repository.SvnScmProviderRepository; +import org.apache.maven.scm.provider.svn.svnexe.command.info.SvnInfoCommandExpanded; import org.apache.maven.scm.repository.ScmRepository; import org.apache.maven.settings.Server; import org.apache.maven.settings.Settings; @@ -654,10 +658,6 @@ public class ChangeLogReport } else if ( "tag".equals( type ) ) { - if ( repository.getProvider().equals( "svn" ) ) - { - throw new MavenReportException( "The type '" + type + "' isn't supported for svn." ); - } Iterator<String> tagsIter = tags.iterator(); @@ -669,11 +669,15 @@ public class ChangeLogReport while ( tagsIter.hasNext() ) { endTag = tagsIter.next(); - - result = provider.changeLog( repository, new ScmFileSet( basedir ), new ScmRevision( startTag ), - new ScmRevision( endTag ) ); + String endRevision = getRevisionForTag( endTag, repository, provider ); + String startRevision = getRevisionForTag( startTag, repository, provider ); + result = provider.changeLog( repository, new ScmFileSet( basedir ), + new ScmRevision( startRevision ), + new ScmRevision( endRevision ) ); checkResult( result ); + result.getChangeLog().setStartVersion( new ScmRevision( startTag ) ); + result.getChangeLog().setEndVersion( new ScmRevision( endTag ) ); changeSets.add( result.getChangeLog() ); @@ -682,11 +686,15 @@ public class ChangeLogReport } else { - result = provider.changeLog( repository, new ScmFileSet( basedir ), new ScmRevision( startTag ), - new ScmRevision( endTag ) ); + String startRevision = getRevisionForTag( startTag, repository, provider ); + String endRevision = getRevisionForTag( endTag, repository, provider ); + result = provider.changeLog( repository, new ScmFileSet( basedir ), + new ScmRevision( startRevision ), + new ScmRevision( endRevision ) ); checkResult( result ); - + result.getChangeLog().setStartVersion( new ScmRevision( startTag ) ); + result.getChangeLog().setEndVersion( null ); changeSets.add( result.getChangeLog() ); } } @@ -742,6 +750,42 @@ public class ChangeLogReport } /** + * Resolves the given tag to the revision number. + * + * @param tag + * @param repository + * @param provider + * @return + * @throws ScmException + */ + private String getRevisionForTag( final String tag, final ScmRepository repository, final ScmProvider provider ) + throws ScmException + { + if ( repository.getProvider().equals( "svn" ) ) + { + if ( tag == null ) + { + return "HEAD"; + } + SvnInfoCommandExpanded infoCommand = new SvnInfoCommandExpanded(); + infoCommand.setLogger( new DefaultLog() ); + + InfoScmResult infoScmResult = + infoCommand.executeInfoTagCommand( (SvnScmProviderRepository) repository.getProviderRepository(), + new ScmFileSet( basedir ), tag, null, false, null ); + if ( infoScmResult.getInfoItems().size() == 0 ) + { + throw new ScmException( "There is no tag named '" + tag + "' in the Subversion repository." ); + } + InfoItem infoItem = infoScmResult.getInfoItems().get( 0 ); + String revision = infoItem.getLastChangedRevision(); + getLog().info( String.format( "Resolved tag '%s' to revision '%s'", tag, revision ) ); + return revision; + } + return tag; + } + + /** * filters out unwanted files from the changesets */ private void filter( List<ChangeLogSet> changeSets ) Added: maven/plugins/trunk/maven-changelog-plugin/src/main/java/org/apache/maven/scm/provider/svn/svnexe/command/info/SvnInfoCommandExpanded.java URL: http://svn.apache.org/viewvc/maven/plugins/trunk/maven-changelog-plugin/src/main/java/org/apache/maven/scm/provider/svn/svnexe/command/info/SvnInfoCommandExpanded.java?rev=1705226&view=auto ============================================================================== --- maven/plugins/trunk/maven-changelog-plugin/src/main/java/org/apache/maven/scm/provider/svn/svnexe/command/info/SvnInfoCommandExpanded.java (added) +++ maven/plugins/trunk/maven-changelog-plugin/src/main/java/org/apache/maven/scm/provider/svn/svnexe/command/info/SvnInfoCommandExpanded.java Fri Sep 25 06:59:45 2015 @@ -0,0 +1,200 @@ +package org.apache.maven.scm.provider.svn.svnexe.command.info; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.io.File; +import java.util.Iterator; + +import org.apache.maven.scm.CommandParameters; +import org.apache.maven.scm.ScmException; +import org.apache.maven.scm.ScmFileSet; +import org.apache.maven.scm.ScmResult; +import org.apache.maven.scm.ScmTag; +import org.apache.maven.scm.command.AbstractCommand; +import org.apache.maven.scm.command.info.InfoScmResult; +import org.apache.maven.scm.provider.ScmProviderRepository; +import org.apache.maven.scm.provider.svn.SvnCommandUtils; +import org.apache.maven.scm.provider.svn.SvnTagBranchUtils; +import org.apache.maven.scm.provider.svn.command.SvnCommand; +import org.apache.maven.scm.provider.svn.repository.SvnScmProviderRepository; +import org.apache.maven.scm.provider.svn.svnexe.command.SvnCommandLineUtils; +import org.codehaus.plexus.util.StringUtils; +import org.codehaus.plexus.util.cli.CommandLineException; +import org.codehaus.plexus.util.cli.CommandLineUtils; +import org.codehaus.plexus.util.cli.Commandline; + +/** + * variation of SvnInfoCommand to work for branches. Taken from 1.7 release of maven-scm-providers + * + * @author <a href="mailto:ken...@apache.org">Kenney Westerhof</a> + */ +public class SvnInfoCommandExpanded + extends AbstractCommand + implements SvnCommand +{ + + /** {@inheritDoc} */ + @Override + protected ScmResult executeCommand( final ScmProviderRepository repository, final ScmFileSet fileSet, + final CommandParameters parameters ) + throws ScmException + { + return executeInfoCommand( (SvnScmProviderRepository) repository, fileSet, parameters, false, null ); + } + + public InfoScmResult executeInfoCommand( final SvnScmProviderRepository repository, final ScmFileSet fileSet, + final CommandParameters parameters, final boolean recursive, + final String revision ) + throws ScmException + { + Commandline cl = createCommandLine( repository, fileSet, recursive, revision ); + return executeInfoCommand( cl ); + } + + public InfoScmResult executeInfoTagCommand( final SvnScmProviderRepository repository, final ScmFileSet fileSet, + final String tag, final CommandParameters parameters, + final boolean recursive, final String revision ) + throws ScmException + { + Commandline cl = createTagCommandLine( repository, fileSet, tag, recursive, revision ); + return executeInfoCommand( cl ); + } + + private InfoScmResult executeInfoCommand( final Commandline cl ) + throws ScmException + { + + SvnInfoConsumer consumer = new SvnInfoConsumer(); + + CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer(); + if ( getLogger().isInfoEnabled() ) + { + getLogger().info( "Executing: " + SvnCommandLineUtils.cryptPassword( cl ) ); + getLogger().info( "Working directory: " + cl.getWorkingDirectory().getAbsolutePath() ); + } + + int exitCode; + try + { + exitCode = SvnCommandLineUtils.execute( cl, consumer, stderr, getLogger() ); + } + catch ( CommandLineException ex ) + { + throw new ScmException( "Error while executing command.", ex ); + } + + if ( exitCode != 0 ) + { + return new InfoScmResult( cl.toString(), "The svn command failed.", stderr.getOutput(), false ); + } + + return new InfoScmResult( cl.toString(), consumer.getInfoItems() ); + } + + // set scope to protected to allow test to call it directly + protected static Commandline createCommandLine( final SvnScmProviderRepository repository, + final ScmFileSet fileSet, final boolean recursive, + final String revision ) + { + Commandline cl = SvnCommandLineUtils.getBaseSvnCommandLine( fileSet.getBasedir(), repository ); + + cl.createArg().setValue( "info" ); + + if ( recursive ) + { + cl.createArg().setValue( "--recursive" ); + } + + if ( StringUtils.isNotEmpty( revision ) ) + { + cl.createArg().setValue( "-r" ); + cl.createArg().setValue( revision ); + } + + Iterator<File> it = fileSet.getFileList().iterator(); + + while ( it.hasNext() ) + { + File file = it.next(); + if ( repository == null ) + { + cl.createArg().setValue( file.getPath() ); + } + else + { + cl.createArg().setValue( repository.getUrl() + "/" + file.getPath().replace( '\\', '/' ) ); + } + } + + return cl; + } + + // set scope to protected to allow test to call it directly + protected static Commandline createTagCommandLine( final SvnScmProviderRepository repository, + final ScmFileSet fileSet, final String tag, + final boolean recursive, final String revision ) + { + Commandline cl = SvnCommandLineUtils.getBaseSvnCommandLine( fileSet.getBasedir(), repository ); + + cl.createArg().setValue( "info" ); + + if ( recursive ) + { + cl.createArg().setValue( "--recursive" ); + } + + if ( StringUtils.isNotEmpty( revision ) ) + { + cl.createArg().setValue( "-r" ); + cl.createArg().setValue( revision ); + } + + Iterator<File> it = fileSet.getFileList().iterator(); + + if ( !it.hasNext() ) + { + String tagUrl = SvnTagBranchUtils.resolveTagUrl( repository, new ScmTag( tag ) ); + cl.createArg().setValue( SvnCommandUtils.fixUrl( tagUrl, repository.getUser() ) ); + } + else + { + while ( it.hasNext() ) + { + File file = it.next(); + + if ( repository == null ) + { + cl.createArg().setValue( file.getPath() ); + } + else + { + // Note: this currently assumes you have the tag base checked out too + String tagUrl = + SvnTagBranchUtils.resolveTagUrl( repository, new ScmTag( tag ) ) + "/" + + file.getPath().replace( '\\', '/' ); + cl.createArg().setValue( SvnCommandUtils.fixUrl( tagUrl, repository.getUser() ) ); + } + } + } + + return cl; + } + +} Propchange: maven/plugins/trunk/maven-changelog-plugin/src/main/java/org/apache/maven/scm/provider/svn/svnexe/command/info/SvnInfoCommandExpanded.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: maven/plugins/trunk/maven-changelog-plugin/src/main/java/org/apache/maven/scm/provider/svn/svnexe/command/info/SvnInfoCommandExpanded.java ------------------------------------------------------------------------------ svn:keywords = Date Revision Author Id