diff options
| -rw-r--r-- | project.py | 16 | ||||
| -rw-r--r-- | subcmds/status.py | 64 |
2 files changed, 70 insertions, 10 deletions
| @@ -650,13 +650,18 @@ class Project(object): | |||
| 650 | 650 | ||
| 651 | return False | 651 | return False |
| 652 | 652 | ||
| 653 | def PrintWorkTreeStatus(self): | 653 | def PrintWorkTreeStatus(self, output_redir=None): |
| 654 | """Prints the status of the repository to stdout. | 654 | """Prints the status of the repository to stdout. |
| 655 | |||
| 656 | Args: | ||
| 657 | output: If specified, redirect the output to this object. | ||
| 655 | """ | 658 | """ |
| 656 | if not os.path.isdir(self.worktree): | 659 | if not os.path.isdir(self.worktree): |
| 657 | print '' | 660 | if output_redir == None: |
| 658 | print 'project %s/' % self.relpath | 661 | output_redir = sys.stdout |
| 659 | print ' missing (run "repo sync")' | 662 | print >>output_redir, '' |
| 663 | print >>output_redir, 'project %s/' % self.relpath | ||
| 664 | print >>output_redir, ' missing (run "repo sync")' | ||
| 660 | return | 665 | return |
| 661 | 666 | ||
| 662 | self.work_git.update_index('-q', | 667 | self.work_git.update_index('-q', |
| @@ -671,6 +676,8 @@ class Project(object): | |||
| 671 | return 'CLEAN' | 676 | return 'CLEAN' |
| 672 | 677 | ||
| 673 | out = StatusColoring(self.config) | 678 | out = StatusColoring(self.config) |
| 679 | if not output_redir == None: | ||
| 680 | out.redirect(output_redir) | ||
| 674 | out.project('project %-40s', self.relpath + '/') | 681 | out.project('project %-40s', self.relpath + '/') |
| 675 | 682 | ||
| 676 | branch = self.CurrentBranch | 683 | branch = self.CurrentBranch |
| @@ -720,6 +727,7 @@ class Project(object): | |||
| 720 | else: | 727 | else: |
| 721 | out.write('%s', line) | 728 | out.write('%s', line) |
| 722 | out.nl() | 729 | out.nl() |
| 730 | |||
| 723 | return 'DIRTY' | 731 | return 'DIRTY' |
| 724 | 732 | ||
| 725 | def PrintWorkTreeDiff(self): | 733 | def PrintWorkTreeDiff(self): |
diff --git a/subcmds/status.py b/subcmds/status.py index b0d419a7..041bcd0f 100644 --- a/subcmds/status.py +++ b/subcmds/status.py | |||
| @@ -15,6 +15,15 @@ | |||
| 15 | 15 | ||
| 16 | from command import PagedCommand | 16 | from command import PagedCommand |
| 17 | 17 | ||
| 18 | try: | ||
| 19 | import threading as _threading | ||
| 20 | except ImportError: | ||
| 21 | import dummy_threading as _threading | ||
| 22 | |||
| 23 | import itertools | ||
| 24 | import sys | ||
| 25 | import StringIO | ||
| 26 | |||
| 18 | class Status(PagedCommand): | 27 | class Status(PagedCommand): |
| 19 | common = True | 28 | common = True |
| 20 | helpSummary = "Show the working tree status" | 29 | helpSummary = "Show the working tree status" |
| @@ -27,6 +36,9 @@ and the most recent commit on this branch (HEAD), in each project | |||
| 27 | specified. A summary is displayed, one line per file where there | 36 | specified. A summary is displayed, one line per file where there |
| 28 | is a difference between these three states. | 37 | is a difference between these three states. |
| 29 | 38 | ||
| 39 | The -j/--jobs option can be used to run multiple status queries | ||
| 40 | in parallel. | ||
| 41 | |||
| 30 | Status Display | 42 | Status Display |
| 31 | -------------- | 43 | -------------- |
| 32 | 44 | ||
| @@ -60,9 +72,34 @@ the following meanings: | |||
| 60 | 72 | ||
| 61 | """ | 73 | """ |
| 62 | 74 | ||
| 75 | def _Options(self, p): | ||
| 76 | p.add_option('-j', '--jobs', | ||
| 77 | dest='jobs', action='store', type='int', default=2, | ||
| 78 | help="number of projects to check simultaneously") | ||
| 79 | |||
| 80 | def _StatusHelper(self, project, clean_counter, sem, output): | ||
| 81 | """Obtains the status for a specific project. | ||
| 82 | |||
| 83 | Obtains the status for a project, redirecting the output to | ||
| 84 | the specified object. It will release the semaphore | ||
| 85 | when done. | ||
| 86 | |||
| 87 | Args: | ||
| 88 | project: Project to get status of. | ||
| 89 | clean_counter: Counter for clean projects. | ||
| 90 | sem: Semaphore, will call release() when complete. | ||
| 91 | output: Where to output the status. | ||
| 92 | """ | ||
| 93 | try: | ||
| 94 | state = project.PrintWorkTreeStatus(output) | ||
| 95 | if state == 'CLEAN': | ||
| 96 | clean_counter.next() | ||
| 97 | finally: | ||
| 98 | sem.release() | ||
| 99 | |||
| 63 | def Execute(self, opt, args): | 100 | def Execute(self, opt, args): |
| 64 | all = self.GetProjects(args) | 101 | all = self.GetProjects(args) |
| 65 | clean = 0 | 102 | counter = itertools.count() |
| 66 | 103 | ||
| 67 | on = {} | 104 | on = {} |
| 68 | for project in all: | 105 | for project in all: |
| @@ -77,9 +114,24 @@ the following meanings: | |||
| 77 | for cb in branch_names: | 114 | for cb in branch_names: |
| 78 | print '# on branch %s' % cb | 115 | print '# on branch %s' % cb |
| 79 | 116 | ||
| 80 | for project in all: | 117 | if opt.jobs == 1: |
| 81 | state = project.PrintWorkTreeStatus() | 118 | for project in all: |
| 82 | if state == 'CLEAN': | 119 | state = project.PrintWorkTreeStatus() |
| 83 | clean += 1 | 120 | if state == 'CLEAN': |
| 84 | if len(all) == clean: | 121 | counter.next() |
| 122 | else: | ||
| 123 | sem = _threading.Semaphore(opt.jobs) | ||
| 124 | threads_and_output = [] | ||
| 125 | for project in all: | ||
| 126 | sem.acquire() | ||
| 127 | output = StringIO.StringIO() | ||
| 128 | t = _threading.Thread(target=self._StatusHelper, | ||
| 129 | args=(project, counter, sem, output)) | ||
| 130 | threads_and_output.append((t, output)) | ||
| 131 | t.start() | ||
| 132 | for (t, output) in threads_and_output: | ||
| 133 | t.join() | ||
| 134 | sys.stdout.write(output.getvalue()) | ||
| 135 | output.close() | ||
| 136 | if len(all) == counter.next(): | ||
| 85 | print 'nothing to commit (working directory clean)' | 137 | print 'nothing to commit (working directory clean)' |
