mirror of
				https://github.com/scm-manager/scm-manager.git
				synced 2025-10-31 18:46:07 +01:00 
			
		
		
		
	Fix edge cases in move (#1874)
Fixes edge cases for "move" in the modify command, like - reject backslashes in validation - add overwrite option - check for invalid source and target options This is an update to the implementation of "move" in #1859. Co-authored-by: Matthias Thieroff <matthias.thieroff@cloudogu.com>
This commit is contained in:
		| @@ -34,6 +34,7 @@ import org.tmatesoft.svn.core.wc.SVNClientManager; | ||||
| import org.tmatesoft.svn.core.wc.SVNWCClient; | ||||
| import org.tmatesoft.svn.core.wc.SVNWCUtil; | ||||
| import sonia.scm.ConcurrentModificationException; | ||||
| import sonia.scm.ContextEntry; | ||||
| import sonia.scm.repository.InternalRepositoryException; | ||||
| import sonia.scm.repository.Repository; | ||||
| import sonia.scm.repository.SvnWorkingCopyFactory; | ||||
| @@ -143,6 +144,9 @@ public class SvnModifyCommand implements ModifyCommand { | ||||
|       try { | ||||
|         wcClient.doDelete(new File(workingDirectory, toBeDeleted), true, true, false); | ||||
|       } catch (SVNException e) { | ||||
|         if (e.getErrorMessage().getErrorCode().getCode() == 125001) { | ||||
|           throw new ModificationFailedException(ContextEntry.ContextBuilder.entity("File", toBeDeleted).in(repository).build(), "Could not remove file from repository"); | ||||
|         } | ||||
|         throw new InternalRepositoryException(repository, "could not delete file from repository"); | ||||
|       } | ||||
|     } | ||||
| @@ -161,6 +165,9 @@ public class SvnModifyCommand implements ModifyCommand { | ||||
|           true | ||||
|         ); | ||||
|       } catch (SVNException e) { | ||||
|         if (e.getErrorMessage().getErrorCode().getCode() == 155010) { | ||||
|           throw new ModificationFailedException(ContextEntry.ContextBuilder.entity("File", name).in(repository).build(), "Could not add file to repository"); | ||||
|         } | ||||
|         throw new InternalRepositoryException(repository, "could not add file to repository"); | ||||
|       } | ||||
|     } | ||||
|   | ||||
| @@ -86,10 +86,8 @@ public class SvnModifyCommandTest extends AbstractSvnCommandTestBase { | ||||
|  | ||||
|   @Test | ||||
|   public void shouldRemoveFiles() { | ||||
|     ModifyCommandRequest request = new ModifyCommandRequest(); | ||||
|     ModifyCommandRequest request = prepareModifyCommandRequest(); | ||||
|     request.addRequest(new ModifyCommandRequest.DeleteFileRequest("a.txt", false)); | ||||
|     request.setCommitMessage("this is great"); | ||||
|     request.setAuthor(new Person("Arthur Dent", "dent@hitchhiker.com")); | ||||
|  | ||||
|     svnModifyCommand.execute(request); | ||||
|     WorkingCopy<File, File> workingCopy = workingCopyFactory.createWorkingCopy(context, null); | ||||
| @@ -99,10 +97,8 @@ public class SvnModifyCommandTest extends AbstractSvnCommandTestBase { | ||||
|  | ||||
|   @Test | ||||
|   public void shouldRemoveDirectory() { | ||||
|     ModifyCommandRequest request = new ModifyCommandRequest(); | ||||
|     ModifyCommandRequest request = prepareModifyCommandRequest(); | ||||
|     request.addRequest(new ModifyCommandRequest.DeleteFileRequest("c", true)); | ||||
|     request.setCommitMessage("this is great"); | ||||
|     request.setAuthor(new Person("Arthur Dent", "dent@hitchhiker.com")); | ||||
|  | ||||
|     svnModifyCommand.execute(request); | ||||
|     WorkingCopy<File, File> workingCopy = workingCopyFactory.createWorkingCopy(context, null); | ||||
| @@ -114,10 +110,8 @@ public class SvnModifyCommandTest extends AbstractSvnCommandTestBase { | ||||
|   public void shouldAddNewFile() throws IOException { | ||||
|     File testfile = temporaryFolder.newFile("Test123"); | ||||
|  | ||||
|     ModifyCommandRequest request = new ModifyCommandRequest(); | ||||
|     ModifyCommandRequest request = prepareModifyCommandRequest(); | ||||
|     request.addRequest(new ModifyCommandRequest.CreateFileRequest("Test123", testfile, false)); | ||||
|     request.setCommitMessage("this is great"); | ||||
|     request.setAuthor(new Person("Arthur Dent", "dent@hitchhiker.com")); | ||||
|  | ||||
|     svnModifyCommand.execute(request); | ||||
|  | ||||
| @@ -129,11 +123,9 @@ public class SvnModifyCommandTest extends AbstractSvnCommandTestBase { | ||||
|   public void shouldAddNewFileInDefaultPath() throws IOException { | ||||
|     File testfile = temporaryFolder.newFile("Test123"); | ||||
|  | ||||
|     ModifyCommandRequest request = new ModifyCommandRequest(); | ||||
|     ModifyCommandRequest request = prepareModifyCommandRequest(); | ||||
|     request.setDefaultPath(true); | ||||
|     request.addRequest(new ModifyCommandRequest.CreateFileRequest("Test123", testfile, false)); | ||||
|     request.setCommitMessage("this is great"); | ||||
|     request.setAuthor(new Person("Arthur Dent", "dent@hitchhiker.com")); | ||||
|  | ||||
|     svnModifyCommand.execute(request); | ||||
|  | ||||
| @@ -145,10 +137,8 @@ public class SvnModifyCommandTest extends AbstractSvnCommandTestBase { | ||||
|   public void shouldThrowFileAlreadyExistsException() throws IOException { | ||||
|     File testfile = temporaryFolder.newFile("a.txt"); | ||||
|  | ||||
|     ModifyCommandRequest request = new ModifyCommandRequest(); | ||||
|     ModifyCommandRequest request = prepareModifyCommandRequest(); | ||||
|     request.addRequest(new ModifyCommandRequest.CreateFileRequest("a.txt", testfile, false)); | ||||
|     request.setCommitMessage("this is great"); | ||||
|     request.setAuthor(new Person("Arthur Dent", "dent@hitchhiker.com")); | ||||
|  | ||||
|     assertThrows(AlreadyExistsException.class, () -> svnModifyCommand.execute(request)); | ||||
|   } | ||||
| @@ -157,10 +147,8 @@ public class SvnModifyCommandTest extends AbstractSvnCommandTestBase { | ||||
|   public void shouldUpdateExistingFile() throws IOException { | ||||
|     File testfile = temporaryFolder.newFile("a.txt"); | ||||
|  | ||||
|     ModifyCommandRequest request = new ModifyCommandRequest(); | ||||
|     ModifyCommandRequest request = prepareModifyCommandRequest(); | ||||
|     request.addRequest(new ModifyCommandRequest.CreateFileRequest("a.txt", testfile, true)); | ||||
|     request.setCommitMessage("this is great"); | ||||
|     request.setAuthor(new Person("Arthur Dent", "dent@hitchhiker.com")); | ||||
|  | ||||
|     svnModifyCommand.execute(request); | ||||
|  | ||||
| @@ -173,10 +161,8 @@ public class SvnModifyCommandTest extends AbstractSvnCommandTestBase { | ||||
|   public void shouldThrowExceptionIfExpectedRevisionDoesNotMatch() throws IOException { | ||||
|     File testfile = temporaryFolder.newFile("Test123"); | ||||
|  | ||||
|     ModifyCommandRequest request = new ModifyCommandRequest(); | ||||
|     ModifyCommandRequest request = prepareModifyCommandRequest(); | ||||
|     request.addRequest(new ModifyCommandRequest.CreateFileRequest("Test123", testfile, false)); | ||||
|     request.setCommitMessage("this should not pass"); | ||||
|     request.setAuthor(new Person("Arthur Dent", "dent@hitchhiker.com")); | ||||
|     request.setExpectedRevision("42"); | ||||
|  | ||||
|     assertThrows(ConcurrentModificationException.class, () -> svnModifyCommand.execute(request)); | ||||
| @@ -190,10 +176,8 @@ public class SvnModifyCommandTest extends AbstractSvnCommandTestBase { | ||||
|   public void shouldPassIfExpectedRevisionMatchesCurrentRevision() throws IOException { | ||||
|     File testfile = temporaryFolder.newFile("Test123"); | ||||
|  | ||||
|     ModifyCommandRequest request = new ModifyCommandRequest(); | ||||
|     ModifyCommandRequest request = prepareModifyCommandRequest(); | ||||
|     request.addRequest(new ModifyCommandRequest.CreateFileRequest("Test123", testfile, false)); | ||||
|     request.setCommitMessage("this should not pass"); | ||||
|     request.setAuthor(new Person("Arthur Dent", "dent@hitchhiker.com")); | ||||
|     request.setExpectedRevision("6"); | ||||
|  | ||||
|     svnModifyCommand.execute(request); | ||||
| @@ -203,20 +187,16 @@ public class SvnModifyCommandTest extends AbstractSvnCommandTestBase { | ||||
|  | ||||
|   @Test(expected = ScmConstraintViolationException.class) | ||||
|   public void shouldThrowErrorIfRelativePathIsOutsideOfWorkdir() { | ||||
|     ModifyCommandRequest request = new ModifyCommandRequest(); | ||||
|     request.addRequest(new ModifyCommandRequest.MoveRequest("a.txt", "/../../../../b.txt")); | ||||
|     request.setCommitMessage("please rename my file pretty please"); | ||||
|     request.setAuthor(new Person("Arthur Dent", "dent@hitchhiker.com")); | ||||
|     ModifyCommandRequest request = prepareModifyCommandRequest(); | ||||
|     request.addRequest(new ModifyCommandRequest.MoveRequest("a.txt", "/../../../../b.txt", false)); | ||||
|  | ||||
|     svnModifyCommand.execute(request); | ||||
|   } | ||||
|  | ||||
|   @Test | ||||
|   public void shouldRenameFile() { | ||||
|     ModifyCommandRequest request = new ModifyCommandRequest(); | ||||
|     request.addRequest(new ModifyCommandRequest.MoveRequest("a.txt", "/b.txt")); | ||||
|     request.setCommitMessage("please rename my file pretty please"); | ||||
|     request.setAuthor(new Person("Arthur Dent", "dent@hitchhiker.com")); | ||||
|     ModifyCommandRequest request = prepareModifyCommandRequest(); | ||||
|     request.addRequest(new ModifyCommandRequest.MoveRequest("a.txt", "/b.txt", false)); | ||||
|  | ||||
|     svnModifyCommand.execute(request); | ||||
|  | ||||
| @@ -227,20 +207,16 @@ public class SvnModifyCommandTest extends AbstractSvnCommandTestBase { | ||||
|  | ||||
|   @Test(expected = AlreadyExistsException.class) | ||||
|   public void shouldThrowAlreadyExistsException() { | ||||
|     ModifyCommandRequest request = new ModifyCommandRequest(); | ||||
|     request.addRequest(new ModifyCommandRequest.MoveRequest("a.txt", "/c")); | ||||
|     request.setCommitMessage("please rename my file pretty please"); | ||||
|     request.setAuthor(new Person("Arthur Dent", "dent@hitchhiker.com")); | ||||
|     ModifyCommandRequest request = prepareModifyCommandRequest(); | ||||
|     request.addRequest(new ModifyCommandRequest.MoveRequest("a.txt", "/c", false)); | ||||
|  | ||||
|     svnModifyCommand.execute(request); | ||||
|   } | ||||
|  | ||||
|   @Test | ||||
|   public void shouldRenameFolder() { | ||||
|     ModifyCommandRequest request = new ModifyCommandRequest(); | ||||
|     request.addRequest(new ModifyCommandRequest.MoveRequest("c", "/notc")); | ||||
|     request.setCommitMessage("please rename my file pretty please"); | ||||
|     request.setAuthor(new Person("Arthur Dent", "dent@hitchhiker.com")); | ||||
|     ModifyCommandRequest request = prepareModifyCommandRequest(); | ||||
|     request.addRequest(new ModifyCommandRequest.MoveRequest("c", "/notc", false)); | ||||
|  | ||||
|     svnModifyCommand.execute(request); | ||||
|  | ||||
| @@ -253,10 +229,8 @@ public class SvnModifyCommandTest extends AbstractSvnCommandTestBase { | ||||
|  | ||||
|   @Test | ||||
|   public void shouldMoveFileToExistingFolder() { | ||||
|     ModifyCommandRequest request = new ModifyCommandRequest(); | ||||
|     request.addRequest(new ModifyCommandRequest.MoveRequest("a.txt", "/c/z.txt")); | ||||
|     request.setCommitMessage("please rename my file pretty please"); | ||||
|     request.setAuthor(new Person("Arthur Dent", "dent@hitchhiker.com")); | ||||
|     ModifyCommandRequest request = prepareModifyCommandRequest(); | ||||
|     request.addRequest(new ModifyCommandRequest.MoveRequest("a.txt", "/c/z.txt", false)); | ||||
|  | ||||
|     svnModifyCommand.execute(request); | ||||
|  | ||||
| @@ -269,10 +243,8 @@ public class SvnModifyCommandTest extends AbstractSvnCommandTestBase { | ||||
|  | ||||
|   @Test | ||||
|   public void shouldMoveFolderToExistingFolder() { | ||||
|     ModifyCommandRequest request = new ModifyCommandRequest(); | ||||
|     request.addRequest(new ModifyCommandRequest.MoveRequest("g/h", "/h/h")); | ||||
|     request.setCommitMessage("please rename my file pretty please"); | ||||
|     request.setAuthor(new Person("Arthur Dent", "dent@hitchhiker.com")); | ||||
|     ModifyCommandRequest request = prepareModifyCommandRequest(); | ||||
|     request.addRequest(new ModifyCommandRequest.MoveRequest("g/h", "/h/h", false)); | ||||
|  | ||||
|     svnModifyCommand.execute(request); | ||||
|  | ||||
| @@ -283,10 +255,8 @@ public class SvnModifyCommandTest extends AbstractSvnCommandTestBase { | ||||
|  | ||||
|   @Test | ||||
|   public void shouldMoveFileToNonExistentFolder() { | ||||
|     ModifyCommandRequest request = new ModifyCommandRequest(); | ||||
|     request.addRequest(new ModifyCommandRequest.MoveRequest("a.txt", "/y/z.txt")); | ||||
|     request.setCommitMessage("please rename my file pretty please"); | ||||
|     request.setAuthor(new Person("Arthur Dent", "dent@hitchhiker.com")); | ||||
|     ModifyCommandRequest request = prepareModifyCommandRequest(); | ||||
|     request.addRequest(new ModifyCommandRequest.MoveRequest("a.txt", "/y/z.txt", false)); | ||||
|  | ||||
|     svnModifyCommand.execute(request); | ||||
|  | ||||
| @@ -295,12 +265,22 @@ public class SvnModifyCommandTest extends AbstractSvnCommandTestBase { | ||||
|     assertThat(new File(workingCopy.getWorkingRepository(), "y/z.txt")).exists(); | ||||
|   } | ||||
|  | ||||
|   @Test | ||||
|   public void shouldMoveFileWithOverwrite() { | ||||
|     ModifyCommandRequest request = prepareModifyCommandRequest(); | ||||
|     request.addRequest(new ModifyCommandRequest.MoveRequest("a.txt", "b.txt", true)); | ||||
|  | ||||
|     svnModifyCommand.execute(request); | ||||
|  | ||||
|     WorkingCopy<File, File> workingCopy = workingCopyFactory.createWorkingCopy(context, null); | ||||
|     assertThat(new File(workingCopy.getWorkingRepository(), "a.txt")).doesNotExist(); | ||||
|     assertThat(new File(workingCopy.getWorkingRepository(), "b.txt")).exists(); | ||||
|   } | ||||
|  | ||||
|   @Test | ||||
|   public void shouldMoveFolderToNonExistentFolder() { | ||||
|     ModifyCommandRequest request = new ModifyCommandRequest(); | ||||
|     request.addRequest(new ModifyCommandRequest.MoveRequest("c", "/j/k/c")); | ||||
|     request.setCommitMessage("please rename my file pretty please"); | ||||
|     request.setAuthor(new Person("Arthur Dent", "dent@hitchhiker.com")); | ||||
|     ModifyCommandRequest request = prepareModifyCommandRequest(); | ||||
|     request.addRequest(new ModifyCommandRequest.MoveRequest("c", "/j/k/c", false)); | ||||
|  | ||||
|     svnModifyCommand.execute(request); | ||||
|  | ||||
| @@ -311,6 +291,14 @@ public class SvnModifyCommandTest extends AbstractSvnCommandTestBase { | ||||
|     assertThat(new File(workingCopy.getWorkingRepository(), "j/k/c/e.txt")).exists(); | ||||
|   } | ||||
|  | ||||
|   @Test(expected = AlreadyExistsException.class) | ||||
|   public void shouldFailMoveAndKeepFilesWhenSourceAndTargetAreTheSame() { | ||||
|     ModifyCommandRequest request = prepareModifyCommandRequest(); | ||||
|     request.addRequest(new ModifyCommandRequest.MoveRequest("c", "c", false)); | ||||
|  | ||||
|     svnModifyCommand.execute(request); | ||||
|   } | ||||
|  | ||||
|   @Test | ||||
|   public void shouldFailIfLockedByOtherPerson() { | ||||
|     Subject subject = mock(Subject.class); | ||||
| @@ -321,10 +309,8 @@ public class SvnModifyCommandTest extends AbstractSvnCommandTestBase { | ||||
|  | ||||
|     initSecurityManager(); | ||||
|  | ||||
|     ModifyCommandRequest request = new ModifyCommandRequest(); | ||||
|     ModifyCommandRequest request = prepareModifyCommandRequest(); | ||||
|     request.addRequest(new ModifyCommandRequest.DeleteFileRequest("a.txt", false)); | ||||
|     request.setCommitMessage("this should not happen"); | ||||
|     request.setAuthor(new Person("Arthur Dent", "dent@hitchhiker.com")); | ||||
|  | ||||
|     assertThrows(FileLockedException.class, () -> svnModifyCommand.execute(request)); | ||||
|     WorkingCopy<File, File> workingCopy = workingCopyFactory.createWorkingCopy(context, null); | ||||
| @@ -335,10 +321,8 @@ public class SvnModifyCommandTest extends AbstractSvnCommandTestBase { | ||||
|   public void shouldSucceedIfLockedByUser() { | ||||
|     lockFile(); | ||||
|  | ||||
|     ModifyCommandRequest request = new ModifyCommandRequest(); | ||||
|     ModifyCommandRequest request = prepareModifyCommandRequest(); | ||||
|     request.addRequest(new ModifyCommandRequest.DeleteFileRequest("a.txt", false)); | ||||
|     request.setCommitMessage("this should not happen"); | ||||
|     request.setAuthor(new Person("Arthur Dent", "dent@hitchhiker.com")); | ||||
|  | ||||
|     svnModifyCommand.execute(request); | ||||
|  | ||||
| @@ -347,6 +331,13 @@ public class SvnModifyCommandTest extends AbstractSvnCommandTestBase { | ||||
|     assertThat(getLock()).isEmpty(); | ||||
|   } | ||||
|  | ||||
|   private ModifyCommandRequest prepareModifyCommandRequest() { | ||||
|     ModifyCommandRequest request = new ModifyCommandRequest(); | ||||
|     request.setCommitMessage("modify some things"); | ||||
|     request.setAuthor(new Person("Arthur Dent", "dent@hitchhiker.com")); | ||||
|     return request; | ||||
|   } | ||||
|  | ||||
|   private void lockFile() { | ||||
|     SvnFileLockCommand svnFileLockCommand = new SvnFileLockCommand(context); | ||||
|     LockCommandRequest lockRequest = new LockCommandRequest(); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user