You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm-commits@maven.apache.org by ev...@apache.org on 2005/11/10 22:25:07 UTC

svn commit: r332374 - in /maven/scm/trunk/maven-scm-providers/maven-scm-provider-svn/src: main/java/org/apache/maven/scm/provider/svn/command/update/SvnUpdateCommand.java test/java/org/apache/maven/scm/provider/svn/command/update/SvnUpdateCommandTest.java

Author: evenisse
Date: Thu Nov 10 13:25:01 2005
New Revision: 332374

URL: http://svn.apache.org/viewcvs?rev=332374&view=rev
Log:
PR: SCM-68
Submitted by : David Hawkins
Reviewed by : Emmanuel Venisse

Fix tag handling.
Thanks David

Modified:
    maven/scm/trunk/maven-scm-providers/maven-scm-provider-svn/src/main/java/org/apache/maven/scm/provider/svn/command/update/SvnUpdateCommand.java
    maven/scm/trunk/maven-scm-providers/maven-scm-provider-svn/src/test/java/org/apache/maven/scm/provider/svn/command/update/SvnUpdateCommandTest.java

Modified: maven/scm/trunk/maven-scm-providers/maven-scm-provider-svn/src/main/java/org/apache/maven/scm/provider/svn/command/update/SvnUpdateCommand.java
URL: http://svn.apache.org/viewcvs/maven/scm/trunk/maven-scm-providers/maven-scm-provider-svn/src/main/java/org/apache/maven/scm/provider/svn/command/update/SvnUpdateCommand.java?rev=332374&r1=332373&r2=332374&view=diff
==============================================================================
--- maven/scm/trunk/maven-scm-providers/maven-scm-provider-svn/src/main/java/org/apache/maven/scm/provider/svn/command/update/SvnUpdateCommand.java (original)
+++ maven/scm/trunk/maven-scm-providers/maven-scm-provider-svn/src/main/java/org/apache/maven/scm/provider/svn/command/update/SvnUpdateCommand.java Thu Nov 10 13:25:01 2005
@@ -16,6 +16,11 @@
  * limitations under the License.
  */
 
+import java.io.File;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
 import org.apache.maven.scm.ScmException;
 import org.apache.maven.scm.ScmFileSet;
 import org.apache.maven.scm.command.changelog.ChangeLogCommand;
@@ -26,12 +31,11 @@
 import org.apache.maven.scm.provider.svn.command.SvnCommandLineUtils;
 import org.apache.maven.scm.provider.svn.command.changelog.SvnChangeLogCommand;
 import org.apache.maven.scm.provider.svn.repository.SvnScmProviderRepository;
+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;
 
