diff options
-rw-r--r-- | project.py | 4 | ||||
-rw-r--r-- | subcmds/diff.py | 42 |
2 files changed, 41 insertions, 5 deletions
@@ -832,10 +832,12 @@ class Project(object): | |||
832 | 832 | ||
833 | return 'DIRTY' | 833 | return 'DIRTY' |
834 | 834 | ||
835 | def PrintWorkTreeDiff(self, absolute_paths=False): | 835 | def PrintWorkTreeDiff(self, absolute_paths=False, output_redir=None): |
836 | """Prints the status of the repository to stdout. | 836 | """Prints the status of the repository to stdout. |
837 | """ | 837 | """ |
838 | out = DiffColoring(self.config) | 838 | out = DiffColoring(self.config) |
839 | if output_redir: | ||
840 | out.redirect(output_redir) | ||
839 | cmd = ['diff'] | 841 | cmd = ['diff'] |
840 | if out.is_on: | 842 | if out.is_on: |
841 | cmd.append('--color') | 843 | cmd.append('--color') |
diff --git a/subcmds/diff.py b/subcmds/diff.py index c987bf23..81868176 100644 --- a/subcmds/diff.py +++ b/subcmds/diff.py | |||
@@ -12,7 +12,11 @@ | |||
12 | # See the License for the specific language governing permissions and | 12 | # See the License for the specific language governing permissions and |
13 | # limitations under the License. | 13 | # limitations under the License. |
14 | 14 | ||
15 | from command import PagedCommand | 15 | import functools |
16 | import io | ||
17 | import multiprocessing | ||
18 | |||
19 | from command import DEFAULT_LOCAL_JOBS, PagedCommand, WORKER_BATCH_SIZE | ||
16 | 20 | ||
17 | 21 | ||
18 | class Diff(PagedCommand): | 22 | class Diff(PagedCommand): |
@@ -25,15 +29,45 @@ The -u option causes '%prog' to generate diff output with file paths | |||
25 | relative to the repository root, so the output can be applied | 29 | relative to the repository root, so the output can be applied |
26 | to the Unix 'patch' command. | 30 | to the Unix 'patch' command. |
27 | """ | 31 | """ |
32 | PARALLEL_JOBS = DEFAULT_LOCAL_JOBS | ||
28 | 33 | ||
29 | def _Options(self, p): | 34 | def _Options(self, p): |
35 | super()._Options(p) | ||
30 | p.add_option('-u', '--absolute', | 36 | p.add_option('-u', '--absolute', |
31 | dest='absolute', action='store_true', | 37 | dest='absolute', action='store_true', |
32 | help='Paths are relative to the repository root') | 38 | help='Paths are relative to the repository root') |
33 | 39 | ||
40 | def _DiffHelper(self, absolute, project): | ||
41 | """Obtains the diff for a specific project. | ||
42 | |||
43 | Args: | ||
44 | absolute: Paths are relative to the root. | ||
45 | project: Project to get status of. | ||
46 | |||
47 | Returns: | ||
48 | The status of the project. | ||
49 | """ | ||
50 | buf = io.StringIO() | ||
51 | ret = project.PrintWorkTreeDiff(absolute, output_redir=buf) | ||
52 | return (ret, buf.getvalue()) | ||
53 | |||
34 | def Execute(self, opt, args): | 54 | def Execute(self, opt, args): |
35 | ret = 0 | 55 | ret = 0 |
36 | for project in self.GetProjects(args): | 56 | all_projects = self.GetProjects(args) |
37 | if not project.PrintWorkTreeDiff(opt.absolute): | 57 | |
38 | ret = 1 | 58 | # NB: Multiprocessing is heavy, so don't spin it up for one job. |
59 | if len(all_projects) == 1 or opt.jobs == 1: | ||
60 | for project in all_projects: | ||
61 | if not project.PrintWorkTreeDiff(opt.absolute): | ||
62 | ret = 1 | ||
63 | else: | ||
64 | with multiprocessing.Pool(opt.jobs) as pool: | ||
65 | states = pool.imap(functools.partial(self._DiffHelper, opt.absolute), | ||
66 | all_projects, WORKER_BATCH_SIZE) | ||
67 | for (state, output) in states: | ||
68 | if output: | ||
69 | print(output, end='') | ||
70 | if not state: | ||
71 | ret = 1 | ||
72 | |||
39 | return ret | 73 | return ret |