changeset 62:b328c6b6526d

TW-5636: Mercurial plugin can easilly hit Windows MAX_PATH limitations
author Pavel.Sher
date Wed, 26 Nov 2008 19:12:27 +0300
parents 59add01ab524
children cef5cfe52e3e
files build.xml mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/Constants.java mercurial-server/resources/buildServerResources/mercurialSettings.jsp mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupportTest.java
diffstat 5 files changed, 103 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/build.xml	Sun Oct 26 17:08:25 2008 +0300
+++ b/build.xml	Wed Nov 26 19:12:27 2008 +0300
@@ -10,16 +10,35 @@
     <jar destfile="${distPath}/unpacked/mercurial-common.jar" basedir="${mercurial-common.output.dir}"/>
     <jar destfile="${distPath}/unpacked/mercurial.jar" basedir="${mercurial-server.output.dir}"/>
     <jar destfile="${distPath}/unpacked/mercurial-agent.jar" basedir="${mercurial-agent.output.dir}"/>
-    <zip basedir="${distPath}/unpacked" destfile="${distPath}/mercurial.zip">
-      <include name="mercurial-common.jar"/>
-      <include name="mercurial.jar"/>
-    </zip>
-    <zip destfile="${distPath}/mercurial-agent.zip">
+
+    <mkdir dir="${distPath}/4.0"/>
+    <mkdir dir="${distPath}/3.1/server"/>
+    <mkdir dir="${distPath}/3.1/agent"/>
+
+    <zip destfile="${distPath}/3.1/agent/mercurial-agent.zip">
       <zipfileset dir="${distPath}/unpacked" prefix="mercurial/lib">
         <include name="mercurial-agent.jar"/>
         <include name="mercurial-common.jar"/>
       </zipfileset>
     </zip>
+
+    <copy todir="${distPath}/3.1/server">
+      <fileset dir="${distPath}/unpacked">
+          <include name="mercurial-common.jar"/>
+          <include name="mercurial.jar"/>
+      </fileset>
+    </copy>
+
+    <zip basedir="${distPath}/unpacked" destfile="${distPath}/4.0/mercurial.zip" excludes="**/*">
+      <zipfileset prefix="server" dir="${distPath}/unpacked">
+          <include name="mercurial-common.jar"/>
+          <include name="mercurial.jar"/>
+      </zipfileset>
+      <zipfileset prefix="agent" dir="${distPath}/3.1/agent">
+          <include name="mercurial-agent.zip"/>
+      </zipfileset>
+    </zip>
+
     <zip basedir="${basedir}" destfile="${distPath}/mercurial-src.zip">
       <exclude name=".hg/**"/>
       <exclude name="dist/**"/>
@@ -27,6 +46,8 @@
       <exclude name="*.iws"/>
       <exclude name="test-output/**"/>
     </zip>
+
+    <delete dir="${distPath}/unpacked"/>
   </target>
 
   <taskdef name="testng" classname="org.testng.TestNGAntTask" classpath="${basedir}/mercurial-tests/lib/testng-5.7-jdk15.jar"/>
--- a/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/Constants.java	Sun Oct 26 17:08:25 2008 +0300
+++ b/mercurial-common/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/Constants.java	Wed Nov 26 19:12:27 2008 +0300
@@ -22,6 +22,7 @@
   String REPOSITORY_PROP = "repositoryPath";
   String BRANCH_NAME_PROP = "branchName";
   String HG_COMMAND_PATH_PROP = "hgCommandPath";
+  String SERVER_CLONE_PATH_PROP = "serverClonePath";
   String USERNAME = "username";
   String PASSWORD = VcsRoot.SECURE_PROPERTY_PREFIX + "password";
 }
--- a/mercurial-server/resources/buildServerResources/mercurialSettings.jsp	Sun Oct 26 17:08:25 2008 +0300
+++ b/mercurial-server/resources/buildServerResources/mercurialSettings.jsp	Wed Nov 26 19:12:27 2008 +0300
@@ -25,10 +25,16 @@
     <th><label for="branchName">Branch name: </label></th>
     <td><props:textProperty name="branchName" /></td>
   </tr>