-import java.io.File;
-
 /**
  * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a>
  * @version $Id$
@@ -40,6 +44,17 @@
     extends AbstractUpdateCommand
     implements SvnCommand
 {
+
+    private final static Set REVISION_SPECIFIERS = Collections.unmodifiableSet( new HashSet()
+    {
+        {
+            add( "HEAD" );
+            add( "BASE" );
+            add( "COMMITTED" );
+            add( "PREV" );
+        }
+    } );
+
     protected UpdateScmResult executeUpdateCommand( ScmProviderRepository repo, ScmFileSet fileSet, String tag )
         throws ScmException
     {
@@ -77,15 +92,30 @@
 
     public static Commandline createCommandLine( SvnScmProviderRepository repository, File workingDirectory, String tag )
     {
+        if ( tag != null && StringUtils.isEmpty( tag.trim() ) ) 
+        {
+            tag = null;
+        }
+        
         Commandline cl = SvnCommandLineUtils.getBaseSvnCommandLine( workingDirectory, repository );
 
-        cl.createArgument().setValue( "update" );
-
-        if ( tag != null )
+        if (tag == null  || isRevisionArgument( tag ) )
         {
-            cl.createArgument().setValue( "-r" );
+            cl.createArgument().setValue( "update" );
 
-            cl.createArgument().setValue( tag );
+            if ( tag != null )
+            {
+                cl.createArgument().setValue( "-r" );
+                cl.createArgument().setValue( tag );
+            }
+        }
+        else
+        {
+            // The tag specified does not appear to be numeric, so assume it refers 
+            // to a branch/tag url and perform a switch operation rather than update
+            cl.createArgument().setValue( "switch" );
+            cl.createArgument().setValue( resolveTagURL( repository, tag ) );
+            cl.createArgument().setValue( workingDirectory.getAbsolutePath() );
         }
 
         return cl;
@@ -102,4 +132,91 @@
 
         return command;
     }
+
+    private final static String[] SVN_BASE_DIRS = new String[] { "/trunk", "/branches", "/tags" };
+
+    /* Returns the "base" repository url, where "base" is the root of
+     * the /trunk, /branches, /tags directories
+     *
+     * This probably belongs in SvnScmProviderRepository rather than here.
+     */
+    static String getSVNBaseURL( SvnScmProviderRepository repository )
+    {
+        String repoPath = repository.getUrl();
+
+        for ( int i = 0; i < SVN_BASE_DIRS.length; i++ )
+        {
+            String dir = SVN_BASE_DIRS[i];
+            if ( repoPath.indexOf( dir ) >= 0 )
+            {
+                return repoPath.substring( 0, repoPath.indexOf( dir ) );
+            }
+        }
+
+        // At this point we were unable to locate the "base" of this svn repository
+        // so assume that the repository url is the "base"
+        if ( repoPath.endsWith( "/" ) )
+        {
+            return repoPath.substring( 0, repoPath.length() - 1 );
+        }
+        else
+        {
+            return repoPath;
+        }
+    }
+
+    /* Resolves a tag to a repository url. If the tag is relative, the tag is appended
+     * to the "base" directory of the repository. 
+     */
+    static String resolveTagURL( SvnScmProviderRepository repository, String tag )
+    {
+        if ( tag == null )
+        {
+            return null;
+        }
+
+        if ( tag.indexOf( "://" ) >= 0 )
+        {
+            // tag is already an absolute url so just return it. 
+            return tag;
+        }
+
+        // Tag must be relative so append it to the repositories base path
+        return getSVNBaseURL( repository ) + "/" + tag;
+    }
+
+    /* Returns whether the supplied tag refers to an
+     * actual revision or is specifying a tag/branch url 
+     * in the repository.  According to the subversion documentation, 
+     * the following are valid revision specifiers:
+     *  NUMBER       revision number
+     *  "{" DATE "}" revision at start of the date
+     *  "HEAD"       latest in repository
+     *  "BASE"       base rev of item's working copy
+     *  "COMMITTED"  last commit at or before BASE
+     *  "PREV" 
+     */
+    private static boolean isRevisionArgument( String tag )
+    {
+        if ( StringUtils.isEmpty( tag ) || StringUtils.isEmpty( tag.trim() ) )
+        {
+            return false;
+        }
+
+        // attempt the revision NUMBER conversion and specifier lookup        
+        if ( StringUtils.isNumeric( tag ) || REVISION_SPECIFIERS.contains( tag ) )
+        {
+            return true;
+        }
+
+        // lastly see if it appears to be a date specifier with 
+        // the first char = '{' and last = '}'
+        if ( tag.startsWith( "{" ) && tag.endsWith( "}" ) )
+        {
+            return true;
+        }
+
+        return false;
+    }
+
 }

Modified: maven/scm/trunk/maven-scm-providers/maven-scm-provider-svn/src/test/java/org/apache/maven/scm/provider/svn/command/update/SvnUpdateCommandTest.java
URL: http://svn.apache.org/viewcvs/maven/scm/trunk/maven-scm-providers/maven-scm-provider-svn/src/test/java/org/apache/maven/scm/provider/svn/command/update/SvnUpdateCommandTest.java?rev=332374&r1=332373&r2=332374&view=diff
==============================================================================
--- maven/scm/trunk/maven-scm-providers/maven-scm-provider-svn/src/test/java/org/apache/maven/scm/provider/svn/command/update/SvnUpdateCommandTest.java (original)
+++ maven/scm/trunk/maven-scm-providers/maven-scm-provider-svn/src/test/java/org/apache/maven/scm/provider/svn/command/update/SvnUpdateCommandTest.java Thu Nov 10 13:25:01 2005
@@ -17,8 +17,10 @@
  */
 
 import org.apache.maven.scm.ScmTestCase;
+import org.apache.maven.scm.manager.NoSuchScmProviderException;
 import org.apache.maven.scm.provider.svn.repository.SvnScmProviderRepository;
 import org.apache.maven.scm.repository.ScmRepository;
+import org.apache.maven.scm.repository.ScmRepositoryException;
 import org.codehaus.plexus.util.cli.Commandline;
 
 import java.io.File;
@@ -34,7 +36,13 @@
         throws Exception
     {
         testCommandLine( "scm:svn:http://foo.com/svn/trunk", "",
-                         "svn --non-interactive update -r " );
+                         "svn --non-interactive update" );
+    }
+    
+    public void testCommandLineWithWhitespaceTag()
+    throws Exception
+    {
+        testCommandLine( "scm:svn:http://foo.com/svn/trunk", "  ", "svn --non-interactive update" );
     }
 
     public void testCommandLineWithoutTag()
@@ -58,20 +66,118 @@
                         "svn --username anonymous --non-interactive update -r 10" );
     }
 
