Author: evenisse Date: Sat Sep 23 06:44:41 2006 New Revision: 449239 URL: http://svn.apache.org/viewvc?view=rev&rev=449239 Log: [SCM-231] Support for incoming deletions through provider-specific metadata file Submitted by: Arne Degenring
Added: maven/scm/trunk/maven-scm-providers/maven-scm-provider-local/src/main/java/org/apache/maven/scm/provider/local/metadata/ maven/scm/trunk/maven-scm-providers/maven-scm-provider-local/src/main/java/org/apache/maven/scm/provider/local/metadata/LocalScmMetadataUtils.java (with props) maven/scm/trunk/maven-scm-providers/maven-scm-provider-local/src/main/mdo/ maven/scm/trunk/maven-scm-providers/maven-scm-provider-local/src/main/mdo/maven-scm-local-metadata.mdo Modified: maven/scm/trunk/maven-scm-providers/maven-scm-provider-local/pom.xml maven/scm/trunk/maven-scm-providers/maven-scm-provider-local/src/main/java/org/apache/maven/scm/provider/local/command/checkout/LocalCheckOutCommand.java maven/scm/trunk/maven-scm-providers/maven-scm-provider-local/src/main/java/org/apache/maven/scm/provider/local/command/update/LocalUpdateCommand.java maven/scm/trunk/maven-scm-providers/maven-scm-provider-local/src/test/java/org/apache/maven/scm/provider/local/command/checkout/LocalCheckOutCommandTckTest.java maven/scm/trunk/maven-scm-providers/maven-scm-provider-local/src/test/java/org/apache/maven/scm/provider/local/command/update/LocalUpdateCommandTckTest.java Modified: maven/scm/trunk/maven-scm-providers/maven-scm-provider-local/pom.xml URL: http://svn.apache.org/viewvc/maven/scm/trunk/maven-scm-providers/maven-scm-provider-local/pom.xml?view=diff&rev=449239&r1=449238&r2=449239 ============================================================================== --- maven/scm/trunk/maven-scm-providers/maven-scm-provider-local/pom.xml (original) +++ maven/scm/trunk/maven-scm-providers/maven-scm-provider-local/pom.xml Sat Sep 23 06:44:41 2006 @@ -8,4 +8,27 @@ <artifactId>maven-scm-provider-local</artifactId> <name>Maven SCM Local Provider</name> <version>1.0-SNAPSHOT</version> -</project> \ No newline at end of file + <build> + <plugins> + <plugin> + <groupId>org.codehaus.modello</groupId> + <artifactId>modello-maven-plugin</artifactId> + <version>1.0-alpha-6</version> + <executions> + <execution> + <goals> + <goal>java</goal> + <goal>xpp3-reader</goal> + <goal>xpp3-writer</goal> + <goal>xsd</goal> + </goals> + </execution> + </executions> + <configuration> + <version>1.0.0</version> + <model>src/main/mdo/maven-scm-local-metadata.mdo</model> + </configuration> + </plugin> + </plugins> + </build> +</project> Modified: maven/scm/trunk/maven-scm-providers/maven-scm-provider-local/src/main/java/org/apache/maven/scm/provider/local/command/checkout/LocalCheckOutCommand.java URL: http://svn.apache.org/viewvc/maven/scm/trunk/maven-scm-providers/maven-scm-provider-local/src/main/java/org/apache/maven/scm/provider/local/command/checkout/LocalCheckOutCommand.java?view=diff&rev=449239&r1=449238&r2=449239 ============================================================================== --- maven/scm/trunk/maven-scm-providers/maven-scm-provider-local/src/main/java/org/apache/maven/scm/provider/local/command/checkout/LocalCheckOutCommand.java (original) +++ maven/scm/trunk/maven-scm-providers/maven-scm-provider-local/src/main/java/org/apache/maven/scm/provider/local/command/checkout/LocalCheckOutCommand.java Sat Sep 23 06:44:41 2006 @@ -16,6 +16,15 @@ * limitations under the License. */ +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.Writer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + import org.apache.maven.scm.ScmException; import org.apache.maven.scm.ScmFile; import org.apache.maven.scm.ScmFileSet; @@ -24,17 +33,14 @@ import org.apache.maven.scm.command.checkout.CheckOutScmResult; import org.apache.maven.scm.provider.ScmProviderRepository; import org.apache.maven.scm.provider.local.command.LocalCommand; +import org.apache.maven.scm.provider.local.metadata.LocalScmMetadataUtils; import org.apache.maven.scm.provider.local.repository.LocalScmProviderRepository; +import org.apache.maven.scm.providers.local.metadata.LocalScmMetadata; +import org.apache.maven.scm.providers.local.metadata.io.xpp3.LocalScmMetadataXpp3Writer; import org.codehaus.plexus.util.FileUtils; +import org.codehaus.plexus.util.IOUtil; import org.codehaus.plexus.util.StringUtils; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; - /** * @author <a href="mailto:[EMAIL PROTECTED]">Trygve Laugstøl</a> * @version $Id$ @@ -101,6 +107,10 @@ } checkedOutFiles = checkOut( source, baseDestination, fileList, repository.getModule() ); + + // write metadata file + LocalScmMetadataUtils metadataUtils = new LocalScmMetadataUtils( getLogger() ); + metadataUtils.writeMetadata( baseDestination, metadataUtils.buildMetadata( source ) ); } catch ( IOException ex ) { @@ -152,4 +162,6 @@ return checkedOutFiles; } + + } Modified: maven/scm/trunk/maven-scm-providers/maven-scm-provider-local/src/main/java/org/apache/maven/scm/provider/local/command/update/LocalUpdateCommand.java URL: http://svn.apache.org/viewvc/maven/scm/trunk/maven-scm-providers/maven-scm-provider-local/src/main/java/org/apache/maven/scm/provider/local/command/update/LocalUpdateCommand.java?view=diff&rev=449239&r1=449238&r2=449239 ============================================================================== --- maven/scm/trunk/maven-scm-providers/maven-scm-provider-local/src/main/java/org/apache/maven/scm/provider/local/command/update/LocalUpdateCommand.java (original) +++ maven/scm/trunk/maven-scm-providers/maven-scm-provider-local/src/main/java/org/apache/maven/scm/provider/local/command/update/LocalUpdateCommand.java Sat Sep 23 06:44:41 2006 @@ -16,6 +16,12 @@ * limitations under the License. */ +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + import org.apache.maven.scm.ScmException; import org.apache.maven.scm.ScmFile; import org.apache.maven.scm.ScmFileSet; @@ -26,16 +32,12 @@ import org.apache.maven.scm.provider.ScmProviderRepository; import org.apache.maven.scm.provider.local.command.LocalCommand; import org.apache.maven.scm.provider.local.command.changelog.LocalChangeLogCommand; +import org.apache.maven.scm.provider.local.metadata.LocalScmMetadataUtils; import org.apache.maven.scm.provider.local.repository.LocalScmProviderRepository; +import org.apache.maven.scm.providers.local.metadata.LocalScmMetadata; import org.codehaus.plexus.util.FileUtils; import org.codehaus.plexus.util.StringUtils; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - /** * @author <a href="mailto:[EMAIL PROTECTED]">Trygve Laugstøl</a> * @version $Id$ @@ -94,6 +96,31 @@ List fileList = FileUtils.getFiles( source.getAbsoluteFile(), "**", null ); updatedFiles = update( source, baseDestination, fileList ); + + // process deletions in repository + LocalScmMetadataUtils metadataUtils = new LocalScmMetadataUtils( getLogger() ); + LocalScmMetadata originalMetadata = metadataUtils.readMetadata( baseDestination ); + if ( originalMetadata != null ) + { + LocalScmMetadata newMetadata = metadataUtils.buildMetadata( source ); + for ( Iterator it = originalMetadata.getRepositoryFileNames().iterator(); it.hasNext(); ) + { + String filename = (String) it.next(); + if ( !newMetadata.getRepositoryFileNames().contains( filename ) ) + { + File localFile = new File( baseDestination, filename ); + if ( localFile.exists() ) + { + localFile.delete(); + updatedFiles.add( new ScmFile( "/" + filename, ScmFileStatus.UPDATED ) ); + } + } + } + } + + // rewrite metadata file + metadataUtils.writeMetadata( baseDestination, metadataUtils.buildMetadata( source ) ); + } catch ( IOException ex ) { Added: maven/scm/trunk/maven-scm-providers/maven-scm-provider-local/src/main/java/org/apache/maven/scm/provider/local/metadata/LocalScmMetadataUtils.java URL: http://svn.apache.org/viewvc/maven/scm/trunk/maven-scm-providers/maven-scm-provider-local/src/main/java/org/apache/maven/scm/provider/local/metadata/LocalScmMetadataUtils.java?view=auto&rev=449239 ============================================================================== --- maven/scm/trunk/maven-scm-providers/maven-scm-provider-local/src/main/java/org/apache/maven/scm/provider/local/metadata/LocalScmMetadataUtils.java (added) +++ maven/scm/trunk/maven-scm-providers/maven-scm-provider-local/src/main/java/org/apache/maven/scm/provider/local/metadata/LocalScmMetadataUtils.java Sat Sep 23 06:44:41 2006 @@ -0,0 +1,103 @@ +package org.apache.maven.scm.provider.local.metadata; + +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.Reader; +import java.io.Writer; +import java.util.List; + +import org.apache.maven.scm.log.ScmLogger; +import org.apache.maven.scm.providers.local.metadata.LocalScmMetadata; +import org.apache.maven.scm.providers.local.metadata.io.xpp3.LocalScmMetadataXpp3Reader; +import org.apache.maven.scm.providers.local.metadata.io.xpp3.LocalScmMetadataXpp3Writer; +import org.codehaus.plexus.util.FileUtils; +import org.codehaus.plexus.util.IOUtil; +import org.codehaus.plexus.util.xml.pull.XmlPullParserException; + +/** + * Utils for dealing with LocalScmMetadata + * + * @author <a href="mailto:[EMAIL PROTECTED]">Arne Degenring</a> + * @version $Id$ + */ +public class LocalScmMetadataUtils +{ + /** The name of the metadata file */ + public static final String FILENMAE = ".maven-scm-local"; + + protected final ScmLogger logger; + + public LocalScmMetadataUtils( ScmLogger logger ) + { + this.logger = logger; + } + + /** + * Builds LocalScmMetadata based on contents of repository + */ + public LocalScmMetadata buildMetadata( File repository ) throws IOException + { + List repoFilenames = FileUtils.getFileNames( repository.getAbsoluteFile(), "**", null, false ); + LocalScmMetadata metadata = new LocalScmMetadata(); + metadata.setRepositoryFileNames( repoFilenames ); + return metadata; + } + + /** + * Writes metadata file + */ + public void writeMetadata( File destinationDir, LocalScmMetadata metadata ) throws IOException + { + File metadataFile = new File( destinationDir, FILENMAE ); + metadataFile.createNewFile(); + Writer writer = new FileWriter( metadataFile ); + try + { + new LocalScmMetadataXpp3Writer().write( writer, metadata ); + } + finally + { + IOUtil.close( writer ); + } + } + + /** + * Reads metadata file from given directory. + * + * @param dir + * The directory that should contain the metadata file + * @return LocalScmMetadata or <tt>null</tt> in case of problems + */ + public LocalScmMetadata readMetadata( File dir ) + { + File metadataFile = new File( dir, FILENMAE ); + if ( !metadataFile.exists() ) + { + return null; + } + LocalScmMetadata result = null; + Reader reader = null; + try + { + reader = new FileReader( metadataFile ); + result = new LocalScmMetadataXpp3Reader().read( reader ); + } + catch ( XmlPullParserException e ) + { + logger.warn( "Could not interpret .maven-scm-local - ignoring", e ); + return null; + } + catch ( IOException e ) + { + logger.warn( "Could not Read .maven-scm-local - ignoring", e ); + } + finally + { + IOUtil.close( reader ); + } + return result; + } + +} Propchange: maven/scm/trunk/maven-scm-providers/maven-scm-provider-local/src/main/java/org/apache/maven/scm/provider/local/metadata/LocalScmMetadataUtils.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: maven/scm/trunk/maven-scm-providers/maven-scm-provider-local/src/main/java/org/apache/maven/scm/provider/local/metadata/LocalScmMetadataUtils.java ------------------------------------------------------------------------------ svn:keywords = "Author Date Id Revision" Added: maven/scm/trunk/maven-scm-providers/maven-scm-provider-local/src/main/mdo/maven-scm-local-metadata.mdo URL: http://svn.apache.org/viewvc/maven/scm/trunk/maven-scm-providers/maven-scm-provider-local/src/main/mdo/maven-scm-local-metadata.mdo?view=auto&rev=449239 ============================================================================== --- maven/scm/trunk/maven-scm-providers/maven-scm-provider-local/src/main/mdo/maven-scm-local-metadata.mdo (added) +++ maven/scm/trunk/maven-scm-providers/maven-scm-provider-local/src/main/mdo/maven-scm-local-metadata.mdo Sat Sep 23 06:44:41 2006 @@ -0,0 +1,29 @@ +<model> + <id>maven-scm-local-metadata</id> + <name>LocalScmMetadata</name> + <description>Metadata for Maven SCM Local provider</description> + <defaults> + <default> + <key>package</key> + <value>org.apache.maven.scm.providers.local.metadata</value> + </default> + </defaults> + + <classes> + <class rootElement="true" xml.tagName="localScmMetadata"> + <name>LocalScmMetadata</name> + <version>1.0.0+</version> + <fields> + <field xml.listStyle="wrapped"> + <name>repositoryFileNames</name> + <version>1.0.0+</version> + <association> + <type>String</type> + <multiplicity>*</multiplicity> + </association> + <description>The list of filenames contained in the repository during last checkout or update operation.</description> + </field> + </fields> + </class> + </classes> +</model> Modified: maven/scm/trunk/maven-scm-providers/maven-scm-provider-local/src/test/java/org/apache/maven/scm/provider/local/command/checkout/LocalCheckOutCommandTckTest.java URL: http://svn.apache.org/viewvc/maven/scm/trunk/maven-scm-providers/maven-scm-provider-local/src/test/java/org/apache/maven/scm/provider/local/command/checkout/LocalCheckOutCommandTckTest.java?view=diff&rev=449239&r1=449238&r2=449239 ============================================================================== --- maven/scm/trunk/maven-scm-providers/maven-scm-provider-local/src/test/java/org/apache/maven/scm/provider/local/command/checkout/LocalCheckOutCommandTckTest.java (original) +++ maven/scm/trunk/maven-scm-providers/maven-scm-provider-local/src/test/java/org/apache/maven/scm/provider/local/command/checkout/LocalCheckOutCommandTckTest.java Sat Sep 23 06:44:41 2006 @@ -16,9 +16,17 @@ * limitations under the License. */ -import org.apache.maven.scm.tck.command.checkout.CheckOutCommandTckTest; - import java.io.File; +import java.io.FileReader; +import java.io.Reader; +import java.util.List; + +import org.apache.maven.scm.command.checkout.CheckOutScmResult; +import org.apache.maven.scm.providers.local.metadata.LocalScmMetadata; +import org.apache.maven.scm.providers.local.metadata.io.xpp3.LocalScmMetadataXpp3Reader; +import org.apache.maven.scm.tck.command.checkout.CheckOutCommandTckTest; +import org.codehaus.plexus.util.FileUtils; +import org.codehaus.plexus.util.IOUtil; /** * @author <a href="mailto:[EMAIL PROTECTED]">Emmanuel Venisse</a> @@ -49,5 +57,40 @@ makeFile( root, "/src/test/java/Test.java" ); makeDirectory( root, "/src/test/resources" ); + } + + /** + * Tests that the metadata file .maven-scm-local is written correctly + */ + public void testMetadata() throws Exception + { + FileUtils.deleteDirectory( getWorkingCopy() ); + + CheckOutScmResult result = checkOut( getWorkingCopy(), getScmRepository() ); + + assertResultIsSuccess( result ); + + List checkedOutFiles = result.getCheckedOutFiles(); + + assertEquals( 4, checkedOutFiles.size() ); + + // ---------------------------------------------------------------------- + // Assert metadata file + // ---------------------------------------------------------------------- + File metadataFile = new File( getWorkingCopy(), ".maven-scm-local" ); + assertTrue( "Expected metadata file .maven-scm-local does not exist", metadataFile.exists() ); + Reader reader = new FileReader( metadataFile ); + LocalScmMetadata metadata; + try + { + metadata = new LocalScmMetadataXpp3Reader().read( reader ); + } + finally + { + IOUtil.close( reader ); + } + File root = new File( getRepositoryRoot() + "/" + module ); + List fileNames = FileUtils.getFileNames( root, "**", null, false ); + assertEquals( fileNames, metadata.getRepositoryFileNames() ); } } Modified: maven/scm/trunk/maven-scm-providers/maven-scm-provider-local/src/test/java/org/apache/maven/scm/provider/local/command/update/LocalUpdateCommandTckTest.java URL: http://svn.apache.org/viewvc/maven/scm/trunk/maven-scm-providers/maven-scm-provider-local/src/test/java/org/apache/maven/scm/provider/local/command/update/LocalUpdateCommandTckTest.java?view=diff&rev=449239&r1=449238&r2=449239 ============================================================================== --- maven/scm/trunk/maven-scm-providers/maven-scm-provider-local/src/test/java/org/apache/maven/scm/provider/local/command/update/LocalUpdateCommandTckTest.java (original) +++ maven/scm/trunk/maven-scm-providers/maven-scm-provider-local/src/test/java/org/apache/maven/scm/provider/local/command/update/LocalUpdateCommandTckTest.java Sat Sep 23 06:44:41 2006 @@ -16,9 +16,26 @@ * limitations under the License. */ -import org.apache.maven.scm.tck.command.update.UpdateCommandTckTest; - import java.io.File; +import java.io.FileReader; +import java.io.Reader; +import java.util.Date; +import java.util.Iterator; +import java.util.List; +import java.util.TreeSet; + +import org.apache.maven.scm.ChangeSet; +import org.apache.maven.scm.ScmFile; +import org.apache.maven.scm.ScmFileSet; +import org.apache.maven.scm.ScmTestCase; +import org.apache.maven.scm.command.update.UpdateScmResult; +import org.apache.maven.scm.manager.ScmManager; +import org.apache.maven.scm.providers.local.metadata.LocalScmMetadata; +import org.apache.maven.scm.providers.local.metadata.io.xpp3.LocalScmMetadataXpp3Reader; +import org.apache.maven.scm.repository.ScmRepository; +import org.apache.maven.scm.tck.command.update.UpdateCommandTckTest; +import org.codehaus.plexus.util.FileUtils; +import org.codehaus.plexus.util.IOUtil; /** * @author <a href="mailto:[EMAIL PROTECTED]">Trygve Laugstøl</a> @@ -41,6 +58,96 @@ makeRepo( getRepositoryRoot() ); } + /** + * Tests that a file that has been deleted from repository after checkout will be removed by scm-local. Local + * additions must not be deleted. + */ + public void testDeletion() throws Exception + { + FileUtils.deleteDirectory( getUpdatingCopy() ); + + ScmRepository repository = makeScmRepository( getScmUrl() ); + + checkOut( getUpdatingCopy(), repository ); + + // Check preconditions + File readmeFileLocal = new File( getUpdatingCopy(), "readme.txt" ); + assertTrue( readmeFileLocal.exists() ); + File newFileLocal = new File( getUpdatingCopy(), "newfile.xml" ); + assertTrue( !newFileLocal.exists() ); + + // Delete readme.txt from repository + File readmeFileRepo = new File( getRepositoryRoot(), moduleName + "/readme.txt" ); + assertTrue( readmeFileRepo.exists() ); + assertTrue( "Could not delete", readmeFileRepo.delete() ); + assertFalse( readmeFileRepo.exists() ); + + // Make local addition to updating copy - this one must not be touched + ScmTestCase.makeFile( getUpdatingCopy(), "newfile.xml", "added newfile.xml locally" ); + assertTrue( newFileLocal.exists() ); + + // ---------------------------------------------------------------------- + // Update the project + // ---------------------------------------------------------------------- + + ScmManager scmManager = getScmManager(); + Date lastUpdate = new Date( System.currentTimeMillis() ); + Thread.sleep( 1000 ); + UpdateScmResult result = + scmManager.getProviderByUrl( getScmUrl() ).update( repository, new ScmFileSet( getUpdatingCopy() ), null, + lastUpdate ); + + assertNotNull( "The command returned a null result.", result ); + + assertResultIsSuccess( result ); + + List updatedFiles = result.getUpdatedFiles(); + + assertEquals( "Expected 1 files in the updated files list " + updatedFiles, 1, updatedFiles.size() ); + + // ---------------------------------------------------------------------- + // Assert the files in the updated files list + // ---------------------------------------------------------------------- + + Iterator files = new TreeSet( updatedFiles ).iterator(); + + // readme.txt + ScmFile file = (ScmFile) files.next(); + assertPath( "/readme.txt", file.getPath() ); + assertTrue( file.getStatus().isUpdate() ); + + // ---------------------------------------------------------------------- + // Assert working directory contents + // ---------------------------------------------------------------------- + + // readme.txt + assertTrue( "Expected local copy of readme.txt to be deleted", !readmeFileLocal.exists() ); + + // newfile.xml + assertTrue( "Expected local copy of newfile.xml NOT to be deleted", newFileLocal.exists() ); + + // ---------------------------------------------------------------------- + // Assert metadata file + // ---------------------------------------------------------------------- + File metadataFile = new File( getUpdatingCopy(), ".maven-scm-local" ); + assertTrue( "Expected metadata file .maven-scm-local does not exist", metadataFile.exists() ); + Reader reader = new FileReader( metadataFile ); + LocalScmMetadata metadata; + try + { + metadata = new LocalScmMetadataXpp3Reader().read( reader ); + } + finally + { + IOUtil.close( reader ); + } + File root = new File( getRepositoryRoot() + "/" + moduleName ); + List fileNames = FileUtils.getFileNames( root, "**", null, false ); + assertEquals( fileNames, metadata.getRepositoryFileNames() ); + + } + + private void makeRepo( File workingDirectory ) throws Exception {