Index: watchlists.py |
=================================================================== |
--- watchlists.py (revision 0) |
+++ watchlists.py (revision 0) |
@@ -0,0 +1,117 @@ |
+#!/usr/bin/python |
+# Copyright (c) 2009 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. |
+ |
+"""Watchlists |
+ |
+Watchlists is a mechanism that allow a developer (a "watcher") to watch over |
+portions of code that he is interested in. A "watcher" will be cc-ed to |
+changes that modify that portion of code, thereby giving him an opportunity |
+to make comments on codereview.chromium.org even before the change is |
+committed. |
+Refer: http://dev.chromium.org/developers/contributing-code/watchlists |
+ |
+When invoked directly from the base of a repository, this script lists out |
+the watchers for files given on the command line. This is useful to verify |
+changes to WATCHLISTS files. |
+""" |
+ |
+import logging |
+import os |
+import re |
+import sys |
+ |
+ |
+class Watchlists(object): |
+ """Manage Watchlists. |
+ |
+ This class provides mechanism to load watchlists for a repo and identify |
+ watchers. |
+ Usage: |
+ wl = Watchlists("/path/to/repo/root") |
+ watchers = wl.GetWatchersForPaths(["/path/to/file1", |
+ "/path/to/file2",]) |
+ """ |
+ |
+ _RULES = "WATCHLISTS" |
+ _RULES_FILENAME = _RULES |
+ _repo_root = None |
+ _defns = {} # Definitions |
+ _watchlists = {} # name to email mapping |
+ |
+ def __init__(self, repo_root): |
+ self._repo_root = repo_root |
+ self._LoadWatchlistRules() |
+ |
+ def _GetRulesFilePath(self): |
+ return os.path.join(self._repo_root, self._RULES_FILENAME) |
+ |
+ def _HasWatchlistsFile(self): |
+ """Determine if watchlists are available for this repo.""" |
+ return os.path.exists(self._GetRulesFilePath()) |
+ |
+ def _LoadWatchlistRules(self): |
+ if not self._HasWatchlistsFile(): |
+ return |
+ watchlists_file = open(self._GetRulesFilePath()) |
+ contents = watchlists_file.read() |
+ watchlists_file.close() |
+ |
+ watchlists_data = None |
+ try: |
+ watchlists_data = eval(contents, {'__builtins__': None}, None) |
+ except SyntaxError, e: |
+ logging.error("Cannot parse %s. %s" % (self._GetRulesFilePath(), e)) |
+ return |
+ |
+ defns = watchlists_data.get("WATCHLIST_DEFINITIONS") |
+ if not defns: |
+ logging.error("WATCHLIST_DEFINITIONS not defined in %s" % |
+ self._GetRulesFilePath()) |
+ return |
+ watchlists = watchlists_data.get("WATCHLISTS") |
+ if not watchlists: |
+ logging.error("WATCHLISTS not defined in %s" % self._GetRulesFilePath()) |
+ return |
+ self._defns = defns |
+ self._watchlists = watchlists |
+ |
+ # Verify that all watchlist names are defined |
+ for name in watchlists: |
+ if name not in defns: |
+ logging.error("%s not defined in %s" % (name, self._GetRulesFilePath())) |
+ |
+ def GetWatchersForPaths(self, paths): |
+ """Fetch the list of watchers for |paths| |
+ |
+ Args: |
+ paths: [path1, path2, ...] |
+ |
+ Returns: |
+ [u1@chromium.org, u2@gmail.com, ...] |
+ """ |
+ watchers = set() # A set, to avoid duplicates |
+ for path in paths: |
+ for name, rule in self._defns.iteritems(): |
+ if name not in self._watchlists: continue |
+ rex_str = rule.get('filepath') |
+ if not rex_str: continue |
+ if re.search(rex_str, path): |
+ map(watchers.add, self._watchlists[name]) |
+ return list(watchers) |
+ |
+ |
+def main(argv): |
+ # Confirm that watchlists can be parsed and spew out the watchers |
+ if len(argv) < 2: |
+ print "Usage (from the base of repo):" |
+ print " %s [file-1] [file-2] ...." % argv[0] |
+ return 1 |
+ wl = Watchlists(os.getcwd()) |
+ watchers = wl.GetWatchersForPaths(argv[1:]) |
+ print watchers |
+ |
+ |
+if __name__ == '__main__': |
+ main(sys.argv) |
Property changes on: watchlists.py |
___________________________________________________________________ |
Name: svn:executable |
+ * |