OLD | NEW |
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2012 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 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 'unknown option: "%s"' % line[4:].strip()) | 158 'unknown option: "%s"' % line[4:].strip()) |
159 if self.email_regexp.match(line) or line == EVERYONE: | 159 if self.email_regexp.match(line) or line == EVERYONE: |
160 self.owned_by.setdefault(line, set()).add(dirpath) | 160 self.owned_by.setdefault(line, set()).add(dirpath) |
161 self.owners_for.setdefault(dirpath, set()).add(line) | 161 self.owners_for.setdefault(dirpath, set()).add(line) |
162 continue | 162 continue |
163 raise SyntaxErrorInOwnersFile(owners_path, lineno, | 163 raise SyntaxErrorInOwnersFile(owners_path, lineno, |
164 ('line is not a comment, a "set" directive, ' | 164 ('line is not a comment, a "set" directive, ' |
165 'or an email address: "%s"' % line)) | 165 'or an email address: "%s"' % line)) |
166 | 166 |
167 def _covering_set_of_owners_for(self, files): | 167 def _covering_set_of_owners_for(self, files): |
168 # TODO(dpranke): implement the greedy algorithm for covering sets, and | 168 # Get the set of directories from the files. |
169 # consider returning multiple options in case there are several equally | 169 dirs = set() |
170 # short combinations of owners. | |
171 every_owner = set() | |
172 for f in files: | 170 for f in files: |
173 dirname = self.os_path.dirname(f) | 171 dirs.add(self.os_path.dirname(f)) |
| 172 |
| 173 owned_dirs = {} |
| 174 dir_owners = {} |
| 175 |
| 176 for current_dir in dirs: |
| 177 # Get the list of owners for each directory. |
| 178 current_owners = set() |
| 179 dirname = current_dir |
174 while dirname in self.owners_for: | 180 while dirname in self.owners_for: |
175 every_owner |= self.owners_for[dirname] | 181 for owner in self.owners_for[dirname]: |
| 182 current_owners.add(owner) |
176 if self._stop_looking(dirname): | 183 if self._stop_looking(dirname): |
177 break | 184 break |
178 dirname = self.os_path.dirname(dirname) | 185 dirname = self.os_path.dirname(dirname) |
179 return every_owner | 186 |
| 187 # Map each directory to a list of its owners. |
| 188 dir_owners[current_dir] = current_owners |
| 189 |
| 190 # Add the directory to the list of each owner. |
| 191 for owner in current_owners: |
| 192 if not owner in owned_dirs: |
| 193 owned_dirs[owner] = set() |
| 194 owned_dirs[owner].add(current_dir) |
| 195 |
| 196 final_owners = set() |
| 197 while dirs: |
| 198 # Find the owner that has the most directories. |
| 199 max_count = 0 |
| 200 max_owner = None |
| 201 owner_count = {} |
| 202 for dirname in dirs: |
| 203 for owner in dir_owners[dirname]: |
| 204 count = owner_count.get(owner, 0) + 1 |
| 205 owner_count[owner] = count |
| 206 if count >= max_count: |
| 207 max_owner = owner |
| 208 |
| 209 # If no more directories have OWNERS, we're done. |
| 210 if not max_owner: |
| 211 break |
| 212 |
| 213 final_owners.add(max_owner) |
| 214 |
| 215 # Remove all directories owned by the current owner from the remaining |
| 216 # list. |
| 217 for dirname in owned_dirs[max_owner]: |
| 218 dirs.remove(dirname) |
| 219 |
| 220 return final_owners |
OLD | NEW |