+  <tr>
+    <th><label for="serverClonePath">Clone repository to: </label></th>
+    <td><props:textProperty name="serverClonePath" className="longField"/>
+      <div class="smallNote" style="margin: 0;">Provide path to a parent directory on TeamCity server where a cloned repository should be created (applicable to "Automatically on server" checkout mode only). Leave blank to use default path.</div>
+    </td>
+  </tr>
   </l:settingsGroup>
   <l:settingsGroup title="Authorization settings">
   <tr>
-    <td colspan="2">You may require to provide authorization settings if you need to tag / label sources in the remote repository.</td>
+    <td colspan="2">Authorization settings can be required if you need to tag / label sources in the remote repository.</td>
   </tr>
   <tr>
     <th><label for="username">User name:</label></th>
--- a/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java	Sun Oct 26 17:08:25 2008 +0300
+++ b/mercurial-server/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupport.java	Wed Nov 26 19:12:27 2008 +0300
@@ -26,6 +26,7 @@
 import jetbrains.buildServer.serverSide.SBuildServer;
 import jetbrains.buildServer.serverSide.ServerPaths;
 import jetbrains.buildServer.util.FileUtil;
+import jetbrains.buildServer.util.StringUtil;
 import jetbrains.buildServer.vcs.*;
 import jetbrains.buildServer.vcs.patches.PatchBuilder;
 import org.jetbrains.annotations.NotNull;
@@ -69,7 +70,7 @@
         removeOldWorkFolders();
       }
     }, 0, OLD_WORK_DIRS_CLEANUP_PERIOD, TimeUnit.SECONDS);
-    myDefaultWorkFolderParent = new File(paths.getCachesDir());
+    myDefaultWorkFolderParent = new File(paths.getCachesDir(), "mercurial");
   }
 
   public List<ModificationData> collectBuildChanges(final VcsRoot root,
@@ -197,6 +198,9 @@
         if (isEmpty(properties.get(Constants.REPOSITORY_PROP))) {
           result.add(new InvalidProperty(Constants.REPOSITORY_PROP, "Repository must be specified"));
         }
+        if (isEmpty(properties.get(Constants.SERVER_CLONE_PATH_PROP))) {
+          properties.put(Constants.SERVER_CLONE_PATH_PROP, myDefaultWorkFolderParent.getAbsolutePath());
+        }
         return result;
       }
     };
@@ -250,7 +254,10 @@
 
   @Nullable
   public Map<String, String> getDefaultVcsProperties() {
-    return Collections.singletonMap(Constants.HG_COMMAND_PATH_PROP, "hg");
+    Map<String, String> defaults = new HashMap<String, String>();
+    defaults.put(Constants.HG_COMMAND_PATH_PROP, "hg");
+    defaults.put(Constants.SERVER_CLONE_PATH_PROP, myDefaultWorkFolderParent.getAbsolutePath());
+    return defaults;
   }
 
   public String getVersionDisplayName(final String version, final VcsRoot root) throws VcsException {
@@ -437,7 +444,7 @@
   }
 
   private void removeOldWorkFolders() {
-    File workFoldersParent = new File(myDefaultWorkFolderParent, "mercurial");
+    File workFoldersParent = myDefaultWorkFolderParent;
     if (!workFoldersParent.isDirectory()) return;
 
     Set<File> workDirs = new HashSet<File>();
@@ -454,8 +461,12 @@
 
     for (VcsRoot vcsRoot: myVcsManager.getAllRegisteredVcsRoots()) {
       if (getName().equals(vcsRoot.getVcsName())) {
-        Settings s = createSettings(vcsRoot);
-        workDirs.remove(PathUtil.getCanonicalFile(s.getLocalRepositoryDir()));
+        try {
+          Settings s = createSettings(vcsRoot);
+          workDirs.remove(PathUtil.getCanonicalFile(s.getLocalRepositoryDir()));
+        } catch (VcsException e) {
+          Loggers.VCS.error(e);
+        }
       }
     }
 
@@ -503,8 +514,32 @@
     return label.replace(':', '_').replace('\r', '_').replace('\n', '_');
   }
 
