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

Side by Side Diff: owners.py

Issue 9621012: Show a list of directories missing OWNER reviewers on upload, and show directories rather than file… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools/
Patch Set: Uncommented owners unit test Created 8 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 | presubmit_canned_checks.py » ('j') | presubmit_canned_checks.py » ('J')
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 collections 7 import collections
8 import re 8 import re
9 9
10 10
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 72
73 files is a sequence of paths relative to (and under) self.root.""" 73 files is a sequence of paths relative to (and under) self.root."""
74 self._check_paths(files) 74 self._check_paths(files)
75 self._load_data_needed_for(files) 75 self._load_data_needed_for(files)
76 return self._covering_set_of_owners_for(files) 76 return self._covering_set_of_owners_for(files)
77 77
78 def files_are_covered_by(self, files, reviewers): 78 def files_are_covered_by(self, files, reviewers):
79 """Returns whether every file is owned by at least one reviewer.""" 79 """Returns whether every file is owned by at least one reviewer."""
80 return not self.files_not_covered_by(files, reviewers) 80 return not self.files_not_covered_by(files, reviewers)
81 81
82 def files_not_covered_by(self, files, reviewers): 82 def directories_not_covered_by(self, files, reviewers):
83 """Returns the set of files that are not owned by at least one reviewer. 83 """Returns the set of directories that are not owned by a reviewer.
84
85 See files_not_covered_by() for details.
86 """
87 return self.files_not_covered_by(files, reviewers, directories=True)
88
89 def files_not_covered_by(self, files, reviewers, directories=False):
Dirk Pranke 2012/03/07 21:51:47 With your change in presubmit_canned_checks, I thi
Pam (message me for reviews) 2012/03/07 22:21:11 Done. It slightly changes the special-cased behavi
90 """Returns the set of items that are not owned by at least one reviewer.
84 91
85 Args: 92 Args:
86 files is a sequence of paths relative to (and under) self.root. 93 files is a sequence of paths relative to (and under) self.root.
87 reviewers is a sequence of strings matching self.email_regexp.""" 94 reviewers is a sequence of strings matching self.email_regexp.
95 if directories is True, returns a set of directories; otherwise,
96 returns a set of files.
97 """
88 self._check_paths(files) 98 self._check_paths(files)
89 self._check_reviewers(reviewers) 99 self._check_reviewers(reviewers)
90 if not reviewers: 100 if not reviewers and not directories:
91 return files 101 return files
92 102
93 self._load_data_needed_for(files) 103 self._load_data_needed_for(files)
94 files_by_dir = self._files_by_dir(files) 104 files_by_dir = self._files_by_dir(files)
95 covered_dirs = self._dirs_covered_by(reviewers) 105 if reviewers:
106 covered_dirs = self._dirs_covered_by(reviewers)
107 else:
108 covered_dirs = set()
96 uncovered_files = [] 109 uncovered_files = []
97 for d, files_in_d in files_by_dir.iteritems(): 110 for d, files_in_d in files_by_dir.iteritems():
98 if not self._is_dir_covered_by(d, covered_dirs): 111 if not self._is_dir_covered_by(d, covered_dirs):
99 uncovered_files.extend(files_in_d) 112 if directories:
113 uncovered_files.append(self._enclosing_dir_with_owners(d))
114 else:
115 uncovered_files.extend(files_in_d)
100 return set(uncovered_files) 116 return set(uncovered_files)
101 117
102 def _check_paths(self, files): 118 def _check_paths(self, files):
103 def _is_under(f, pfx): 119 def _is_under(f, pfx):
104 return self.os_path.abspath(self.os_path.join(pfx, f)).startswith(pfx) 120 return self.os_path.abspath(self.os_path.join(pfx, f)).startswith(pfx)
105 _assert_is_collection(files) 121 _assert_is_collection(files)
106 assert all(_is_under(f, self.os_path.abspath(self.root)) for f in files) 122 assert all(_is_under(f, self.os_path.abspath(self.root)) for f in files)
107 123
108 def _check_reviewers(self, reviewers): 124 def _check_reviewers(self, reviewers):
109 _assert_is_collection(reviewers) 125 _assert_is_collection(reviewers)
(...skipping 12 matching lines...) Expand all
122 return dirs 138 return dirs
123 139
124 def _stop_looking(self, dirname): 140 def _stop_looking(self, dirname):
125 return dirname in self.stop_looking 141 return dirname in self.stop_looking
126 142
127 def _is_dir_covered_by(self, dirname, covered_dirs): 143 def _is_dir_covered_by(self, dirname, covered_dirs):
128 while not dirname in covered_dirs and not self._stop_looking(dirname): 144 while not dirname in covered_dirs and not self._stop_looking(dirname):
129 dirname = self.os_path.dirname(dirname) 145 dirname = self.os_path.dirname(dirname)
130 return dirname in covered_dirs 146 return dirname in covered_dirs
131 147
148 def _enclosing_dir_with_owners(self, directory):
149 """Returns the innermost enclosing directory that has an OWNERS file."""
150 dirpath = directory
151 while not dirpath in self.owners_for:
152 if self._stop_looking(dirpath):
153 break
154 dirpath = self.os_path.dirname(dirpath)
155 return dirpath
156
132 def _load_data_needed_for(self, files): 157 def _load_data_needed_for(self, files):
133 for f in files: 158 for f in files:
134 dirpath = self.os_path.dirname(f) 159 dirpath = self.os_path.dirname(f)
135 while not dirpath in self.owners_for: 160 while not dirpath in self.owners_for:
136 self._read_owners_in_dir(dirpath) 161 self._read_owners_in_dir(dirpath)
137 if self._stop_looking(dirpath): 162 if self._stop_looking(dirpath):
138 break 163 break
139 dirpath = self.os_path.dirname(dirpath) 164 dirpath = self.os_path.dirname(dirpath)
140 165
141 def _read_owners_in_dir(self, dirpath): 166 def _read_owners_in_dir(self, dirpath):
(...skipping 27 matching lines...) Expand all
169 # short combinations of owners. 194 # short combinations of owners.
170 every_owner = set() 195 every_owner = set()
171 for f in files: 196 for f in files:
172 dirname = self.os_path.dirname(f) 197 dirname = self.os_path.dirname(f)
173 while dirname in self.owners_for: 198 while dirname in self.owners_for:
174 every_owner |= self.owners_for[dirname] 199 every_owner |= self.owners_for[dirname]
175 if self._stop_looking(dirname): 200 if self._stop_looking(dirname):
176 break 201 break
177 dirname = self.os_path.dirname(dirname) 202 dirname = self.os_path.dirname(dirname)
178 return every_owner 203 return every_owner
OLDNEW
« no previous file with comments | « no previous file | presubmit_canned_checks.py » ('j') | presubmit_canned_checks.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698