OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """Display active git branches and code changes in a ChromiumOS workspace.""" | 6 """Display active git branches and code changes in a ChromiumOS workspace.""" |
7 | 7 |
| 8 import optparse |
8 import os | 9 import os |
9 import re | 10 import re |
10 import subprocess | 11 import subprocess |
11 | 12 |
12 def RunCommand(path, command): | 13 def RunCommand(path, command): |
13 """Run a command in a given directory, return stdout.""" | 14 """Run a command in a given directory, return stdout.""" |
14 | 15 |
15 return subprocess.Popen(command, | 16 return subprocess.Popen(command, |
16 cwd=path, | 17 cwd=path, |
17 stdout=subprocess.PIPE).communicate()[0].rstrip() | 18 stdout=subprocess.PIPE).communicate()[0].rstrip() |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 return branches | 60 return branches |
60 | 61 |
61 def GetStatus(full_name, relative_name, color): | 62 def GetStatus(full_name, relative_name, color): |
62 """Return a list of files that have modifications.""" | 63 """Return a list of files that have modifications.""" |
63 | 64 |
64 command = ['git', 'status', '-s'] | 65 command = ['git', 'status', '-s'] |
65 | 66 |
66 return RunCommand(full_name, command).splitlines() | 67 return RunCommand(full_name, command).splitlines() |
67 | 68 |
68 | 69 |
69 def ShowDir(full_name, relative_name, color): | 70 def GetHistory(full_name, relative_name, color, author, days): |
| 71 """Return a list of oneline log messages. |
| 72 |
| 73 The messages are for the author going back a specified number of days. |
| 74 """ |
| 75 |
| 76 command = ['git', 'log', |
| 77 '--author=' + author, |
| 78 '--after=' + '-' + str(days) + 'days', |
| 79 '--pretty=oneline', |
| 80 'm/master'] |
| 81 |
| 82 return RunCommand(full_name, command).splitlines() |
| 83 |
| 84 |
| 85 def ShowDir(full_name, relative_name, color, logs, author, days): |
70 """Display active work in a single git repository.""" | 86 """Display active work in a single git repository.""" |
71 | 87 |
72 branches = GetBranches(full_name, relative_name, color) | 88 branches = GetBranches(full_name, relative_name, color) |
73 status = GetStatus(full_name, relative_name, color) | 89 status = GetStatus(full_name, relative_name, color) |
74 | 90 |
75 if branches or status: | 91 if logs: |
| 92 history = GetHistory(full_name, relative_name, color, author, days) |
| 93 else: |
| 94 history = [] |
| 95 |
| 96 if branches or status or history: |
76 ShowName(relative_name, color) | 97 ShowName(relative_name, color) |
77 | 98 |
78 if branches: print '\n'.join(branches) | 99 if branches: print '\n'.join(branches) |
79 if status: print '\n'.join(status) | 100 if status: print '\n'.join(status) |
| 101 if history: print '\n'.join(history) |
80 | 102 |
81 if branches or status: | 103 if branches or status or history: |
82 print "" | 104 print "" |
83 | 105 |
84 | 106 |
85 def FindRoot(): | 107 def FindRoot(): |
86 """Returns the repo root.""" | 108 """Returns the repo root.""" |
87 | 109 |
88 repo_file = '.repo' | 110 repo_file = '.repo' |
89 repo_path = FindFileUpwards(repo_file, os.getcwd()) | 111 repo_path = FindFileUpwards(repo_file, os.getcwd()) |
90 | 112 |
91 if repo_path is None: | 113 if repo_path is None: |
92 raise Exception('Failed to find %s.' % repo_file) | 114 raise Exception('Failed to find %s.' % repo_file) |
93 | 115 |
94 return os.path.dirname(repo_path) | 116 return os.path.dirname(repo_path) |
95 | 117 |
96 | 118 |
97 def main(): | 119 def main(): |
98 """Take no arguments.""" | 120 parser = optparse.OptionParser(usage = 'usage: %prog [options]\n') |
| 121 |
| 122 parser.add_option('-l', '--logs', default=False, |
| 123 help='Show the last few days of your commits in short ' |
| 124 'form.', |
| 125 action='store_true', |
| 126 dest='logs') |
| 127 |
| 128 parser.add_option('-d', '--days', default=8, |
| 129 help='Set the number of days of history to show.', |
| 130 type='int', |
| 131 dest='days') |
| 132 |
| 133 parser.add_option('-a', '--author', default=os.environ['USER'], |
| 134 help='Set the author to filter for.', |
| 135 type='string', |
| 136 dest='author') |
| 137 |
| 138 options, arguments = parser.parse_args() |
| 139 |
| 140 if arguments: |
| 141 parser.print_usage() |
| 142 return 1 |
99 | 143 |
100 color = os.isatty(1) | 144 color = os.isatty(1) |
101 root = FindRoot() | 145 root = FindRoot() |
102 repos = RunCommand(root, ['repo', 'forall', '-c', 'pwd']).splitlines() | 146 repos = RunCommand(root, ['repo', 'forall', '-c', 'pwd']).splitlines() |
103 | 147 |
104 # We want to use the full path for testing, but we want to use the relative | 148 # We want to use the full path for testing, but we want to use the relative |
105 # path for display. | 149 # path for display. |
106 reldirs = [re.sub('^' + re.escape(root) + '/', '', p) for p in repos] | 150 reldirs = [re.sub('^' + re.escape(root) + '/', '', p) for p in repos] |
107 | 151 |
108 for full, relative in zip(repos, reldirs): | 152 for full, relative in zip(repos, reldirs): |
109 ShowDir(full, relative, color) | 153 ShowDir(full, relative, color, options.logs, options.author, options.days) |
110 | 154 |
111 | 155 |
112 if __name__ == '__main__': | 156 if __name__ == '__main__': |
113 main() | 157 main() |
OLD | NEW |