| 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 OWNERS files indicate who is allowed to approve changes in a specific directory | 7 OWNERS files indicate who is allowed to approve changes in a specific directory |
| 8 (or who is allowed to make changes without needing approval of another OWNER). | 8 (or who is allowed to make changes without needing approval of another OWNER). |
| 9 Note that all changes must still be reviewed by someone familiar with the code, | 9 Note that all changes must still be reviewed by someone familiar with the code, |
| 10 so you may need approval from both an OWNER and a reviewer in many cases. | 10 so you may need approval from both an OWNER and a reviewer in many cases. |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 114 # Set of paths that stop us from looking above them for owners. | 114 # Set of paths that stop us from looking above them for owners. |
| 115 # (This is implicitly true for the root directory). | 115 # (This is implicitly true for the root directory). |
| 116 self.stop_looking = set(['']) | 116 self.stop_looking = set(['']) |
| 117 | 117 |
| 118 def reviewers_for(self, files): | 118 def reviewers_for(self, files): |
| 119 """Returns a suggested set of reviewers that will cover the files. | 119 """Returns a suggested set of reviewers that will cover the files. |
| 120 | 120 |
| 121 files is a sequence of paths relative to (and under) self.root.""" | 121 files is a sequence of paths relative to (and under) self.root.""" |
| 122 self._check_paths(files) | 122 self._check_paths(files) |
| 123 self._load_data_needed_for(files) | 123 self._load_data_needed_for(files) |
| 124 return self._covering_set_of_owners_for(files) | 124 suggested_owners = self._covering_set_of_owners_for(files) |
| 125 if EVERYONE in suggested_owners: |
| 126 if len(suggested_owners) > 1: |
| 127 suggested_owners.remove(EVERYONE) |
| 128 else: |
| 129 suggested_owners = set(['<anyone>']) |
| 130 return suggested_owners |
| 125 | 131 |
| 126 # TODO(dpranke): rename to objects_not_covered_by | 132 # TODO(dpranke): rename to objects_not_covered_by |
| 127 def directories_not_covered_by(self, files, reviewers): | 133 def directories_not_covered_by(self, files, reviewers): |
| 128 """Returns the set of directories that are not owned by a reviewer. | 134 """Returns the set of directories that are not owned by a reviewer. |
| 129 | 135 |
| 130 Determines which of the given files are not owned by at least one of the | 136 Determines which of the given files are not owned by at least one of the |
| 131 reviewers, then returns a set containing the applicable enclosing | 137 reviewers, then returns a set containing the applicable enclosing |
| 132 directories, i.e. the ones upward from the files that have OWNERS files. | 138 directories, i.e. the ones upward from the files that have OWNERS files. |
| 133 | 139 |
| 134 Args: | 140 Args: |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 303 if num_directories_owned: | 309 if num_directories_owned: |
| 304 total_costs_by_owner[owner] = (total_distance / | 310 total_costs_by_owner[owner] = (total_distance / |
| 305 pow(num_directories_owned, 1.75)) | 311 pow(num_directories_owned, 1.75)) |
| 306 | 312 |
| 307 # Return the lowest cost owner. In the case of a tie, pick one randomly. | 313 # Return the lowest cost owner. In the case of a tie, pick one randomly. |
| 308 lowest_cost = min(total_costs_by_owner.itervalues()) | 314 lowest_cost = min(total_costs_by_owner.itervalues()) |
| 309 lowest_cost_owners = filter( | 315 lowest_cost_owners = filter( |
| 310 lambda owner: total_costs_by_owner[owner] == lowest_cost, | 316 lambda owner: total_costs_by_owner[owner] == lowest_cost, |
| 311 total_costs_by_owner) | 317 total_costs_by_owner) |
| 312 return random.Random().choice(lowest_cost_owners) | 318 return random.Random().choice(lowest_cost_owners) |
| OLD | NEW |