diff --git a/scm-core/src/main/java/sonia/scm/repository/spi/ModifyCommand.java b/scm-core/src/main/java/sonia/scm/repository/spi/ModifyCommand.java index 012c7ef2c6..b3ba882040 100644 --- a/scm-core/src/main/java/sonia/scm/repository/spi/ModifyCommand.java +++ b/scm-core/src/main/java/sonia/scm/repository/spi/ModifyCommand.java @@ -12,7 +12,7 @@ public interface ModifyCommand { void create(String toBeCreated, File file, boolean overwrite) throws IOException; - void modify(String path, File file); + void modify(String path, File file) throws IOException; void move(String sourcePath, String targetPath); } diff --git a/scm-core/src/main/java/sonia/scm/repository/spi/ModifyCommandRequest.java b/scm-core/src/main/java/sonia/scm/repository/spi/ModifyCommandRequest.java index 9069154951..a108a73546 100644 --- a/scm-core/src/main/java/sonia/scm/repository/spi/ModifyCommandRequest.java +++ b/scm-core/src/main/java/sonia/scm/repository/spi/ModifyCommandRequest.java @@ -158,7 +158,7 @@ public class ModifyCommandRequest implements Resetable, Validateable { } @Override - public void execute(ModifyCommand.Worker worker) { + public void execute(ModifyCommand.Worker worker) throws IOException { worker.modify(path, getContent()); cleanup(); } diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitModifyCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitModifyCommand.java index 806f667515..d03af28e3a 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitModifyCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitModifyCommand.java @@ -9,7 +9,6 @@ import org.eclipse.jgit.revwalk.RevCommit; import sonia.scm.BadRequestException; import sonia.scm.ConcurrentModificationException; import sonia.scm.ContextEntry; -import sonia.scm.NotFoundException; import sonia.scm.repository.GitWorkdirFactory; import sonia.scm.repository.InternalRepositoryException; import sonia.scm.repository.Repository; @@ -25,6 +24,7 @@ import java.util.Optional; import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; import static sonia.scm.AlreadyExistsException.alreadyExists; import static sonia.scm.ContextEntry.ContextBuilder.entity; +import static sonia.scm.NotFoundException.notFound; import static sonia.scm.ScmConstraintViolationException.Builder.doThrow; public class GitModifyCommand extends AbstractGitCommand implements ModifyCommand { @@ -79,10 +79,10 @@ public class GitModifyCommand extends AbstractGitCommand implements ModifyComman Path targetFile = new File(workDir, toBeCreated).toPath(); Files.createDirectories(targetFile.getParent()); if (overwrite) { - Files.copy(file.toPath(), targetFile, REPLACE_EXISTING); + Files.move(file.toPath(), targetFile, REPLACE_EXISTING); } else { try { - Files.copy(file.toPath(), targetFile); + Files.move(file.toPath(), targetFile); } catch (FileAlreadyExistsException e) { throw alreadyExists(createFileContext(toBeCreated)); } @@ -94,13 +94,28 @@ public class GitModifyCommand extends AbstractGitCommand implements ModifyComman } } + @Override + public void modify(String path, File file) throws IOException { + Path targetFile = new File(workDir, path).toPath(); + Files.createDirectories(targetFile.getParent()); + if (!targetFile.toFile().exists()) { + throw notFound(createFileContext(path)); + } + Files.move(file.toPath(), targetFile, REPLACE_EXISTING); + try { + getClone().add().addFilepattern(path).call(); + } catch (GitAPIException e) { + throwInternalRepositoryException("could not add new file to index", e); + } + } + @Override public void delete(String toBeDeleted) throws IOException { Path fileToBeDeleted = new File(workDir, toBeDeleted).toPath(); try { Files.delete(fileToBeDeleted); } catch (NoSuchFileException e) { - throw NotFoundException.notFound(createFileContext(toBeDeleted)); + throw notFound(createFileContext(toBeDeleted)); } try { getClone().rm().addFilepattern(toBeDeleted).call(); @@ -109,8 +124,8 @@ public class GitModifyCommand extends AbstractGitCommand implements ModifyComman } } - private ContextEntry.ContextBuilder createFileContext(String toBeDeleted) { - ContextEntry.ContextBuilder contextBuilder = entity("file", toBeDeleted); + private ContextEntry.ContextBuilder createFileContext(String path) { + ContextEntry.ContextBuilder contextBuilder = entity("file", path); if (!StringUtils.isEmpty(request.getBranch())) { contextBuilder.in("branch", request.getBranch()); } @@ -118,11 +133,6 @@ public class GitModifyCommand extends AbstractGitCommand implements ModifyComman return contextBuilder; } - @Override - public void modify(String path, File file) { - - } - @Override public void move(String sourcePath, String targetPath) { diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitModifyCommandTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitModifyCommandTest.java index 1a9bd5e04a..9916272596 100644 --- a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitModifyCommandTest.java +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitModifyCommandTest.java @@ -129,6 +129,38 @@ public class GitModifyCommandTest extends AbstractGitCommandTestBase { assertInTree(assertions); } + @Test + public void shouldModifyExistingFile() throws IOException, GitAPIException { + File newFile = Files.write(temporaryFolder.newFile().toPath(), "new content".getBytes()).toFile(); + + GitModifyCommand command = createCommand(); + + ModifyCommandRequest request = new ModifyCommandRequest(); + request.setCommitMessage("test commit"); + request.addRequest(new ModifyCommandRequest.ModifyFileRequest("a.txt", newFile)); + request.setAuthor(new Person("Dirk Gently", "dirk@holistic.det")); + + command.execute(request); + + TreeAssertions assertions = canonicalTreeParser -> assertThat(canonicalTreeParser.findFile("a.txt")).isTrue(); + + assertInTree(assertions); + } + + @Test(expected = NotFoundException.class) + public void shouldFailIfFileToModifyDoesNotExist() throws IOException { + File newFile = Files.write(temporaryFolder.newFile().toPath(), "new content".getBytes()).toFile(); + + GitModifyCommand command = createCommand(); + + ModifyCommandRequest request = new ModifyCommandRequest(); + request.setCommitMessage("test commit"); + request.addRequest(new ModifyCommandRequest.ModifyFileRequest("no.such.file", newFile)); + request.setAuthor(new Person("Dirk Gently", "dirk@holistic.det")); + + command.execute(request); + } + @Test(expected = BadRequestException.class) public void shouldFailIfNoChangesMade() throws IOException { File newFile = Files.write(temporaryFolder.newFile().toPath(), "b\n".getBytes()).toFile();