1 package org.antmod.scm.impl; 2 3 import java.io.BufferedReader ; 4 import java.io.File ; 5 import java.io.IOException ; 6 import java.io.StringReader ; 7 import java.util.ArrayList ; 8 import java.util.Collections ; 9 import java.util.StringTokenizer ; 10 11 import org.antmod.conf.AntmodProperties; 12 import org.antmod.scm.ScmDifference; 13 import org.antmod.scm.ScmSystem; 14 import org.antmod.scm.ScmUrl; 15 import org.antmod.scm.ScmVersion; 16 import org.antmod.util.ProcessLauncher; 17 import org.apache.commons.io.FileUtils; 18 import org.apache.commons.io.HexDump; 19 import org.apache.commons.lang.StringUtils; 20 import org.apache.tools.ant.BuildException; 21 22 33 public class SvnSystemImpl implements ScmSystem { 34 35 public final static char REVISION_NAME_SEPARATOR = '_'; 36 public final static char REVISION_VERSION_SEPARATOR = '.'; 37 38 private ScmUrl url; 39 private String standardOutput; 40 private String errorOutput; 41 42 43 46 public SvnSystemImpl() { 47 } 48 49 public String getStandardOutput() { 50 return standardOutput; 51 } 52 public String getErrorOutput() { 53 return errorOutput; 54 } 55 56 59 public ScmUrl getUrl() { 60 return url; 61 } 62 63 66 public void setUrl(ScmUrl providerUrl) { 67 this.url = providerUrl; 68 } 69 70 75 private void doImport(File file, boolean recursive) { 76 if (!file.isDirectory()) { 77 throw new IllegalArgumentException ("Cannot import a file, it needs to be a directory: " + file.getPath()); 78 } 79 ArrayList svnCommand = new ArrayList (); 80 81 String creationMessage = "Creation of new module " + file.getName(); 82 String svnModulePath = renderUrlToSvnArg(getUrl()) + '/' + file.getName(); 83 84 svnCommand.add("import"); 86 addAuthenticationArgs(svnCommand); 87 svnCommand.add("-m"); 88 svnCommand.add(creationMessage); 89 if (!recursive) { 90 svnCommand.add("--non-recursive"); 91 } 92 svnCommand.add("."); 93 svnCommand.add(svnModulePath + "/trunk"); 94 95 run(file, svnCommand); 97 98 svnCommand = new ArrayList (); 100 svnCommand.add("mkdir"); 101 addAuthenticationArgs(svnCommand); 102 svnCommand.add("-m"); 103 svnCommand.add(creationMessage); 104 svnCommand.add(svnModulePath + "/branches"); 105 run(null, svnCommand); 106 107 svnCommand.set(svnCommand.size() - 1, svnModulePath + "/tags"); 108 run(null, svnCommand); 109 } 110 111 public void doAdd(File file, boolean recursive) { 112 File parentDir = file.getParentFile(); 114 115 if (!isCheckoutDir(parentDir)) { 116 doImport(file, recursive); 118 } else { 119 ArrayList svnCommand = new ArrayList (); 121 svnCommand.add("add"); 122 svnCommand.add(file.getName()); 123 run(parentDir, svnCommand); 124 } 125 } 126 127 128 131 public void doCheckout(String moduleName, File destDir, ScmVersion version, boolean reallyQuiet) { 132 doSvnRetrieve("checkout", moduleName, destDir, version, reallyQuiet); 133 } 134 135 138 public void doExport(String moduleName, File destDir, ScmVersion version, boolean reallyQuiet) { 139 doSvnRetrieve("export", moduleName, destDir, version, reallyQuiet); 140 } 141 142 public void doCheckoutOrUpdate(String packageName, File destDir, ScmVersion version, boolean reallyQuiet) { 143 if (isCheckoutDir(destDir)) { 144 doUpdate(packageName, destDir, version, reallyQuiet); 145 } else { 146 doCheckout(packageName, destDir, version, reallyQuiet); 147 } 148 } 149 150 private void doSvnRetrieve(String svnCommandName, String moduleName, File destDir, ScmVersion version, boolean reallyQuiet) { 151 if (destDir == null) { 152 throw new IllegalArgumentException ("destDir attribute for Subversion " + svnCommandName + " must not be null"); 153 } 154 if (destDir.getParentFile() == null || !destDir.getParentFile().exists()) { 155 throw new IllegalArgumentException ("destDir parent directory (basedir for the " +svnCommandName + ") for Subversion " + svnCommandName + " does not exist on filesystem: " + destDir.getParentFile()); 156 } 157 158 ArrayList svnCommand = new ArrayList (); 159 svnCommand.add(svnCommandName); 160 161 addAuthenticationArgs(svnCommand); 163 164 svnCommand.add(renderUrlToSvnArg(getUrl()) + '/' + renderSvnPath(moduleName, version)); 166 167 svnCommand.add(destDir.getName()); 169 170 boolean suppressErrorOutput = reallyQuiet; 171 boolean suppressStandardOutput = reallyQuiet; 172 run(destDir.getParentFile(), svnCommand, suppressErrorOutput, suppressStandardOutput); 174 180 if (!suppressStandardOutput) { 181 this.standardOutput = null; 182 } 183 } 184 185 189 private void addAuthenticationArgs(ArrayList list) { 190 if (getUrl().getUser() != null) { 192 list.add("--username"); 193 list.add(getUrl().getUser()); 194 } 195 if (getUrl().getPassword() != null) { 196 list.add("--password"); 197 list.add(getUrl().getPassword()); 198 199 list.add("--non-interactive"); 201 } 202 203 } 204 205 206 public void doMerge(File moduleDir, ScmVersion version) { 207 doMerge(moduleDir, version, false); 208 } 209 public void doMerge(File moduleDir, ScmVersion version, boolean reallyQuiet) { 210 if (moduleDir == null) { 211 throw new IllegalArgumentException ("moduleDir attribute for Subversion merge must not be null"); 212 } 213 if (!moduleDir.exists()) { 214 throw new IllegalArgumentException ("moduleDir for Subversion merge does not exist on filesystem: " + moduleDir.getPath()); 215 } 216 if (!isCheckoutDir(moduleDir)) { 217 throw new IllegalArgumentException ("Directory " + moduleDir.getPath() + " is not an existing Subversion checkout."); 218 } 219 ScmVersion localVersion = getLocalVersion(moduleDir); 220 221 ArrayList svnCommand = new ArrayList (); 222 svnCommand.add("merge"); 223 224 addAuthenticationArgs(svnCommand); 226 227 svnCommand.add(renderUrlToSvnArg(getUrl()) + '/' + renderSvnPath(moduleDir.getName(), localVersion)); 229 svnCommand.add(renderUrlToSvnArg(getUrl()) + '/' + renderSvnPath(moduleDir.getName(), version)); 230 231 boolean suppressErrorOutput = reallyQuiet; 233 boolean suppressStandardOutput = reallyQuiet; 234 run(moduleDir, svnCommand, suppressErrorOutput, suppressStandardOutput); 235 if (!suppressStandardOutput) { 236 this.standardOutput = null; 237 } 238 } 239 240 241 public void doUpdate(File file, ScmVersion version) { 242 doUpdate(file.getName(), file, version, false); 243 } 244 245 private void doUpdate(String packageName, File file, ScmVersion version, boolean reallyQuiet) { 246 if (file == null) { 247 throw new IllegalArgumentException ("file attribute for Subversion update must not be null"); 248 } 249 if (!file.exists()) { 250 throw new IllegalArgumentException ("file for Subversion update does not exist on filesystem: " + file.getPath()); 251 } 252 if (!isCheckoutDir(file)) { 253 throw new IllegalArgumentException ("Directory " + file.getPath() + " is not an existing Subversion checkout."); 254 } 255 256 String currentCheckoutUrl = readCheckoutUrl(file); 258 boolean differentUrl = false; 259 if (currentCheckoutUrl != null && 260 (currentCheckoutUrl.indexOf(this.url.getPath()) < 0 || 261 (this.url.getHost() != null && currentCheckoutUrl.indexOf(this.url.getHost()) < 0))) { 262 differentUrl = true; 263 } 264 265 ScmVersion localVersion = null; 267 boolean differentVersion = false; 268 if (version != null) { 269 localVersion = getLocalVersion(version.getModuleName(), file); 270 if (localVersion == null) { 271 throw new IllegalStateException ("Local version of \"" + file.getName() + "\" unknown! Most likely it is an invalid Subversion checkout."); 272 } 273 if (!version.equals(localVersion)) { 274 differentVersion = true; 275 } 276 } 277 278 if (differentVersion || differentUrl) { 280 String localSvnChanges = getLocalSvnChanges(file); 282 if (!StringUtils.isBlank(localSvnChanges)) { 283 if (differentVersion) { 284 System.err.println("Subversion update from version " + localVersion + " to " + version + " not possible because of local changes:"); 285 } else { 286 System.err.println("Subversion update from url " + currentCheckoutUrl + " to " + renderUrlToSvnArg(this.url) + " not possible because of local changes:"); 287 } 288 System.err.println(localSvnChanges); 289 this.errorOutput = null; 290 return; 291 } else { 292 if (differentVersion) { 293 System.err.println("Changing existing checkout of \"" + file.getName() + "\" from version \"" + localVersion + "\" to \"" + version + "\""); 294 } else { 295 System.err.println("Changing existing checkout of \"" + file.getName() + "\" from url \"" + currentCheckoutUrl + "\" to \"" + renderUrlToSvnArg(this.url) + "\""); 296 } 297 298 deleteSvnFilesInDirectory(file); 300 301 doCheckout(packageName, file, version, reallyQuiet); 303 return; 304 } 305 } 306 307 ArrayList svnCommand = new ArrayList (); 309 svnCommand.add("update"); 310 311 addAuthenticationArgs(svnCommand); 313 314 boolean suppressErrorOutput = reallyQuiet; 315 boolean suppressStandardOutput = reallyQuiet; 316 if (file.isDirectory()) { 317 run(file, svnCommand, suppressErrorOutput, suppressStandardOutput); 318 } else { 319 svnCommand.add(file.getName()); 320 run(file.getParentFile(), svnCommand, suppressErrorOutput, suppressStandardOutput); 321 } 322 328 if (!suppressStandardOutput) { 329 this.standardOutput = null; 330 } 331 } 332 333 private void deleteSvnFilesInDirectory(File dir) { 334 ArrayList svnCommand = new ArrayList (1); 336 svnCommand.add("list"); 337 String svnResult = run(dir, svnCommand); 338 StringTokenizer st = new StringTokenizer (svnResult, "\n"); 339 while (st.hasMoreTokens()) { 340 File moduleFile = new File (dir, st.nextToken().trim()); 341 if (moduleFile.exists()) { 342 if (moduleFile.isDirectory()) { 343 try { 344 FileUtils.deleteDirectory(moduleFile); 345 } catch (IOException e) { 346 e.printStackTrace(); 347 } 348 } else { 349 moduleFile.delete(); 350 } 351 } 352 } 353 354 try { 356 FileUtils.deleteDirectory(new File (dir, ".svn")); 357 } catch (IOException e) { 358 e.printStackTrace(); 359 } 360 } 361 362 363 367 public void doCommit(File file, String message) { 368 if (file == null) { 369 throw new IllegalArgumentException ("file attribute for Subversion commit must not be null"); 370 } 371 if (message == null) { 372 throw new IllegalArgumentException ("message attribute for Subversion commit must not be null"); 373 } 374 375 if (!isCheckoutDir(file)) { 376 System.err.println("Nothing to commit in \"" + file.getPath() + "\", it is not an svn working copy."); 377 return; 378 } 379 380 ArrayList svnCommand = new ArrayList (); 381 svnCommand.add("commit"); 382 383 addAuthenticationArgs(svnCommand); 385 386 svnCommand.add("-m"); 388 svnCommand.add(message); 389 390 if (file.isDirectory()) { 392 run(file, svnCommand); 393 } else { 394 svnCommand.add(file.getName()); 395 run(file.getParentFile(), svnCommand); 396 } 397 } 398 399 400 403 public String getRevisionNumber(File file) { 404 if (file.isDirectory()) { 405 throw new IllegalArgumentException ("File for 'getRevisionNumber' is a directory: " +file); 406 } 407 408 ArrayList svnCommand = new ArrayList (1); 409 svnCommand.add("info"); 410 svnCommand.add(file.getName()); 411 String info = run(file.getParentFile(), svnCommand, true); 412 String searchKey = "Last Changed Rev:"; 413 int index = info.indexOf(searchKey); 414 if (index > 0) { 415 int endIndex = info.indexOf("\n", index); 416 if (endIndex > 0) { 417 return info.substring(index + searchKey.length(), endIndex).trim(); 418 } 419 } 420 return null; 421 } 422 423 427 public ScmVersion getLatestVersion(File moduleDir) { 428 ScmVersion localVersion = getLocalVersion(moduleDir.getName(), moduleDir); 429 if (localVersion == null) { 430 return null; 431 } 432 if (localVersion.isTag()) { 433 throw new RuntimeException ("getLatestVersion is not possible on a Subversion tag."); 434 } 435 436 if (!new File (moduleDir, "module.xml").exists()) { 437 throw new RuntimeException ("FATAL: File module.xml does not exist in the module " + moduleDir.getName() + " !!!"); 438 } 439 440 ScmVersion[] revs = getVersionsInBranch(new File (moduleDir, "module.xml"), localVersion); 441 ScmVersion latestRev = null; 442 if (revs.length > 0) { 443 return revs[0]; 444 } else { 445 return null; 446 } 447 } 448 449 455 public ScmVersion getLocalVersion(File moduleDir) throws BuildException { 456 return getLocalVersion(moduleDir.getName(), moduleDir); 457 } 458 459 public ScmVersion getLocalVersion(String moduleName, File moduleDir) throws BuildException { 460 if (moduleName == null) { 461 moduleName = moduleDir.getName(); 462 } 463 String checkoutUrl = readCheckoutUrl(moduleDir); 464 if (checkoutUrl != null) { 465 return parseSvnPath(moduleName, checkoutUrl); 466 } else { 467 return null; 468 } 469 } 470 471 475 private String readCheckoutUrl(File moduleDir) { 476 File svnDir = new File (moduleDir, ".svn"); 477 if (!svnDir.exists()) { 478 return null; 479 } 480 481 493 try { 494 String entries = FileUtils.readFileToString(new File (svnDir, "entries"), System.getProperty("file.encoding")); 495 496 if (entries.startsWith("<?xml")) { 497 int urlIndex = entries.indexOf("url=\""); 499 if (urlIndex > 0) { 500 entries = entries.substring(urlIndex + 5); 501 int endOfUrl = entries.indexOf("\""); 502 if (endOfUrl > 0) { 503 return entries.substring(0, endOfUrl); 504 } 505 } 506 } else { 507 int urlIndex = -1; 509 for (int fifthLine = 4; fifthLine-- > 0;) { 510 urlIndex = entries.indexOf("\n", urlIndex + 1); 511 if (urlIndex < 0) { 512 return null; 513 } 514 } 515 int endOfUrl = entries.indexOf("\n", urlIndex + 1); 517 if (endOfUrl > 0) { 518 return entries.substring(urlIndex + 1, endOfUrl).trim(); 519 } 520 } 521 } catch (IOException e) { 522 e.printStackTrace(); 523 } 524 return null; 525 } 526 527 531 public ScmVersion[] getVersionsInBranch(File file, ScmVersion branch) { 532 if (file == null) { 533 throw new IllegalArgumentException ("File attribute for Subversion 'getVersionsInBranch' must not be null"); 534 } 535 File moduleDir = file.getParentFile(); 536 String moduleName = moduleDir.getName(); 537 538 ArrayList svnCommand = new ArrayList (); 539 svnCommand.add("list"); 540 addAuthenticationArgs(svnCommand); 541 542 String modulePath = renderUrlToSvnArg(getUrl()) + '/' + moduleName; 544 boolean returnTags = false; 545 if (branch == null || branch.isTrunk()) { 546 modulePath += "/branches"; 548 } else { 549 modulePath += "/tags"; 551 returnTags = true; 552 } 553 svnCommand.add(modulePath); 554 555 ArrayList result = new ArrayList (); 556 557 String svnResult = run(null, svnCommand); 561 StringTokenizer st = new StringTokenizer (svnResult, "\n"); 562 String branchVersionString = branch.toString(REVISION_VERSION_SEPARATOR); 563 String versionString; 564 while (st.hasMoreTokens()) { 565 versionString = st.nextToken().trim(); 566 if (versionString.endsWith("/")) { 567 versionString = versionString.substring(0, versionString.length() - 1); 568 } 569 if (returnTags) { 570 if (versionString.startsWith(branchVersionString) && countVersionChars(REVISION_VERSION_SEPARATOR, versionString) == 2) { 571 result.add(new ScmVersion(moduleName, versionString)); 572 } 573 } else { 574 if (countVersionChars(REVISION_VERSION_SEPARATOR, versionString) == 1) { 575 result.add(new ScmVersion(moduleName, versionString)); 576 } 577 } 578 } 579 580 Collections.sort(result); 582 ScmVersion[] array = new ScmVersion[result.size()]; 583 result.toArray(array); 584 return array; 585 } 586 587 593 public boolean isUpToDate(File checkoutDir) { 594 return StringUtils.isBlank(getLocalSvnChanges(checkoutDir)); 595 } 596 597 private String getLocalSvnChanges(File checkoutDir) { 598 ArrayList svnCommand = new ArrayList (2); 599 svnCommand.add("status"); 600 svnCommand.add("-q"); 601 return run(checkoutDir, svnCommand); 602 } 603 604 608 private static class ScmDifferenceImpl implements ScmDifference { 609 String filename; 610 boolean conflict = false; 611 StringBuffer log = new StringBuffer (); 612 613 ScmDifferenceImpl(String filename) { 614 this.filename = filename; 615 } 616 public String getFilename() { 617 return filename; 618 } 619 public boolean hasConflict() { 620 return conflict; 621 } 622 private void setConflict(boolean conflict) { 623 this.conflict = conflict; 624 } 625 public String getLog() { 626 return log.toString(); 627 } 628 private void addLogLine(String logLine) { 629 this.log.append(logLine); 630 this.log.append(HexDump.EOL); 631 } 632 } 633 634 637 public ScmDifference[] getDifferences(ScmVersion version1, ScmVersion version2) { 638 if (version1 .getModuleName() == null) { 639 throw new IllegalArgumentException ("Modulename attribute (of version1) for svndiffs must not be null"); 640 } 641 if (version2.getModuleName() == null) { 642 throw new IllegalArgumentException ("Modulename attribute (of version2) for svndiffs must not be null"); 643 } 644 if (!version1.getModuleName().equals(version2.getModuleName())) { 645 throw new IllegalArgumentException ("Module of version1 \"" + version1.getModuleName() + "\" is not the same as module of version2 \"" + version2.getModuleName() + "\""); 646 } 647 648 ArrayList svnCommand = new ArrayList (); 650 svnCommand.add("diff"); 651 addAuthenticationArgs(svnCommand); 652 svnCommand.add(renderUrlToSvnArg(getUrl()) + '/' + renderSvnPath(version1.getModuleName(), version1)); 653 svnCommand.add(renderUrlToSvnArg(getUrl()) + '/' + renderSvnPath(version2.getModuleName(), version2)); 654 655 ArrayList result = new ArrayList (); 656 657 String svnResult = run(null, svnCommand); 661 try { 662 BufferedReader reader = new BufferedReader (new StringReader (svnResult)); 663 String line; 664 ScmDifferenceImpl currentEntry = null; 665 666 while ((line = reader.readLine()) != null) { 667 if (line.startsWith("Index:")) { 668 String file = line.substring(7).trim(); 670 currentEntry = new ScmDifferenceImpl(file); 672 result.add(currentEntry); 673 674 } else if (currentEntry != null) { 675 currentEntry.addLogLine(line); 676 677 if (line.startsWith("! ")) { 678 currentEntry.setConflict(true); 679 } 680 } 681 } 682 } catch (IOException ioe) { 683 ioe.printStackTrace(); 684 } 685 686 ScmDifference[] array = new ScmDifference[result.size()]; 687 result.toArray(array); 688 return array; 689 } 690 691 694 public String createBranchInTrunk(ScmVersion newBranchForModule) { 695 if (newBranchForModule == null) { 696 throw new IllegalArgumentException ("newBranchForModule attribute for createBranchInTrunk must not be null"); 697 } 698 ArrayList svnCommand = new ArrayList (); 699 svnCommand.add("copy"); 700 addAuthenticationArgs(svnCommand); 701 702 svnCommand.add("-m"); 704 svnCommand.add("Create branch " + newBranchForModule); 705 706 svnCommand.add(renderUrlToSvnArg(getUrl()) + '/' + renderSvnPath(newBranchForModule.getModuleName(), null)); 708 709 svnCommand.add(renderUrlToSvnArg(getUrl()) + '/' + renderSvnPath(null, newBranchForModule)); 711 712 return run(null, svnCommand); 713 } 714 715 718 public String createTagInBranch(ScmVersion existingBranch, ScmVersion newTag) { 719 if (existingBranch == null) { 720 throw new IllegalArgumentException ("existingBranch attribute for createTagInBranch must not be null"); 721 } 722 if (newTag == null) { 723 throw new IllegalArgumentException ("newTag attribute for createTagInBranch must not be null"); 724 } 725 if (existingBranch.getModuleName() == null) { 726 throw new IllegalArgumentException ("moduleName of existing branch for createTagInBranch must not be null"); 727 } 728 729 ArrayList svnCommand = new ArrayList (); 730 svnCommand.add("copy"); 731 addAuthenticationArgs(svnCommand); 732 733 svnCommand.add("-m"); 735 svnCommand.add("Create tag " + newTag + " in branch " + existingBranch); 736 737 svnCommand.add(renderUrlToSvnArg(getUrl()) + '/' + renderSvnPath(null, existingBranch)); 739 740 svnCommand.add(renderUrlToSvnArg(getUrl()) + '/' + renderSvnPath(null, newTag)); 742 743 return run(null, svnCommand); 744 } 745 746 747 750 private static int countVersionChars(char c, String s) { 751 return StringUtils.countMatches(s, String.valueOf(c)); 753 } 754 755 756 762 private String run(File baseDir, ArrayList commandList) { 763 return run(baseDir, commandList, false); 764 } 765 766 private String run(File baseDir, ArrayList commandList, boolean suppressErrorOutput) { 767 return run(baseDir, commandList, suppressErrorOutput, true); 768 } 769 770 private String run(File baseDir, ArrayList commandList, boolean suppressErrorOutput, boolean suppressStandardOutput) { 771 return run(baseDir, commandList, suppressErrorOutput, suppressStandardOutput, false); 772 } 773 774 private String run(File baseDir, ArrayList commandList, boolean suppressErrorOutput, boolean suppressStandardOutput, boolean cleaningUp) { 775 commandList = new ArrayList (commandList); 777 ArrayList orgCommandList = new ArrayList (commandList); 778 779 String cmd = (String )commandList.get(0); 781 if (!cmd.equals("info") && 783 !cmd.equals("list") && 784 !cmd.equals("diff") && 785 !cmd.equals("cleanup") && 786 !cmd.equals("merge") && 787 !cmd.equals("update") && 788 !cmd.equals("checkout") && 789 !commandList.contains("-q") && !commandList.contains("--quiet")) { 790 commandList.add("-q"); 791 } 792 793 commandList.add(0, AntmodProperties.getProperty("antmod.scm.svn.executable")); 795 796 ProcessLauncher launcher = new ProcessLauncher(commandList, baseDir); 798 799 final boolean suppressStd = suppressStandardOutput; 800 final StringBuffer stdOut = new StringBuffer (); 801 final StringBuffer stdErr = new StringBuffer (); 802 stdOut.setLength(0); 803 stdErr.setLength(0); 804 launcher.addOutputListener(new ProcessLauncher.OutputListener() { 805 public void standardOutput(char[] output) { 806 stdOut.append(output); 807 808 if (!suppressStd) { 809 System.err.print(output); 810 } 811 } 812 813 public void errorOutput(char[] output) { 814 stdErr.append(output); 815 } 816 }); 817 818 launcher.launch(); 820 821 if (!cleaningUp && stdErr.length() > 0 && !cmd.equals("cleanup") && stdErr.indexOf("locked") > 0) { 823 System.err.println("Removing lock from \"" + baseDir.getName() + "\" using 'svn cleanup'..."); 824 ArrayList cleanupCommand = new ArrayList (); 825 cleanupCommand.add("cleanup"); 826 run(baseDir, cleanupCommand, false); 827 828 return run(baseDir, orgCommandList, suppressErrorOutput, suppressStandardOutput, true); 830 } 831 832 if (!suppressErrorOutput && stdErr.length() > 0) { 834 System.err.println("'" + launcher.getCommandLine() + "' produced error output:"); 835 System.err.println(stdErr.toString()); 836 } 837 838 this.standardOutput = stdOut.toString(); 840 this.errorOutput = stdErr.toString(); 841 return stdOut.toString(); 842 } 843 844 845 static ScmVersion parseSvnPath(String moduleName, String svnPath) { 846 String moduleNameSearch = '/' + moduleName + '/'; 848 int moduleNameIndex = svnPath.lastIndexOf(moduleNameSearch); 849 if (moduleNameIndex < 0) { 850 throw new IllegalArgumentException ("Subversion URL \"" + svnPath + "\" does not contain modulename \"" + moduleName + "\""); 851 } 852 853 String versionString = svnPath.substring(moduleNameIndex + moduleNameSearch.length()); 855 if (!versionString.startsWith("trunk")) { 856 int nextSlash = versionString.indexOf("/"); 857 if (nextSlash < 0) { 858 throw new IllegalArgumentException ("Subversion URL \"" + svnPath + "\" does not have version in URL after tags/branches part."); 859 } 860 versionString = versionString.substring(nextSlash + 1); 861 } 862 return new ScmVersion(moduleName, versionString); 863 } 864 865 static String renderSvnPath(String moduleName, ScmVersion ver) { 866 if (StringUtils.isBlank(moduleName) && StringUtils.isBlank(ver.getModuleName())) { 867 throw new RuntimeException ("Modulename unknown - proper Subversion repository path not possible."); 868 } 869 if (moduleName == null) { 870 moduleName = ver.getModuleName(); 871 } 872 873 if (ver == null) { 874 return moduleName + "/trunk"; 875 } 876 877 if (ver.isTag()) { 878 return moduleName + "/tags/" + ver.toString(REVISION_VERSION_SEPARATOR); 879 } else if (ver.isBranch()) { 880 return moduleName + "/branches/" + ver.toString(REVISION_VERSION_SEPARATOR); 881 } else { 882 return moduleName + "/trunk"; 883 } 884 } 885 886 static String renderUrlToSvnArg(ScmUrl url) { 887 StringBuffer result = new StringBuffer (); 888 result.append(url.getProtocol()); 889 result.append("://"); 890 if (url.getProtocol().equals("file")) { 891 result.append('/'); 892 } else { 893 result.append(url.getHost()); 894 } 895 result.append(url.getPath()); 896 return result.toString(); 897 } 898 899 public boolean isCheckoutDir(File directory) { 900 return new File (directory, ".svn").exists(); 901 } 902 } 903 | Popular Tags |