Author: evenisse Date: Wed Mar 21 04:04:06 2007 New Revision: 520837 URL: http://svn.apache.org/viewvc?view=rev&rev=520837 Log: [SCM-288] Improved support for SCM providers like ClearCase that do NOT check out directly into the check-out-dir but into sub-directories of the check-out-dir Submitted by: Arne Degenring
Added: maven/scm/trunk/maven-scm-plugin/src/test/java/org/apache/maven/scm/plugin/BootstrapMojoTest.java (with props) Modified: maven/scm/trunk/maven-scm-api/src/main/java/org/apache/maven/scm/command/checkout/CheckOutScmResult.java maven/scm/trunk/maven-scm-plugin/src/main/java/org/apache/maven/scm/plugin/BootstrapMojo.java maven/scm/trunk/maven-scm-plugin/src/main/java/org/apache/maven/scm/plugin/CheckoutMojo.java maven/scm/trunk/maven-scm-providers/maven-scm-provider-clearcase/src/main/java/org/apache/maven/scm/provider/clearcase/command/checkout/ClearCaseCheckOutCommand.java Modified: maven/scm/trunk/maven-scm-api/src/main/java/org/apache/maven/scm/command/checkout/CheckOutScmResult.java URL: http://svn.apache.org/viewvc/maven/scm/trunk/maven-scm-api/src/main/java/org/apache/maven/scm/command/checkout/CheckOutScmResult.java?view=diff&rev=520837&r1=520836&r2=520837 ============================================================================== --- maven/scm/trunk/maven-scm-api/src/main/java/org/apache/maven/scm/command/checkout/CheckOutScmResult.java (original) +++ maven/scm/trunk/maven-scm-api/src/main/java/org/apache/maven/scm/command/checkout/CheckOutScmResult.java Wed Mar 21 04:04:06 2007 @@ -31,8 +31,21 @@ public class CheckOutScmResult extends ScmResult { + private List checkedOutFiles; + /** + * The relative path of the directory of the checked out project in comparison to the checkout directory, or + * an empty String in case the checkout directory equals the project directory. + * <p/> + * With most SCMs, this is just an empty String, meaning that the checkout directory equals the project directory. + * But there are cases (e.g. ClearCase) where within the checkout directory, the directory structure of the + * SCM system is repeated. E.g. if you check out the project "my/project" to "/some/dir", the project sources + * are actually checked out to "my/project/some/dir". In this example, relativePathProjectDirectory would + * contain "my/project". + */ + protected String relativePathProjectDirectory = ""; + public CheckOutScmResult( String commandLine, String providerMessage, String commandOutput, boolean success ) { super( commandLine, providerMessage, commandOutput, success ); @@ -45,6 +58,16 @@ this.checkedOutFiles = checkedOutFiles; } + public CheckOutScmResult( String commandLine, List checkedOutFiles, String relativePathProjectDirectory ) + { + this( commandLine, checkedOutFiles ); + + if ( relativePathProjectDirectory != null ) + { + this.relativePathProjectDirectory = relativePathProjectDirectory; + } + } + public CheckOutScmResult( List checkedOutFiles, ScmResult result ) { super( result ); @@ -55,5 +78,14 @@ public List getCheckedOutFiles() { return checkedOutFiles; + } + + /** + * @return the contents of [EMAIL PROTECTED] #relativePathProjectDirectory} + * @see #relativePathProjectDirectory + */ + public String getRelativePathProjectDirectory() + { + return relativePathProjectDirectory; } } Modified: maven/scm/trunk/maven-scm-plugin/src/main/java/org/apache/maven/scm/plugin/BootstrapMojo.java URL: http://svn.apache.org/viewvc/maven/scm/trunk/maven-scm-plugin/src/main/java/org/apache/maven/scm/plugin/BootstrapMojo.java?view=diff&rev=520837&r1=520836&r2=520837 ============================================================================== --- maven/scm/trunk/maven-scm-plugin/src/main/java/org/apache/maven/scm/plugin/BootstrapMojo.java (original) +++ maven/scm/trunk/maven-scm-plugin/src/main/java/org/apache/maven/scm/plugin/BootstrapMojo.java Wed Mar 21 04:04:06 2007 @@ -20,6 +20,7 @@ */ import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.scm.command.checkout.CheckOutScmResult; import org.codehaus.plexus.util.StringUtils; import org.codehaus.plexus.util.cli.CommandLineException; import org.codehaus.plexus.util.cli.CommandLineUtils; @@ -55,7 +56,9 @@ private String goals; /** - * The subdirectory (under the checkout directory) in which to run the goals. + * The subdirectory (under the project directory) in which to run the goals. + * The project directory is the same as the checkout directory in most cases, + * but for some SCMs, it is a subdirectory of the checkout directory. * * @parameter expression="${goalsDirectory}" default-value="" */ @@ -64,12 +67,16 @@ public void execute() throws MojoExecutionException { - checkout(); + CheckOutScmResult result = checkout(); - runGoals(); + runGoals( result.getRelativePathProjectDirectory() ); } - private void runGoals() + /** + * @param relativePathProjectDirectory the project directory's path relative to the checkout + * directory; or "" if they are the same + */ + private void runGoals( String relativePathProjectDirectory ) throws MojoExecutionException { Commandline cl = new Commandline(); @@ -87,14 +94,8 @@ cl.setExecutable( "mvn" ); - if ( StringUtils.isEmpty( goalsDirectory ) ) - { - cl.setWorkingDirectory( this.getCheckoutDirectory().getPath() ); - } - else - { - cl.setWorkingDirectory( new File( this.getCheckoutDirectory(), goalsDirectory ).getPath() ); - } + cl.setWorkingDirectory( determineWorkingDirectoryPath( this.getCheckoutDirectory(), + relativePathProjectDirectory, goalsDirectory ) ); if ( this.goals != null ) { @@ -120,6 +121,39 @@ catch ( CommandLineException e ) { throw new MojoExecutionException( "Can't run goal " + goals, e ); + } + } + + /** + * Determines the path of the working directory. By default, this is the checkout directory. For some SCMs, the project root directory + * is not the checkout directory itself, but a SCM-specific subdirectory. The build can furthermore optionally be executed in a + * subdirectory of this project directory, in case + * + * @param checkoutDirectory + * @param relativePathProjectDirectory + * @param goalsDirectory + * @return + */ + protected String determineWorkingDirectoryPath( File checkoutDirectory, String relativePathProjectDirectory, + String goalsDirectory ) + { + File projectDirectory; + if ( StringUtils.isNotEmpty( relativePathProjectDirectory ) ) + { + projectDirectory = new File( checkoutDirectory, relativePathProjectDirectory ); + } + else + { + projectDirectory = checkoutDirectory; + } + + if ( StringUtils.isEmpty( goalsDirectory ) ) + { + return projectDirectory.getPath(); + } + else + { + return new File( projectDirectory, goalsDirectory ).getPath(); } } Modified: maven/scm/trunk/maven-scm-plugin/src/main/java/org/apache/maven/scm/plugin/CheckoutMojo.java URL: http://svn.apache.org/viewvc/maven/scm/trunk/maven-scm-plugin/src/main/java/org/apache/maven/scm/plugin/CheckoutMojo.java?view=diff&rev=520837&r1=520836&r2=520837 ============================================================================== --- maven/scm/trunk/maven-scm-plugin/src/main/java/org/apache/maven/scm/plugin/CheckoutMojo.java (original) +++ maven/scm/trunk/maven-scm-plugin/src/main/java/org/apache/maven/scm/plugin/CheckoutMojo.java Wed Mar 21 04:04:06 2007 @@ -89,7 +89,7 @@ this.checkoutDirectory = checkoutDirectory; } - protected void checkout() + protected CheckOutScmResult checkout() throws MojoExecutionException { try @@ -130,6 +130,8 @@ currentTag ); checkResult( result ); + + return result; } catch ( ScmException e ) { Added: maven/scm/trunk/maven-scm-plugin/src/test/java/org/apache/maven/scm/plugin/BootstrapMojoTest.java URL: http://svn.apache.org/viewvc/maven/scm/trunk/maven-scm-plugin/src/test/java/org/apache/maven/scm/plugin/BootstrapMojoTest.java?view=auto&rev=520837 ============================================================================== --- maven/scm/trunk/maven-scm-plugin/src/test/java/org/apache/maven/scm/plugin/BootstrapMojoTest.java (added) +++ maven/scm/trunk/maven-scm-plugin/src/test/java/org/apache/maven/scm/plugin/BootstrapMojoTest.java Wed Mar 21 04:04:06 2007 @@ -0,0 +1,93 @@ +package org.apache.maven.scm.plugin; + +/* + * 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 org.apache.maven.plugin.testing.AbstractMojoTestCase; +import org.codehaus.plexus.util.FileUtils; + +import java.io.File; + +/** + * Unit Test for BootstrapMojo + * + * @author <a href="mailto:[EMAIL PROTECTED]">Arne Degenring</a> + * @version $Id$ + */ +public class BootstrapMojoTest + extends AbstractMojoTestCase +{ + File checkoutDir; + + File projectDir; + + File goalDir; + + BootstrapMojo bootstrapMojo; + + protected void setUp() + throws Exception + { + super.setUp(); + + checkoutDir = getTestFile( "target/checkout" ); + FileUtils.forceDelete( checkoutDir ); + checkoutDir.mkdirs(); + + projectDir = getTestFile( "target/checkout/my/project" ); + projectDir.mkdirs(); + + goalDir = getTestFile( "target/checkout/my/project/modules/1" ); + goalDir.mkdirs(); + + bootstrapMojo = new BootstrapMojo(); + } + + public void testDetermineWorkingDirectoryPath() + throws Exception + { + // only checkout dir + assertEquals( checkoutDir.getPath(), bootstrapMojo.determineWorkingDirectoryPath( checkoutDir, "", "" ) ); + assertEquals( checkoutDir.getPath(), bootstrapMojo.determineWorkingDirectoryPath( checkoutDir, null, null ) ); + + // checkout dir and goal dir + assertEquals( projectDir.getPath(), + bootstrapMojo.determineWorkingDirectoryPath( checkoutDir, "", "my/project" ) ); + + // checkout dir and relative path project dir + assertEquals( projectDir.getPath(), + bootstrapMojo.determineWorkingDirectoryPath( checkoutDir, "my/project", null ) ); + assertEquals( projectDir.getPath(), + bootstrapMojo.determineWorkingDirectoryPath( checkoutDir, "my/project/", null ) ); + assertEquals( projectDir.getPath(), bootstrapMojo.determineWorkingDirectoryPath( checkoutDir, "my" + File + .separator + "project", null ) ); + + // checkout dir, relative path project dir and goal dir have been set + assertEquals( goalDir.getPath(), + bootstrapMojo.determineWorkingDirectoryPath( checkoutDir, "my/project", "modules/1" ) ); + assertEquals( goalDir.getPath(), + bootstrapMojo.determineWorkingDirectoryPath( checkoutDir, "my/project/", "modules/1/" ) ); + assertEquals( goalDir.getPath(), bootstrapMojo.determineWorkingDirectoryPath( checkoutDir, + "my" + File.separator + "project", + "modules" + File.separator + + "1" ) ); + } + + +} Propchange: maven/scm/trunk/maven-scm-plugin/src/test/java/org/apache/maven/scm/plugin/BootstrapMojoTest.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: maven/scm/trunk/maven-scm-plugin/src/test/java/org/apache/maven/scm/plugin/BootstrapMojoTest.java ------------------------------------------------------------------------------ svn:keywords = "Author Date Id Revision" Modified: maven/scm/trunk/maven-scm-providers/maven-scm-provider-clearcase/src/main/java/org/apache/maven/scm/provider/clearcase/command/checkout/ClearCaseCheckOutCommand.java URL: http://svn.apache.org/viewvc/maven/scm/trunk/maven-scm-providers/maven-scm-provider-clearcase/src/main/java/org/apache/maven/scm/provider/clearcase/command/checkout/ClearCaseCheckOutCommand.java?view=diff&rev=520837&r1=520836&r2=520837 ============================================================================== --- maven/scm/trunk/maven-scm-providers/maven-scm-provider-clearcase/src/main/java/org/apache/maven/scm/provider/clearcase/command/checkout/ClearCaseCheckOutCommand.java (original) +++ maven/scm/trunk/maven-scm-providers/maven-scm-provider-clearcase/src/main/java/org/apache/maven/scm/provider/clearcase/command/checkout/ClearCaseCheckOutCommand.java Wed Mar 21 04:04:06 2007 @@ -79,6 +79,8 @@ int exitCode; Commandline cl; + String projectDirectory = ""; + try { // Since clearcase only wants to checkout to a non-existent directory, first delete the working dir if it already exists @@ -108,24 +110,18 @@ // write config spec to temp file String configSpec = createConfigSpec( repo.getLoadDirectory(), tag ); getLogger().info( "Created config spec for view '" + viewName + "':\n" + configSpec ); - configSpecLocation = File.createTempFile( "configspec-" + viewName, ".txt" ); - FileWriter fw = new FileWriter( configSpecLocation ); - try - { - fw.write( configSpec ); - } - finally + configSpecLocation = writeTemporaryConfigSpecFile( configSpec, viewName ); + + // When checking out from ClearCase, the directory structure of the + // SCM system is repeated within the checkout directory. E.g. if you check out the + // project "my/project" to "/some/dir", the project sources are actually checked out + // to "my/project/some/dir". + projectDirectory = repo.getLoadDirectory(); + // strip off leading / to make the path relative + if ( projectDirectory.startsWith( "/" ) ) { - try - { - fw.close(); - } - catch ( IOException e ) - { - // ignoree - } + projectDirectory = projectDirectory.substring( 1 ); } - configSpecLocation.deleteOnExit(); } cl = createUpdateConfigSpecCommandLine( workingDirectory, configSpecLocation, viewName ); @@ -149,7 +145,7 @@ return new CheckOutScmResult( cl.toString(), "The cleartool command failed.", stderr.getOutput(), false ); } - return new CheckOutScmResult( cl.toString(), consumer.getCheckedOutFiles() ); + return new CheckOutScmResult( cl.toString(), consumer.getCheckedOutFiles(), projectDirectory ); } // ---------------------------------------------------------------------- @@ -157,6 +153,38 @@ // ---------------------------------------------------------------------- /** + * Creates a temporary config spec file with the given contents that will be + * deleted on VM exit. + * + * @param configSpecContents The contents for the file + * @param viewName The name of the view; used to determine an appropriate file + * name + */ + protected static File writeTemporaryConfigSpecFile( String configSpecContents, String viewName ) + throws IOException + { + File configSpecLocation = File.createTempFile( "configspec-" + viewName, ".txt" ); + FileWriter fw = new FileWriter( configSpecLocation ); + try + { + fw.write( configSpecContents ); + } + finally + { + try + { + fw.close(); + } + catch ( IOException e ) + { + // ignore + } + } + configSpecLocation.deleteOnExit(); + return configSpecLocation; + } + + /** * Creates a config spec that loads the given loadDirectory and uses the * given version tag * @@ -183,29 +211,29 @@ return configSpec.toString(); } - private static Commandline createDeleteViewCommandLine( ClearCaseScmProviderRepository repository, - File workingDirectory ) - { - Commandline command = new Commandline(); - - command.setWorkingDirectory( workingDirectory.getAbsolutePath() ); - - command.setExecutable( "cleartool" ); - - command.createArgument().setValue( "rmview" ); - command.createArgument().setValue( "-force" ); - command.createArgument().setValue( "-tag" ); - if ( isClearCaseLT() ) - { - command.createArgument().setValue( getViewStore() ); - } - else - { - command.createArgument().setValue( getUniqueViewName( repository, workingDirectory.getAbsolutePath() ) ); - } - - return command; - } +// private static Commandline createDeleteViewCommandLine( ClearCaseScmProviderRepository repository, +// File workingDirectory ) +// { +// Commandline command = new Commandline(); +// +// command.setWorkingDirectory( workingDirectory.getAbsolutePath() ); +// +// command.setExecutable( "cleartool" ); +// +// command.createArgument().setValue( "rmview" ); +// command.createArgument().setValue( "-force" ); +// command.createArgument().setValue( "-tag" ); +// if ( isClearCaseLT() ) +// { +// command.createArgument().setValue( getViewStore() ); +// } +// else +// { +// command.createArgument().setValue( getUniqueViewName( repository, workingDirectory.getAbsolutePath() ) ); +// } +// +// return command; +// } protected static Commandline createCreateViewCommandLine( File workingDirectory, String viewName ) throws IOException