Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(89)

Side by Side Diff: owners.py

Issue 6646007: use PEP-8 naming for method names in owners.py, tests/owners_unittest.py (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | tests/owners_unittest.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 # Copyright (c) 2010 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """A database of OWNERS files.""" 5 """A database of OWNERS files."""
6 6
7 import re 7 import re
8 8
9 9
10 # If this is present by itself on a line, this means that everyone can review. 10 # If this is present by itself on a line, this means that everyone can review.
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 # Mapping of owners to the paths they own. 54 # Mapping of owners to the paths they own.
55 self.owned_by = {EVERYONE: set()} 55 self.owned_by = {EVERYONE: set()}
56 56
57 # Mapping of paths to authorized owners. 57 # Mapping of paths to authorized owners.
58 self.owners_for = {} 58 self.owners_for = {}
59 59
60 # Set of paths that stop us from looking above them for owners. 60 # Set of paths that stop us from looking above them for owners.
61 # (This is implicitly true for the root directory). 61 # (This is implicitly true for the root directory).
62 self.stop_looking = set(['']) 62 self.stop_looking = set([''])
63 63
64 def ReviewersFor(self, files): 64 def reviewers_for(self, files):
65 """Returns a suggested set of reviewers that will cover the set of files. 65 """Returns a suggested set of reviewers that will cover the set of files.
66 66
67 files is a set of paths relative to (and under) self.root.""" 67 files is a set of paths relative to (and under) self.root."""
68 self._CheckPaths(files) 68 self._check_paths(files)
69 self._LoadDataNeededFor(files) 69 self._load_data_needed_for(files)
70 return self._CoveringSetOfOwnersFor(files) 70 return self._covering_set_of_owners_for(files)
71 71
72 def FilesAreCoveredBy(self, files, reviewers): 72 def files_are_covered_by(self, files, reviewers):
73 """Returns whether every file is owned by at least one reviewer.""" 73 """Returns whether every file is owned by at least one reviewer."""
74 return not self.FilesNotCoveredBy(files, reviewers) 74 return not self.files_not_covered_by(files, reviewers)
75 75
76 def FilesNotCoveredBy(self, files, reviewers): 76 def files_not_covered_by(self, files, reviewers):
77 """Returns the set of files that are not owned by at least one reviewer.""" 77 """Returns the set of files that are not owned by at least one reviewer."""
78 self._CheckPaths(files) 78 self._check_paths(files)
79 self._CheckReviewers(reviewers) 79 self._check_reviewers(reviewers)
80 if not reviewers: 80 if not reviewers:
81 return files 81 return files
82 82
83 self._LoadDataNeededFor(files) 83 self._load_data_needed_for(files)
84 files_by_dir = self._FilesByDir(files) 84 files_by_dir = self._files_by_dir(files)
85 covered_dirs = self._DirsCoveredBy(reviewers) 85 covered_dirs = self._dirs_covered_by(reviewers)
86 uncovered_files = [] 86 uncovered_files = []
87 for d, files_in_d in files_by_dir.iteritems(): 87 for d, files_in_d in files_by_dir.iteritems():
88 if not self._IsDirCoveredBy(d, covered_dirs): 88 if not self._is_dir_covered_by(d, covered_dirs):
89 uncovered_files.extend(files_in_d) 89 uncovered_files.extend(files_in_d)
90 return set(uncovered_files) 90 return set(uncovered_files)
91 91
92 def _CheckPaths(self, files): 92 def _check_paths(self, files):
93 def _isunder(f, pfx): 93 def _is_under(f, pfx):
94 return self.os_path.abspath(self.os_path.join(pfx, f)).startswith(pfx) 94 return self.os_path.abspath(self.os_path.join(pfx, f)).startswith(pfx)
95 assert all(_isunder(f, self.os_path.abspath(self.root)) for f in files) 95 assert all(_is_under(f, self.os_path.abspath(self.root)) for f in files)
96 96
97 def _CheckReviewers(self, reviewers): 97 def _check_reviewers(self, reviewers):
98 """Verifies each reviewer is a valid email address.""" 98 """Verifies each reviewer is a valid email address."""
99 assert all(self.email_regexp.match(r) for r in reviewers) 99 assert all(self.email_regexp.match(r) for r in reviewers)
100 100
101 def _FilesByDir(self, files): 101 def _files_by_dir(self, files):
102 dirs = {} 102 dirs = {}
103 for f in files: 103 for f in files:
104 dirs.setdefault(self.os_path.dirname(f), []).append(f) 104 dirs.setdefault(self.os_path.dirname(f), []).append(f)
105 return dirs 105 return dirs
106 106
107 def _DirsCoveredBy(self, reviewers): 107 def _dirs_covered_by(self, reviewers):
108 dirs = self.owned_by[EVERYONE] 108 dirs = self.owned_by[EVERYONE]
109 for r in reviewers: 109 for r in reviewers:
110 dirs = dirs | self.owned_by.get(r, set()) 110 dirs = dirs | self.owned_by.get(r, set())
111 return dirs 111 return dirs
112 112
113 def _StopLooking(self, dirname): 113 def _stop_looking(self, dirname):
114 return dirname in self.stop_looking 114 return dirname in self.stop_looking
115 115
116 def _IsDirCoveredBy(self, dirname, covered_dirs): 116 def _is_dir_covered_by(self, dirname, covered_dirs):
117 while not dirname in covered_dirs and not self._StopLooking(dirname): 117 while not dirname in covered_dirs and not self._stop_looking(dirname):
118 dirname = self.os_path.dirname(dirname) 118 dirname = self.os_path.dirname(dirname)
119 return dirname in covered_dirs 119 return dirname in covered_dirs
120 120
121 def _LoadDataNeededFor(self, files): 121 def _load_data_needed_for(self, files):
122 for f in files: 122 for f in files:
123 dirpath = self.os_path.dirname(f) 123 dirpath = self.os_path.dirname(f)
124 while not dirpath in self.owners_for: 124 while not dirpath in self.owners_for:
125 self._ReadOwnersInDir(dirpath) 125 self._read_owners_in_dir(dirpath)
126 if self._StopLooking(dirpath): 126 if self._stop_looking(dirpath):
127 break 127 break
128 dirpath = self.os_path.dirname(dirpath) 128 dirpath = self.os_path.dirname(dirpath)
129 129
130 def _ReadOwnersInDir(self, dirpath): 130 def _read_owners_in_dir(self, dirpath):
131 owners_path = self.os_path.join(self.root, dirpath, 'OWNERS') 131 owners_path = self.os_path.join(self.root, dirpath, 'OWNERS')
132 if not self.os_path.exists(owners_path): 132 if not self.os_path.exists(owners_path):
133 return 133 return
134 134
135 lineno = 0 135 lineno = 0
136 for line in self.fopen(owners_path): 136 for line in self.fopen(owners_path):
137 lineno += 1 137 lineno += 1
138 line = line.strip() 138 line = line.strip()
139 if line.startswith('#'): 139 if line.startswith('#'):
140 continue 140 continue
141 if line == 'set noparent': 141 if line == 'set noparent':
142 self.stop_looking.add(dirpath) 142 self.stop_looking.add(dirpath)
143 continue 143 continue
144 if self.email_regexp.match(line) or line == EVERYONE: 144 if self.email_regexp.match(line) or line == EVERYONE:
145 self.owned_by.setdefault(line, set()).add(dirpath) 145 self.owned_by.setdefault(line, set()).add(dirpath)
146 self.owners_for.setdefault(dirpath, set()).add(line) 146 self.owners_for.setdefault(dirpath, set()).add(line)
147 continue 147 continue
148 raise SyntaxErrorInOwnersFile(owners_path, lineno, line) 148 raise SyntaxErrorInOwnersFile(owners_path, lineno, line)
149 149
150 def _CoveringSetOfOwnersFor(self, files): 150 def _covering_set_of_owners_for(self, files):
151 # TODO(dpranke): implement the greedy algorithm for covering sets, and 151 # TODO(dpranke): implement the greedy algorithm for covering sets, and
152 # consider returning multiple options in case there are several equally 152 # consider returning multiple options in case there are several equally
153 # short combinations of owners. 153 # short combinations of owners.
154 every_owner = set() 154 every_owner = set()
155 for f in files: 155 for f in files:
156 dirname = self.os_path.dirname(f) 156 dirname = self.os_path.dirname(f)
157 while dirname in self.owners_for: 157 while dirname in self.owners_for:
158 every_owner |= self.owners_for[dirname] 158 every_owner |= self.owners_for[dirname]
159 if self._StopLooking(dirname): 159 if self._stop_looking(dirname):
160 break 160 break
161 dirname = self.os_path.dirname(dirname) 161 dirname = self.os_path.dirname(dirname)
162 return every_owner 162 return every_owner
OLDNEW
« no previous file with comments | « no previous file | tests/owners_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698