Mercurial > hg > mercurial
changeset 339:b799355b4016
Merge branch Eluru-6.5.x
author | Dmitry Neverov <dmitry.neverov@jetbrains.com> |
---|---|
date | Fri, 02 Dec 2011 15:35:00 +0300 |
parents | ae189ede9756 (current diff) d31d7c81b637 (diff) |
children | abfaa81ee52b |
files | mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/BaseCommand.java mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CatCommand.java mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CommandUtil.java mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupportTest.java |
diffstat | 9 files changed, 116 insertions(+), 24 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/BaseCommand.java Thu Dec 01 14:51:35 2011 +0300 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/BaseCommand.java Fri Dec 02 15:35:00 2011 +0300 @@ -72,9 +72,9 @@ } /** - * Since mercurial 1.7 on Windows the only file inside '<mercurial_install_dir>/bin' is 'hg.cmd' - * which run hg.exe placed in the parent dir. GeneralCommandLine will not find hg.cmd, in the - * case when $PATH contains <mercurial_install_dir>/bin and doesn't contain <mercurial_install_dir> + * Since mercurial 1.7 on Windows the only file inside '<mercurial_install_dir>/bin' is 'hg.cmd' + * which run hg.exe placed in the parent dir. GeneralCommandLine will not find hg.cmd, in the + * case when $PATH contains <mercurial_install_dir>/bin and doesn't contain <mercurial_install_dir> * and hg executable is set to 'hg'. To fix it - run hg using windows shell which expand * hg to hg.cmd correctly. * @param cli command line in which to setup hg executable
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CommandUtil.java Thu Dec 01 14:51:35 2011 +0300 +++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/command/CommandUtil.java Fri Dec 02 15:35:00 2011 +0300 @@ -31,9 +31,8 @@ private static final int DEFAULT_COMMAND_TIMEOUT_SEC = 3600; public static void checkCommandFailed(@NotNull String cmdName, @NotNull ExecResult res) throws VcsException { - if (res.getExitCode() != 0 || res.getException() != null) { + if (res.getExitCode() != 0 || res.getException() != null) commandFailed(cmdName, res); - } if (res.getStderr().length() > 0) { Loggers.VCS.warn("Error output produced by: " + cmdName); Loggers.VCS.warn(res.getStderr()); @@ -41,18 +40,21 @@ } public static void commandFailed(final String cmdName, final ExecResult res) throws VcsException { + final String message = createCommandLogMessage(cmdName, res); + Loggers.VCS.warn(message); + if (hasImportantException(res)) + Loggers.VCS.error("Error during executing '" + cmdName + "'", res.getException()); + throw new VcsException(message); + } + + private static String createCommandLogMessage(final String cmdName, final ExecResult res) { String stderr = res.getStderr(); String stdout = res.getStdout(); String exceptionMessage = getExceptionMessage(res); - final String message = "'" + cmdName + "' command failed.\n" + + return "'" + cmdName + "' command failed.\n" + (!StringUtil.isEmpty(stdout) ? "stdout: " + stdout + "\n" : "") + (!StringUtil.isEmpty(stderr) ? "stderr: " + stderr + "\n" : "") + (exceptionMessage != null ? "exception: " + exceptionMessage : ""); - Loggers.VCS.warn(message); - if (hasImportantException(res)) { - Loggers.VCS.error("Error during executing '" + cmdName + "'", res.getException()); - } - throw new VcsException(message); } @Nullable
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java Thu Dec 01 14:51:35 2011 +0300 +++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java Fri Dec 02 15:35:00 2011 +0300 @@ -33,6 +33,7 @@ import org.jetbrains.annotations.Nullable; import java.io.File; +import java.io.FileFilter; import java.io.FileInputStream; import java.io.IOException; import java.util.*; @@ -41,6 +42,8 @@ import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; +import static com.intellij.openapi.util.text.StringUtil.isEmptyOrSpaces; + /** * Mercurial VCS plugin for TeamCity works as follows: * <ul> @@ -61,6 +64,8 @@ private final ServerPluginConfig myConfig; private final HgPathProvider myHgPathProvider; private final CommandFactory myCommandFactory; + private final FileFilter myIgnoreDotHgFilter = new IgnoreDotHgFilter(); + private final FileFilter myAcceptAllFilter = new AcceptAllFilter(); public MercurialVcsSupport(@NotNull final VcsManager vcsManager, @NotNull final SBuildServer server, @@ -350,22 +355,73 @@ File tempDir = FileUtil.createTempDirectory("mercurial", toVer.getId()); try { File mirrorDir = getWorkingDir(settings); - ArchiveCommand archive = new ArchiveCommand(settings, mirrorDir); - archive.setDestDir(tempDir); - archive.setToId(toVer.getId()); - archive.execute(); - buildPatchFromDirectory(builder, tempDir, checkoutRules); + if (hasSubrepositories(settings, toVer)) { + Loggers.VCS.debug("Repository '" + settings.getRepository() + "' has submodules at revision " + toVer.getId() + ", use 'hg clone' to build clean patch"); + CloneCommand cl = new CloneCommand(settings, tempDir); + cl.setRepository(mirrorDir.getAbsolutePath()); + cl.setToId(toVer.getId()); + cl.setUpdateWorkingDir(false); + cl.setUsePullProtocol(myConfig.isUsePullProtocol()); + cl.execute(); + + UpdateCommand up = new UpdateCommand(settings, tempDir); + up.setToId(toVer.getId()); + up.execute(); + + buildPatchFromDirectory(builder, tempDir, checkoutRules, myIgnoreDotHgFilter); + } else { + Loggers.VCS.debug("Repository '" + settings.getRepository() + "' doesn't have submodules at revision " + toVer.getId() + ", use 'hg archive' to build clean patch"); + ArchiveCommand archive = new ArchiveCommand(settings, mirrorDir); + archive.setDestDir(tempDir); + archive.setToId(toVer.getId()); + archive.execute(); + buildPatchFromDirectory(builder, tempDir, checkoutRules, myAcceptAllFilter); + } } finally { FileUtil.delete(tempDir); } } - private void buildPatchFromDirectory(final PatchBuilder builder, final File repRoot, final CheckoutRules checkoutRules) throws IOException { - buildPatchFromDirectory(repRoot, builder, repRoot, checkoutRules); + private boolean hasSubrepositories(@NotNull final Settings settings, @NotNull final ChangeSet cset) throws VcsException { + String hgsub = getFileContent(".hgsub", settings, cset); + return !isEmptyOrSpaces(hgsub); } - private void buildPatchFromDirectory(File curDir, final PatchBuilder builder, final File repRoot, final CheckoutRules checkoutRules) throws IOException { - File[] files = curDir.listFiles(); + /** + * Returns file's content or empty string if it doesn't exist. + * @param path path of the file of interest + * @param settings root settings + * @param cset repository cset (should be present in the repository) + * @return see above + */ + @NotNull + private String getFileContent(@NotNull final String path, @NotNull final Settings settings, @NotNull final ChangeSet cset) throws VcsException { + File dir = getWorkingDir(settings); + CatCommand cat = new CatCommand(settings, dir); + cat.setRevId(cset.getId()); + File parentDir = null; + try { + parentDir = cat.execute(Collections.singletonList(path), false); + File f = new File(parentDir, path); + if (f.isFile()) + return FileUtil.readText(f); + else + return ""; + } catch (Exception e) { + return ""; + } finally { + if (parentDir != null) + deleteTmpDir(parentDir); + } + } + + + private void buildPatchFromDirectory(final PatchBuilder builder, final File repRoot, final CheckoutRules checkoutRules, @NotNull final FileFilter filter) throws IOException { + buildPatchFromDirectory(repRoot, builder, repRoot, checkoutRules, filter); + } + + private void buildPatchFromDirectory(File curDir, final PatchBuilder builder, final File repRoot, final CheckoutRules checkoutRules, @NotNull final FileFilter filter) throws IOException { + File[] files = curDir.listFiles(filter); if (files != null) { for (File realFile: files) { String relPath = realFile.getAbsolutePath().substring(repRoot.getAbsolutePath().length()); @@ -374,7 +430,7 @@ final File virtualFile = new File(mappedPath); if (realFile.isDirectory()) { builder.createDirectory(virtualFile); - buildPatchFromDirectory(realFile, builder, repRoot, checkoutRules); + buildPatchFromDirectory(realFile, builder, repRoot, checkoutRules, filter); } else { final FileInputStream is = new FileInputStream(realFile); try { @@ -385,7 +441,7 @@ } } else { if (realFile.isDirectory()) { - buildPatchFromDirectory(realFile, builder, repRoot, checkoutRules); + buildPatchFromDirectory(realFile, builder, repRoot, checkoutRules, filter); } } } @@ -782,4 +838,16 @@ public boolean isDAGBasedVcs() { return true; } + + private static class IgnoreDotHgFilter implements FileFilter { + public boolean accept(final File file) { + return !(file.isDirectory() && ".hg".equals(file.getName())); + } + } + + private static class AcceptAllFilter implements FileFilter { + public boolean accept(File pathname) { + return true; + } + } }
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupportTest.java Thu Dec 01 14:51:35 2011 +0300 +++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupportTest.java Fri Dec 02 15:35:00 2011 +0300 @@ -34,6 +34,9 @@ import java.io.IOException; import java.util.*; +import static com.intellij.openapi.util.io.FileUtil.copyDir; +import static com.intellij.openapi.util.io.FileUtil.moveDirWithContent; + @Test public class MercurialVcsSupportTest extends BaseMercurialTestCase { @@ -127,7 +130,7 @@ builder.close(); return output; } - + @Test public void test_build_patch() throws IOException, VcsException { setName("cleanPatch1"); @@ -181,6 +184,20 @@ checkPatchResult(output.toByteArray()); } + public void test_clean_patch_with_subrepositories() throws Exception { + File r1 = new File(myPluginConfig.getCachesDir(), "r1"); + File r3 = new File(myPluginConfig.getCachesDir(), "r3"); + copyDir(new File("mercurial-tests/testData/subrepos/r1"), r1); + copyDir(new File("mercurial-tests/testData/subrepos/r3"), r3); + moveDirWithContent(new File(r1, "hg"), new File(r1, ".hg")); + moveDirWithContent(new File(r3, "hg"), new File(r3, ".hg")); + + VcsRootImpl root = createVcsRoot(r1.getAbsolutePath()); + + setName("clean_patch_with_subrepositories"); + checkPatchResult(buildPatch(root, null, "3:d350e7209906", CheckoutRules.DEFAULT).toByteArray()); + } + public void test_get_content() throws IOException, VcsException { VcsRootImpl vcsRoot = createVcsRoot(simpleRepo()); @@ -488,4 +505,4 @@ assertTrue(myVcs.getCollectChangesPolicy() instanceof CollectChangesByCheckoutRules); } } - +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/clean_patch_with_subrepositories/after/.hgsub Fri Dec 02 15:35:00 2011 +0300 @@ -0,0 +1,1 @@ +r2 = ../r3 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/clean_patch_with_subrepositories/after/.hgsubstate Fri Dec 02 15:35:00 2011 +0300 @@ -0,0 +1,1 @@ +9e4a2fef1a1c04623a0d89edb4f3ba290cf2666e r2
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial-tests/testData/clean_patch_with_subrepositories/after/a Fri Dec 02 15:35:00 2011 +0300 @@ -0,0 +1,1 @@ +a