|
9 | 9 | import java.util.Collection; |
10 | 10 | import java.util.Collections; |
11 | 11 | import java.util.HashSet; |
| 12 | +import java.util.Iterator; |
12 | 13 | import java.util.List; |
13 | 14 | import java.util.Set; |
14 | 15 |
|
|
18 | 19 | import org.scm4j.vcs.api.VCSCommit; |
19 | 20 | import org.scm4j.vcs.api.VCSDiffEntry; |
20 | 21 | import org.scm4j.vcs.api.VCSMergeResult; |
| 22 | +import org.scm4j.vcs.api.VCSTag; |
21 | 23 | import org.scm4j.vcs.api.WalkDirection; |
22 | 24 | import org.scm4j.vcs.api.exceptions.EVCSBranchExists; |
23 | 25 | import org.scm4j.vcs.api.exceptions.EVCSException; |
24 | 26 | import org.scm4j.vcs.api.exceptions.EVCSFileNotFound; |
| 27 | +import org.scm4j.vcs.api.exceptions.EVCSTagExists; |
25 | 28 | import org.scm4j.vcs.api.workingcopy.IVCSLockedWorkingCopy; |
26 | 29 | import org.scm4j.vcs.api.workingcopy.IVCSRepositoryWorkspace; |
27 | 30 | import org.scm4j.vcs.api.workingcopy.IVCSWorkspace; |
|
31 | 34 | import org.tmatesoft.svn.core.SVNDirEntry; |
32 | 35 | import org.tmatesoft.svn.core.SVNException; |
33 | 36 | import org.tmatesoft.svn.core.SVNLogEntry; |
| 37 | +import org.tmatesoft.svn.core.SVNLogEntryPath; |
34 | 38 | import org.tmatesoft.svn.core.SVNNodeKind; |
35 | 39 | import org.tmatesoft.svn.core.SVNProperties; |
36 | 40 | import org.tmatesoft.svn.core.SVNURL; |
|
49 | 53 | import org.tmatesoft.svn.core.wc.SVNCopyClient; |
50 | 54 | import org.tmatesoft.svn.core.wc.SVNCopySource; |
51 | 55 | import org.tmatesoft.svn.core.wc.SVNDiffClient; |
| 56 | +import org.tmatesoft.svn.core.wc.SVNInfo; |
52 | 57 | import org.tmatesoft.svn.core.wc.SVNRevision; |
53 | 58 | import org.tmatesoft.svn.core.wc.SVNRevisionRange; |
54 | 59 | import org.tmatesoft.svn.core.wc.SVNStatusType; |
@@ -77,6 +82,7 @@ public class SVNVCS implements IVCS { |
77 | 82 |
|
78 | 83 | public static final String MASTER_PATH= "trunk/"; |
79 | 84 | public static final String BRANCHES_PATH = "branches/"; |
| 85 | + public static final String TAGS_PATH = "tags/"; |
80 | 86 | private static final String SVN_VCS_TYPE_STRING = "svn"; |
81 | 87 |
|
82 | 88 | public SVNClientManager getClientManager() { |
@@ -609,4 +615,70 @@ public Boolean fileExists(String branchName, String filePath) { |
609 | 615 | throw new RuntimeException(e); |
610 | 616 | } |
611 | 617 | } |
| 618 | + |
| 619 | + @Override |
| 620 | + public VCSTag createTag(String branchName, String tagName, String tagMessage) throws EVCSTagExists { |
| 621 | + try { |
| 622 | + SVNURL srcURL = getBranchUrl(branchName); |
| 623 | + SVNURL dstURL = SVNURL.parseURIEncoded(repoUrl + TAGS_PATH + tagName); |
| 624 | + SVNCopySource copySource = |
| 625 | + new SVNCopySource(SVNRevision.HEAD, SVNRevision.HEAD, srcURL); |
| 626 | + |
| 627 | + clientManager.getCopyClient().doCopy(new SVNCopySource[] {copySource}, dstURL, |
| 628 | + false, false, true, tagMessage, null); |
| 629 | + |
| 630 | + SVNDirEntry entry = repository.info(TAGS_PATH + tagName, -1); |
| 631 | + |
| 632 | + VCSTag tag = new VCSTag(tagName, tagMessage, entry.getAuthor(), getHeadCommit(branchName)); |
| 633 | + return tag; |
| 634 | + } catch (SVNException e) { |
| 635 | + if (e.getErrorMessage().getErrorCode().getCode() == SVN_ITEM_EXISTS_ERROR_CODE) { |
| 636 | + throw new EVCSTagExists(e); |
| 637 | + } |
| 638 | + throw new EVCSException(e); |
| 639 | + } catch (Exception e) { |
| 640 | + throw new RuntimeException(e); |
| 641 | + } |
| 642 | + } |
| 643 | + |
| 644 | + @Override |
| 645 | + public List<VCSTag> getTags() { |
| 646 | + Set<String> entries = new HashSet<>(); |
| 647 | + try { |
| 648 | + listEntries(entries, TAGS_PATH); |
| 649 | + List<VCSTag> res = new ArrayList<>(); |
| 650 | + for (String entryStr : entries) { |
| 651 | + SVNDirEntry entry = repository.info(entryStr, -1); |
| 652 | + SVNInfo info = clientManager.getWCClient().doInfo(SVNURL.parseURIEncoded(repoUrl + entryStr), SVNRevision.HEAD, SVNRevision.HEAD); |
| 653 | + |
| 654 | + info.getCommittedRevision(); // tag revision number |
| 655 | + |
| 656 | + class SVNTagBaseCommit implements ISVNLogEntryHandler { |
| 657 | + |
| 658 | + public Long copyFromRevision; |
| 659 | + |
| 660 | + @Override |
| 661 | + public void handleLogEntry(SVNLogEntry logEntry) throws SVNException { |
| 662 | + for (Iterator<?> changedPaths = logEntry.getChangedPaths().keySet().iterator(); changedPaths.hasNext();) { |
| 663 | + SVNLogEntryPath entryPath = (SVNLogEntryPath) logEntry.getChangedPaths().get(changedPaths.next()); |
| 664 | + copyFromRevision = entryPath.getCopyRevision(); |
| 665 | + } |
| 666 | + } |
| 667 | + } |
| 668 | + |
| 669 | + SVNTagBaseCommit handler = new SVNTagBaseCommit(); |
| 670 | + |
| 671 | + repository.log(new String[] { entryStr }, -1 /* start from head descending */, |
| 672 | + 0, true, true, -1, handler); |
| 673 | + |
| 674 | + SVNDirEntry copyFromEntry = repository.info("", handler.copyFromRevision); |
| 675 | + |
| 676 | + res.add(new VCSTag(entry.getName(), entry.getCommitMessage(), entry.getAuthor(), new VCSCommit(Long.toString(copyFromEntry.getRevision()), |
| 677 | + copyFromEntry.getCommitMessage(), copyFromEntry.getAuthor()))); |
| 678 | + } |
| 679 | + return res; |
| 680 | + } catch (SVNException e) { |
| 681 | + throw new EVCSException(e); |
| 682 | + } |
| 683 | + } |
612 | 684 | } |
0 commit comments