|
39 | 39 | import java.util.HashMap;
|
40 | 40 | import java.util.Map;
|
41 | 41 | import java.util.TreeSet;
|
| 42 | +import java.util.concurrent.ExecutionException; |
| 43 | +import java.util.concurrent.ExecutorService; |
| 44 | +import java.util.concurrent.Executors; |
| 45 | +import java.util.concurrent.Future; |
| 46 | +import java.util.concurrent.TimeUnit; |
| 47 | +import java.util.concurrent.TimeoutException; |
42 | 48 | import java.util.logging.Level;
|
43 | 49 | import java.util.logging.Logger;
|
44 | 50 | import java.util.regex.Matcher;
|
@@ -589,6 +595,44 @@ boolean hasFileBasedTags() {
|
589 | 595 | return true;
|
590 | 596 | }
|
591 | 597 |
|
| 598 | + private void rebuildTagList(File directory) { |
| 599 | + this.tagList = new TreeSet<>(); |
| 600 | + try (org.eclipse.jgit.lib.Repository repository = FileRepositoryBuilder. |
| 601 | + create(Paths.get(directory.getAbsolutePath(), ".git").toFile())) { |
| 602 | + try (Git git = new Git(repository)) { |
| 603 | + List<Ref> refList = git.tagList().call(); // refs sorted according to tag names |
| 604 | + Map<RevCommit, String> commit2Tags = new HashMap<>(); |
| 605 | + for (Ref ref : refList) { |
| 606 | + String tagName = ref.getName().replace("refs/tags/", ""); |
| 607 | + String existingTags; |
| 608 | + RevCommit commit = getCommit(repository, ref); |
| 609 | + if ((existingTags = commit2Tags.get(commit)) != null) { |
| 610 | + existingTags = existingTags + TAGS_SEPARATOR + tagName; |
| 611 | + commit2Tags.put(commit, existingTags); |
| 612 | + } else { |
| 613 | + commit2Tags.put(commit, tagName); |
| 614 | + } |
| 615 | + } |
| 616 | + |
| 617 | + for (Map.Entry<RevCommit, String> entry : commit2Tags.entrySet()) { |
| 618 | + int commitTime = entry.getKey().getCommitTime(); |
| 619 | + Date date = new Date((long) (commitTime) * 1000); |
| 620 | + GitTagEntry tagEntry = new GitTagEntry(entry.getKey().getName(), |
| 621 | + date, entry.getValue()); |
| 622 | + this.tagList.add(tagEntry); |
| 623 | + } |
| 624 | + } |
| 625 | + } catch (IOException | GitAPIException e) { |
| 626 | + LOGGER.log(Level.WARNING, "cannot get tags for \"" + directory.getAbsolutePath() + "\"", e); |
| 627 | + // In case of partial success, do not null-out tagList here. |
| 628 | + } |
| 629 | + |
| 630 | + if (LOGGER.isLoggable(Level.FINEST)) { |
| 631 | + LOGGER.log(Level.FINEST, "Read tags count={0} for {1}", |
| 632 | + new Object[] {tagList.size(), directory}); |
| 633 | + } |
| 634 | + } |
| 635 | + |
592 | 636 | /**
|
593 | 637 | * Builds a Git tag list by querying Git commit hash, commit time, and tag
|
594 | 638 | * names.
|
@@ -622,42 +666,22 @@ boolean hasFileBasedTags() {
|
622 | 666 | */
|
623 | 667 | @Override
|
624 | 668 | protected void buildTagList(File directory, CommandTimeoutType cmdType) {
|
625 |
| - this.tagList = new TreeSet<>(); |
626 |
| - |
627 |
| - // TODO: add timeout |
628 |
| - try (org.eclipse.jgit.lib.Repository repository = FileRepositoryBuilder. |
629 |
| - create(Paths.get(directory.getAbsolutePath(), ".git").toFile())) { |
630 |
| - try (Git git = new Git(repository)) { |
631 |
| - List<Ref> refList = git.tagList().call(); // refs sorted according to tag names |
632 |
| - Map<RevCommit, String> commit2Tags = new HashMap<>(); |
633 |
| - for (Ref ref : refList) { |
634 |
| - String tagName = ref.getName().replace("refs/tags/", ""); |
635 |
| - String existingTags; |
636 |
| - RevCommit commit = getCommit(repository, ref); |
637 |
| - if ((existingTags = commit2Tags.get(commit)) != null) { |
638 |
| - existingTags = existingTags + TAGS_SEPARATOR + tagName; |
639 |
| - commit2Tags.put(commit, existingTags); |
640 |
| - } else { |
641 |
| - commit2Tags.put(commit, tagName); |
642 |
| - } |
643 |
| - } |
| 669 | + final ExecutorService executor = Executors.newSingleThreadExecutor(); |
| 670 | + final Future<?> future = executor.submit(() -> rebuildTagList(directory)); |
| 671 | + executor.shutdown(); |
644 | 672 |
|
645 |
| - for (Map.Entry<RevCommit, String> entry : commit2Tags.entrySet()) { |
646 |
| - int commitTime = entry.getKey().getCommitTime(); |
647 |
| - Date date = new Date((long) (commitTime) * 1000); |
648 |
| - GitTagEntry tagEntry = new GitTagEntry(entry.getKey().getName(), |
649 |
| - date, entry.getValue()); |
650 |
| - this.tagList.add(tagEntry); |
651 |
| - } |
652 |
| - } |
653 |
| - } catch (IOException | GitAPIException e) { |
654 |
| - LOGGER.log(Level.WARNING, "cannot get tags for \"" + directory.getAbsolutePath() + "\"", e); |
655 |
| - // In case of partial success, do not null-out tagList here. |
| 673 | + try { |
| 674 | + future.get(RuntimeEnvironment.getInstance().getCommandTimeout(cmdType), TimeUnit.SECONDS); |
| 675 | + } |
| 676 | + catch (InterruptedException | ExecutionException e) { |
| 677 | + LOGGER.log(Level.WARNING, "failed tag rebuild for directory " + directory, e); |
| 678 | + } |
| 679 | + catch (TimeoutException e) { |
| 680 | + LOGGER.log(Level.WARNING, "timed out tag rebuild for directory " + directory, e); |
656 | 681 | }
|
657 | 682 |
|
658 |
| - if (LOGGER.isLoggable(Level.FINEST)) { |
659 |
| - LOGGER.log(Level.FINEST, "Read tags count={0} for {1}", |
660 |
| - new Object[] {tagList.size(), directory}); |
| 683 | + if (!executor.isTerminated()) { |
| 684 | + executor.shutdownNow(); |
661 | 685 | }
|
662 | 686 | }
|
663 | 687 |
|
|
0 commit comments