From a01f7187143daf69a25885d342db40d47935103c Mon Sep 17 00:00:00 2001 From: Luke Granger-Brown Date: Sat, 16 May 2020 13:55:09 +0100 Subject: [PATCH] Make Mercurial at least slightly usable. --- .../com/google/copybara/hg/HgDestination.java | 28 +++++++++---------- java/com/google/copybara/hg/HgModule.java | 25 +++++++++++++++++ java/com/google/copybara/hg/HgRepository.java | 2 +- .../google/copybara/util/CommandRunner.java | 2 +- 4 files changed, 40 insertions(+), 17 deletions(-) diff --git a/java/com/google/copybara/hg/HgDestination.java b/java/com/google/copybara/hg/HgDestination.java index d904781f..b60e4911 100644 --- a/java/com/google/copybara/hg/HgDestination.java +++ b/java/com/google/copybara/hg/HgDestination.java @@ -162,7 +162,7 @@ public class HgDestination implements Destination { @Override public boolean supportsHistory() { - throw new UnsupportedOperationException("Not implemented yet"); + return true; } private HgRepository getRepository() throws RepoException { @@ -216,7 +216,7 @@ public class HgDestination implements Destination { Path workDir, HgRepository localRepo) throws RepoException, IOException { // Create a temp archive of the remote repository to compute diff with - Path tempArchivePath = generalOptions.getDirFactory().newTempDir("tempArchive"); + Path tempArchivePath = Files.createTempDirectory(workDir.getParent(), "tempArchive"); localRepo.archive(tempArchivePath.toString()); // Find excluded files in the archive @@ -238,24 +238,20 @@ public class HgDestination implements Destination { Operation diffOp = diff.getOperation(); if (diffOp.equals(Operation.ADD)) { + Path targetPath = localRepo.getHgDir().getParent().resolve(diff.getName()); + Files.createDirectories(targetPath.getParent()); Files.copy(workDir.resolve(diff.getName()), - localRepo.getHgDir().resolve(diff.getName()), StandardCopyOption.COPY_ATTRIBUTES); - localRepo.hg(localRepo.getHgDir(), "add", diff.getName()); + targetPath, StandardCopyOption.COPY_ATTRIBUTES, StandardCopyOption.REPLACE_EXISTING); } if (diffOp.equals(Operation.MODIFIED)) { Files.copy(workDir.resolve(diff.getName()), - localRepo.getHgDir().resolve(diff.getName()), StandardCopyOption.REPLACE_EXISTING); + localRepo.getHgDir().getParent().resolve(diff.getName()), StandardCopyOption.REPLACE_EXISTING); } if (diffOp.equals(Operation.DELETE)) { - try { - localRepo.hg(localRepo.getHgDir(), "remove", diff.getName()); - } catch (RepoException e) { - // Ignore a .hg_archival file that is not in the workdir nor in the local repo. - if (!e.getMessage().contains(".hg_archival.txt: No such file or directory")) { - throw e; - } + if (!diff.getName().equals(".hg_archival.txt")) { + Files.delete(localRepo.getHgDir().getParent().resolve(diff.getName())); } } } @@ -264,6 +260,8 @@ public class HgDestination implements Destination { } finally { FileUtil.deleteRecursively(tempArchivePath); } + + localRepo.hg(localRepo.getHgDir().getParent(), "addremove"); } /** @@ -282,7 +280,7 @@ public class HgDestination implements Destination { localRepo.cleanUpdate(remoteFetch); // Set the default path of the local repo to be the remote repo, so we can push to it - Files.write(localRepo.getHgDir().resolve(".hg/hgrc"), + Files.write(localRepo.getHgDir().getParent().resolve(".hg/hgrc"), String.format("[paths]\ndefault = %s\n", repoUrl).getBytes(StandardCharsets.UTF_8)); console.progress("Hg Destination: Computing diff"); @@ -293,12 +291,12 @@ public class HgDestination implements Destination { ChangeMessage msg = getChangeMessage(transformResult, ORIGIN_LABEL_SEPARATOR); String date = transformResult.getTimestamp().format(DateTimeFormatter.RFC_1123_DATE_TIME); - localRepo.hg(localRepo.getHgDir(), "commit", "--user", + localRepo.hg(localRepo.getHgDir().getParent(), "commit", "--user", transformResult.getAuthor().toString(), "--date", date, "-m", msg.toString()); console.progress(String.format("Hg Destination: Pushing to %s %s", repoUrl, remotePush)); - localRepo.hg(localRepo.getHgDir(), "push", "--rev", remotePush, repoUrl); + localRepo.hg(localRepo.getHgDir().getParent(), "push", "--rev", remotePush, repoUrl); String tip = localRepo.identify("tip").getGlobalId(); diff --git a/java/com/google/copybara/hg/HgModule.java b/java/com/google/copybara/hg/HgModule.java index d8a22f33..b1ca7ba2 100644 --- a/java/com/google/copybara/hg/HgModule.java +++ b/java/com/google/copybara/hg/HgModule.java @@ -19,6 +19,7 @@ package com.google.copybara.hg; import static com.google.copybara.config.SkylarkUtil.checkNotEmpty; import com.google.common.base.Preconditions; +import com.google.copybara.GeneralOptions; import com.google.copybara.Options; import com.google.copybara.config.LabelsAwareModule; import com.google.copybara.doc.annotations.UsesFlags; @@ -73,4 +74,28 @@ public class HgModule implements LabelsAwareModule, StarlarkValue { public HgOrigin origin(String url, String ref) throws EvalException { return HgOrigin.newHgOrigin(options, checkNotEmpty(url, "url"), ref); } + + @StarlarkMethod( + name = "destination", + doc = "EXPERIMENTAL: Defines a standard Mercurial (Hg) destination.", + parameters = { + @Param( + name = "url", + type = String.class, + named = true, + doc = "Indicates the URL of the Hg repository"), + @Param( + name = "fetch", + type = String.class, + named = true, + doc = "XXX: ref to fetch?"), + @Param( + name = "push", + type = String.class, + named = true, + doc = "XXX: ref to push?") + }) + public HgDestination destination(String url, String fetch, String push) throws EvalException { + return HgDestination.newHgDestination(url, fetch, push, options.get(GeneralOptions.class), options.get(HgOptions.class)); + } } diff --git a/java/com/google/copybara/hg/HgRepository.java b/java/com/google/copybara/hg/HgRepository.java index 414f22e7..40bc2663 100644 --- a/java/com/google/copybara/hg/HgRepository.java +++ b/java/com/google/copybara/hg/HgRepository.java @@ -141,7 +141,7 @@ public class HgRepository { } try { - hg(hgDir, builder.build(), fetchTimeout); + hg(hgDir.getParent(), builder.build(), fetchTimeout); } catch (RepoException e) { if (INVALID_HG_REPOSITORY.matcher(e.getMessage()).find()){ throw new ValidationException("Repository not found: " + e.getMessage()); diff --git a/java/com/google/copybara/util/CommandRunner.java b/java/com/google/copybara/util/CommandRunner.java index 14c12987..bf96b493 100644 --- a/java/com/google/copybara/util/CommandRunner.java +++ b/java/com/google/copybara/util/CommandRunner.java @@ -185,7 +185,7 @@ public final class CommandRunner { String startMsg = ShellUtils.prettyPrintArgv(Arrays.asList(cmd.getCommandLineElements())); startMsg = startMsg.length() > MAX_COMMAND_LENGTH ? startMsg.substring(0, MAX_COMMAND_LENGTH) + "..." : startMsg; - String validStartMsg = "Executing [" + startMsg + "]"; + String validStartMsg = "Executing [" + startMsg + "] in workdir [" + cmd.getWorkingDirectory() + "]"; logger.atInfo().log(validStartMsg); if (verbose) { System.err.println(validStartMsg); -- 2.26.2