-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Watchlists provides an opportunity for someone interested in a particular code section to make comments before commit. One can subscribe to watchlists depending on filepath (regular expressions) and she'll automatically get cc-ed to changes when the watchlist is triggered. Additional examples of watchlist_rules in diff repo: http://codereview.chromium.org/118431 http://codereview.chromium.org/119356 Review URL: http://codereview.chromium.org/118432 git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@18209 0039d316-1c4b-4281-b951-d872f2087c98
- Loading branch information
1 parent
899410c
commit b2ab494
Showing
3 changed files
with
154 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# Copyright (c) 2006-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. | ||
|
||
# Watchlist Rules | ||
# Refer: http://dev.chromium.org/developers/contributing-code/watchlists | ||
|
||
{ | ||
|
||
'WATCHLIST_DEFINITIONS': { | ||
'this_file': { | ||
'filepath': '^WATCHLISTS$', | ||
}, | ||
'depot_tools': { | ||
'filepath': '.+', | ||
}, | ||
}, | ||
|
||
'WATCHLISTS': { | ||
'this_file': ['[email protected]'], | ||
'depot_tools': ['[email protected]'], | ||
}, | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -615,6 +615,7 @@ def Help(argv=None): | |
gcl upload change_name [-r [email protected],[email protected],...] | ||
[--send_mail] [--no_try] [--no_presubmit] | ||
[--no_watchlists] | ||
Uploads the changelist to the server for review. | ||
gcl commit change_name [--no_presubmit] | ||
|
@@ -738,6 +739,8 @@ def UploadCL(change_info, args): | |
if not OptionallyDoPresubmitChecks(change_info, False, args): | ||
return | ||
no_try = FilterFlag(args, "--no_try") or FilterFlag(args, "--no-try") | ||
no_watchlists = FilterFlag(args, "--no_watchlists") or \ | ||
FilterFlag(args, "--no-watchlists") | ||
|
||
# Map --send-mail to --send_mail | ||
if FilterFlag(args, "--send-mail"): | ||
|
@@ -775,7 +778,17 @@ def UploadCL(change_info, args): | |
os.write(handle, change_info.description) | ||
os.close(handle) | ||
|
||
# Watchlist processing -- CC people interested in this changeset | ||
# http://dev.chromium.org/developers/contributing-code/watchlists | ||
if not no_watchlists: | ||
import watchlists | ||
watchlist = watchlists.Watchlists(GetRepositoryRoot()) | ||
watchers = watchlist.GetWatchersForPaths(change_info.FileList()) | ||
|
||
cc_list = GetCodeReviewSetting("CC_LIST") | ||
if not no_watchlists and watchers: | ||
# Filter out all empty elements and join by ',' | ||
cc_list = ','.join(filter(None, [cc_list] + watchers)) | ||
if cc_list: | ||
upload_arg.append("--cc=" + cc_list) | ||
upload_arg.append("--description_file=" + desc_file + "") | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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: | ||
[[email protected], [email protected], ...] | ||
""" | ||
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) |