-  private Settings createSettings(final VcsRoot root) {
-    return new Settings(myDefaultWorkFolderParent, root);
+  private Settings createSettings(final VcsRoot root) throws VcsException {
+    Settings settings = new Settings(myDefaultWorkFolderParent, root);
+    String customClonePath = root.getProperty(Constants.SERVER_CLONE_PATH_PROP);
+    if (!StringUtil.isEmptyOrSpaces(customClonePath) && !myDefaultWorkFolderParent.equals(new File(customClonePath).getAbsoluteFile())) {
+      File parentDir = new File(customClonePath);
+      createClonedRepositoryParentDir(parentDir);
+
+      // take last part of repository path
+      String repPath = settings.getRepository();
+      String[] splitted = repPath.split("[/\\\\]");
+      if (splitted.length > 0) {
+        repPath = splitted[splitted.length-1];
+      }
+
+      File customWorkingDir = new File(parentDir, repPath);
+      settings.setWorkingDir(customWorkingDir);
+    } else {
+      createClonedRepositoryParentDir(myDefaultWorkFolderParent);
+    }
+    return settings;
+  }
+
+  private void createClonedRepositoryParentDir(final File parentDir) throws VcsException {
+    if (!parentDir.exists() && !parentDir.mkdirs()) {
+      throw new VcsException("Failed to create parent directory for cloned repository: " + parentDir.getAbsolutePath());
+    }
   }
 
   public boolean isAgentSideCheckoutAvailable() {
--- a/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupportTest.java	Sun Oct 26 17:08:25 2008 +0300
+++ b/mercurial-tests/src/jetbrains/buildServer/buildTriggers/vcs/mercurial/MercurialVcsSupportTest.java	Wed Nov 26 19:12:27 2008 +0300
@@ -30,6 +30,7 @@
 
 import java.io.ByteArrayOutputStream;
 import java.io.File;
+import java.io.FilenameFilter;
 import java.io.IOException;
 import java.util.List;
 import java.util.concurrent.Executors;
@@ -114,7 +115,7 @@
     assertEquals(md.getDescription(), "modified in subdir");
   }
 
-  @Test(invocationCount = 3)
+  @Test
   public void test_build_patch() throws IOException, VcsException {
     setName("cleanPatch1");
     VcsRootImpl vcsRoot = createVcsRoot();
@@ -126,6 +127,14 @@
     builder.close();
 
     checkPatchResult(output.toByteArray());
+
+    File clonedReposParentDir = new File(myServerPaths.getCachesDir(), "mercurial");
+    assertTrue(clonedReposParentDir.isDirectory());
+    assertTrue(1 == clonedReposParentDir.list(new FilenameFilter() {
+      public boolean accept(final File dir, final String name) {
+        return name.startsWith("hg_");
+      }
+    }).length);
   }
 
   public void test_build_incremental_patch() throws IOException, VcsException {
@@ -284,6 +293,23 @@
     assertEquals("default", settings.getBranchName());
   }
 
+  public void build_patch_using_custom_clone_path() throws IOException, VcsException {
+    setName("cleanPatch1");
+    VcsRootImpl vcsRoot = createVcsRoot();
+    File cloneDir = myTempFiles.createTempDir();
+    vcsRoot.addProperty(Constants.SERVER_CLONE_PATH_PROP, cloneDir.getAbsolutePath());
+
+    final ByteArrayOutputStream output = new ByteArrayOutputStream();
+    final PatchBuilderImpl builder = new PatchBuilderImpl(output);
+
+    myVcs.buildPatch(vcsRoot, null, "4:b06a290a363b", builder, new CheckoutRules(""));
+    builder.close();
+
+    checkPatchResult(output.toByteArray());
+
+    assertTrue(new File(cloneDir, new File(vcsRoot.getProperty(Constants.REPOSITORY_PROP)).getName()).isDirectory());
+  }
+
   private Object normalizePath(final String path) {
     return path.replace(File.separatorChar, '/');
   }