+    public void testCommandLineWithRelativeURLTag()
+        throws Exception
+    {
+        testCommandLine( "scm:svn:http://foo.com/svn/trunk", "branches/my-test-branch",
+                         "svn --non-interactive switch http://foo.com/svn/branches/my-test-branch "
+                             + getUpdateTestFile().getAbsolutePath() );
+    }
+
+    public void testCommandLineWithAbsoluteURLTag()
+        throws Exception
+    {
+        testCommandLine( "scm:svn:http://foo.com/svn/trunk", "http://foo.com/svn/branches/my-test-branch",
+                         "svn --non-interactive switch http://foo.com/svn/branches/my-test-branch "
+                             + getUpdateTestFile().getAbsolutePath() );
+    }
+
+    public void testCommandLineWithNonDeterminantBase()
+        throws Exception
+    {
+        testCommandLine( "scm:svn:http://foo.com/svn/some-project", "branches/my-test-branch",
+                         "svn --non-interactive switch http://foo.com/svn/some-project/branches/my-test-branch "
+                             + getUpdateTestFile().getAbsolutePath() );
+    }
+
+    public void testCommandLineWithNonDeterminantBaseTrailingSlash()
+        throws Exception
+    {
+        testCommandLine( "scm:svn:http://foo.com/svn/some-project/", "branches/my-test-branch",
+                         "svn --non-interactive switch http://foo.com/svn/some-project/branches/my-test-branch "
+                             + getUpdateTestFile().getAbsolutePath() );
+    }
+
+    public void testCommandLineWithBranchSameAsBase()
+        throws Exception
+    {
+        testCommandLine( "scm:svn:http://foo.com/svn/tags/my-tag", "tags/my-tag",
+                         "svn --non-interactive switch http://foo.com/svn/tags/my-tag "
+                             + getUpdateTestFile().getAbsolutePath() );
+    }
+    
+    public void testSVNBaseUrlsTagBranchTrunk()
+        throws Exception
+    {
+        testGetSVNBaseURL( "scm:svn:http://foo.com/svn/tags/my-tag", "http://foo.com/svn" );
+
+        testGetSVNBaseURL( "scm:svn:http://foo.com/svn/branches/my-branch", "http://foo.com/svn" );
+
+        testGetSVNBaseURL( "scm:svn:http://foo.com/svn/trunk", "http://foo.com/svn" );
+    }
+    
+    public void testSVNBaseUrlsNoRootSpecifier()
+        throws Exception
+    {
+        testGetSVNBaseURL( "scm:svn:http://foo.com/svn/", "http://foo.com/svn" );
+        
+        testGetSVNBaseURL( "scm:svn:http://foo.com/svn",  "http://foo.com/svn" );
+
+    }
+    
+    public void testSVNBaseUrlDoubleProjectRoots()
+        throws Exception
+    {
+        // Not sure why anyone would do this, but creating test case to assure it behavior stays consistent
+        testGetSVNBaseURL( "scm:svn:http://foo.com/svn/tags/my-tag/tags/another-tag/", "http://foo.com/svn" );
+    }
+    
+    public void testSVNResolveTagRelative()
+        throws Exception
+    {
+        testResolveSVNTag( "scm:svn:http://foo.com/svn/", "tags/my-tag", "http://foo.com/svn/tags/my-tag" );
+        
+        testResolveSVNTag( "scm:svn:http://foo.com/svn/", "http://foo.com/svn/tags/my-tag", "http://foo.com/svn/tags/my-tag" );
+        
+    }
+    
     // ----------------------------------------------------------------------
     //
     // ----------------------------------------------------------------------
-
-    private void testCommandLine( String scmUrl, String tag, String commandLine )
+    
+    private File getUpdateTestFile()
+    {
+        return getTestFile( "target/svn-update-command-test" );
+    }
+    
+    private SvnScmProviderRepository getSvnRepository( String scmUrl )
         throws Exception
     {
-        File workingDirectory = getTestFile( "target/svn-update-command-test" );
-
         ScmRepository repository = getScmManager().makeScmRepository( scmUrl );
 
-        SvnScmProviderRepository svnRepository = (SvnScmProviderRepository) repository.getProviderRepository();
+        return (SvnScmProviderRepository) repository.getProviderRepository();
+    }
+    
+    private void testResolveSVNTag( String scmUrl, String tag, String expected ) 
+        throws Exception
+    {
+        assertEquals( expected, 
+                      SvnUpdateCommand.resolveTagURL( getSvnRepository( scmUrl ), tag ) );
+    }
+    
+    private void testGetSVNBaseURL( String scmUrl, String expected ) 
+        throws Exception
+    {
+        assertEquals( expected, 
+                      SvnUpdateCommand.getSVNBaseURL( getSvnRepository( scmUrl ) ) );
+    }
+
+    private void testCommandLine( String scmUrl, String tag, String commandLine )
+        throws Exception
+    {
+        File workingDirectory = getUpdateTestFile();
 
-        Commandline cl = SvnUpdateCommand.createCommandLine( svnRepository, workingDirectory, tag );
+        Commandline cl = SvnUpdateCommand.createCommandLine( getSvnRepository( scmUrl ), workingDirectory, tag );
 
         assertEquals( commandLine, cl.toString() );
     }