Clean up hg repo on reclaim

This commit is contained in:
René Pfeuffer
2020-05-07 22:01:30 +02:00
parent fcdd2243c3
commit e8247cbfe1
2 changed files with 168 additions and 4 deletions

View File

@@ -27,11 +27,14 @@ package sonia.scm.repository.spi;
import com.aragost.javahg.BaseRepository;
import com.aragost.javahg.Repository;
import com.aragost.javahg.commands.CloneCommand;
import com.aragost.javahg.commands.ExecutionException;
import com.aragost.javahg.commands.PullCommand;
import com.aragost.javahg.commands.StatusCommand;
import com.aragost.javahg.commands.UpdateCommand;
import com.aragost.javahg.commands.flags.CloneCommandFlags;
import sonia.scm.repository.util.WorkingCopyPool;
import sonia.scm.repository.util.SimpleWorkingCopyFactory;
import sonia.scm.util.IOUtil;
import sonia.scm.web.HgRepositoryEnvironmentBuilder;
import javax.inject.Inject;
@@ -71,11 +74,22 @@ public class SimpleHgWorkingCopyFactory extends SimpleWorkingCopyFactory<Reposit
}
@Override
protected ParentAndClone<Repository, Repository> reclaimRepository(HgCommandContext context, File target, String initialBranch) throws IOException {
protected ParentAndClone<Repository, Repository> reclaimRepository(HgCommandContext context, File target, String initialBranch) throws ReclaimFailedException {
Repository centralRepository = openCentral(context);
BaseRepository clone = Repository.open(target);
UpdateCommand.on(clone).rev(initialBranch).execute();
return new ParentAndClone<>(centralRepository, clone, target);
try {
BaseRepository clone = Repository.open(target);
for (String unknown : StatusCommand.on(clone).execute().getUnknown()) {
delete(clone.getDirectory(), unknown);
}
UpdateCommand.on(clone).rev(initialBranch).clean().execute();
return new ParentAndClone<>(centralRepository, clone, target);
} catch (ExecutionException | IOException e) {
throw new ReclaimFailedException(e);
}
}
private void delete(File directory, String unknownFile) throws IOException {
IOUtil.delete(new File(directory, unknownFile));
}
@Override

View File

@@ -0,0 +1,150 @@
/*
* MIT License
*
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.repository.spi;
import com.aragost.javahg.Repository;
import com.google.inject.util.Providers;
import org.assertj.core.api.Assertions;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.rules.TemporaryFolder;
import org.junitpioneer.jupiter.TempDirectory;
import sonia.scm.repository.HgHookManager;
import sonia.scm.repository.HgTestUtil;
import sonia.scm.repository.util.CachingAllWorkingCopyPool;
import sonia.scm.repository.util.NoneCachingWorkingCopyPool;
import sonia.scm.repository.util.WorkdirProvider;
import sonia.scm.repository.util.WorkingCopy;
import sonia.scm.web.HgRepositoryEnvironmentBuilder;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import static org.assertj.core.api.Assertions.assertThat;
@ExtendWith(TempDirectory.class)
public class SimpleHgWorkingCopyFactoryTest extends AbstractHgCommandTestBase {
@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();
private WorkdirProvider workdirProvider;
private SimpleHgWorkingCopyFactory workingCopyFactory;
@Before
public void bindScmProtocol() throws IOException {
workdirProvider = new WorkdirProvider(temporaryFolder.newFolder());
HgHookManager hookManager = HgTestUtil.createHookManager();
HgRepositoryEnvironmentBuilder environmentBuilder = new HgRepositoryEnvironmentBuilder(handler, hookManager);
workingCopyFactory = new SimpleHgWorkingCopyFactory(Providers.of(environmentBuilder), new CachingAllWorkingCopyPool(workdirProvider)) {
@Override
public void configure(com.aragost.javahg.commands.PullCommand pullCommand) {
// we do not want to configure http hooks in this unit test
}
};
}
@Test
public void shouldSwitchBranch() {
WorkingCopy<Repository, Repository> workingCopy = workingCopyFactory.createWorkingCopy(cmdContext, "default");
File initialDirectory = workingCopy.getDirectory();
workingCopy.close();
assertThat(initialDirectory).exists();
assertThat(initialDirectory.toPath().resolve("f.txt")).exists();
WorkingCopy<Repository, Repository> cachedWorkingCopy = workingCopyFactory.createWorkingCopy(cmdContext, "test-branch");
assertThat(cachedWorkingCopy.getDirectory()).isEqualTo(initialDirectory);
assertThat(cachedWorkingCopy.getDirectory().toPath().resolve("f.txt")).doesNotExist();
}
@Test
public void shouldReplaceFileWithContentFromNewBranch() throws IOException {
WorkingCopy<Repository, Repository> workingCopy = workingCopyFactory.createWorkingCopy(cmdContext, "test-branch");
File initialDirectory = workingCopy.getDirectory();
Path fileToBeReplaced = initialDirectory.toPath().resolve("f.txt");
Files.createFile(fileToBeReplaced);
Files.write(fileToBeReplaced, Collections.singleton("some content"));
workingCopy.close();
assertThat(initialDirectory).exists();
assertThat(fileToBeReplaced).hasContent("some content");
WorkingCopy<Repository, Repository> cachedWorkingCopy = workingCopyFactory.createWorkingCopy(cmdContext, "default");
assertThat(cachedWorkingCopy.getDirectory()).isEqualTo(initialDirectory);
assertThat(cachedWorkingCopy.getDirectory().toPath().resolve("f.txt")).exists();
assertThat(fileToBeReplaced).hasContent("f");
}
@Test
public void shouldDeleteUntrackedFile() throws IOException {
WorkingCopy<Repository, Repository> workingCopy = workingCopyFactory.createWorkingCopy(cmdContext, "test-branch");
File initialDirectory = workingCopy.getDirectory();
Path fileToBeDeleted = initialDirectory.toPath().resolve("x.txt");
Files.createFile(fileToBeDeleted);
Files.write(fileToBeDeleted, Collections.singleton("some content"));
workingCopy.close();
assertThat(initialDirectory).exists();
assertThat(fileToBeDeleted).hasContent("some content");
WorkingCopy<Repository, Repository> cachedWorkingCopy = workingCopyFactory.createWorkingCopy(cmdContext, "default");
assertThat(cachedWorkingCopy.getDirectory()).isEqualTo(initialDirectory);
assertThat(cachedWorkingCopy.getDirectory().toPath().resolve("x.txt")).doesNotExist();
}
@Test
public void shouldDeleteUntrackedDirectory() throws IOException {
WorkingCopy<Repository, Repository> workingCopy = workingCopyFactory.createWorkingCopy(cmdContext, "test-branch");
File initialDirectory = workingCopy.getDirectory();
Path directoryToBeDeleted = initialDirectory.toPath().resolve("newDir");
Files.createDirectories(directoryToBeDeleted);
Path fileToBeDeleted = directoryToBeDeleted.resolve("y.txt");
Files.createFile(fileToBeDeleted);
Files.write(fileToBeDeleted, Collections.singleton("some content"));
workingCopy.close();
assertThat(initialDirectory).exists();
assertThat(fileToBeDeleted).hasContent("some content");
WorkingCopy<Repository, Repository> cachedWorkingCopy = workingCopyFactory.createWorkingCopy(cmdContext, "default");
assertThat(cachedWorkingCopy.getDirectory()).isEqualTo(initialDirectory);
assertThat(cachedWorkingCopy.getDirectory().toPath().resolve("newDir")).doesNotExist();
}
}