Index: host/willis |
diff --git a/host/willis b/host/willis |
new file mode 100755 |
index 0000000000000000000000000000000000000000..bbdace0c95ae88a7020061e939cd72a800812dd0 |
--- /dev/null |
+++ b/host/willis |
@@ -0,0 +1,109 @@ |
+#!/usr/bin/env python |
+# Copyright (c) 2011 The Chromium Authors. All rights reserved. |
+# Use of this source code is governed by a BSD-style license that can be |
+# found in the LICENSE file. |
+ |
+"""Display active git branches and code changes in a ChromiumOS workspace.""" |
+ |
+import os |
+import re |
+import subprocess |
+ |
+def RunCommand(path, command): |
+ """Run a command in a given directory, return stdout.""" |
+ |
+ return subprocess.Popen(command, |
+ cwd=path, |
+ stdout=subprocess.PIPE).communicate()[0].rstrip() |
+ |
+# |
+# Taken with slight modification from gclient_utils.py in the depot_tools |
+# project. |
+# |
+def FindFileUpwards(filename, path): |
+ """Search upwards from the a directory to find a file.""" |
+ |
+ path = os.path.realpath(path) |
+ while True: |
+ file_path = os.path.join(path, filename) |
+ if os.path.exists(file_path): |
+ return file_path |
+ (new_path, _) = os.path.split(path) |
+ if new_path == path: |
+ return None |
+ path = new_path |
+ |
+ |
+def ShowName(relative_name, color): |
+ """Display the directory name.""" |
+ |
+ if color: |
+ print('\033[44m\033[37m%s\033[0m' % (relative_name)) |
Kenneth Waters
2011/02/01 20:55:01
print '\033[44m\033[37m%s\033[0m' % relative_name
|
+ else: |
+ print('%s' % relative_name) |
Kenneth Waters
2011/02/01 20:55:01
print relative_name
|
+ |
+ |
+def ShowDir(full_name, relative_name, color): |
+ """Display active work in a single git repo.""" |
+ |
+ lines_printed = 0 |
+ command = ['git', 'branch', '-vv'] |
+ |
+ if color: |
+ command.append('--color') |
+ |
+ branch = RunCommand(full_name, command) |
+ lines = branch.splitlines() |
+ |
+ if (len(lines) > 1 or |
+ (len(lines) == 1 and not re.search(r"\(no branch\)", lines[0]))) : |
Kenneth Waters
2011/02/01 20:55:01
No space before colon.
robotboy
2011/02/01 21:21:52
Done.
|
+ if lines_printed == 0: |
+ ShowName(relative_name, color) |
+ lines_printed += 1 |
+ print branch |
+ |
+ status = RunCommand(full_name, ['git', 'status', '-s']) |
+ |
+ if status.splitlines(): |
+ if lines_printed == 0: |
+ ShowName(relative_name, color) |
+ if lines_printed == 1: |
+ print '---------------' |
+ lines_printed += 1 |
+ print status |
+ |
+ if lines_printed > 0: |
+ print "" |
+ |
+ |
+def FindRoot(): |
+ """Returns the repo root.""" |
+ |
+ repo_file = '.repo' |
+ repo_path = FindFileUpwards(repo_file, os.getcwd()) |
+ |
+ if repo_path is None: |
+ raise Exception('Failed to find %s.' % repo_file) |
+ |
+ return os.path.dirname(repo_path) |
+ |
+ |
+def main(): |
+ """Take no arguments.""" |
+ |
+ color = os.isatty(1) |
+ base = os.path.basename(os.getcwd()) |
+ root = FindRoot() |
+ repos = RunCommand(root, ['repo', 'forall', '-c', 'pwd']).splitlines() |
+ |
+ # We want to use the full path for testing, but we want to use the relative |
+ # path for display. |
+ fulldirs = [os.path.normpath(os.path.join(root, p)) for p in repos] |
+ reldirs = [re.sub('^' + re.escape(base), '.', p) for p in repos] |
+ |
+ for full_path, relative_path in zip(fulldirs, reldirs): |
+ ShowDir(full_path, relative_path, color) |
+ |
+ |
+if __name__ == '__main__': |
+ main() |