Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 # Copyright (c) 2010 The Chromium Authors. All rights reserved. | |
|
M-A Ruel
2011/02/24 16:25:57
2011
| |
| 2 # Use of this source code is governed by a BSD-style license that can be | |
| 3 # found in the LICENSE file. | |
| 4 | |
| 5 """A database of OWNERS files.""" | |
| 6 | |
| 7 import os | |
| 8 import pdb | |
|
M-A Ruel
2011/02/24 16:25:57
remove
| |
| 9 | |
| 10 | |
| 11 class Assertion(AssertionError): | |
| 12 pass | |
| 13 | |
| 14 class Database(object): | |
| 15 def __init__(self, root, all_owners=None, | |
|
M-A Ruel
2011/02/24 16:25:57
Either all align one per line or all packed at 80
| |
| 16 open=file, | |
| 17 os_path=os.path): | |
| 18 """Initialize the database of owners for a repository. | |
|
M-A Ruel
2011/02/24 16:25:57
Initializes
| |
| 19 | |
| 20 Args: | |
| 21 root: the path to the root of the Repository | |
| 22 all_owners: the list of every owner in the system | |
| 23 open: function callback to open a text file for reading | |
| 24 os_path: module/object callback with fields for 'exists', | |
| 25 'dirname', and 'join' | |
| 26 """ | |
| 27 self.root = root | |
| 28 self.all_owners = all_owners or set() | |
| 29 self.open = open | |
| 30 self.os_path = os_path | |
| 31 | |
| 32 # Mapping of files to authorized owners. | |
| 33 self.files_owned_by = {} | |
| 34 | |
| 35 # Mapping of owners to the files they own. | |
| 36 self.owners_for = {} | |
| 37 | |
| 38 # In-memory cached map of files to their OWNERS files. | |
| 39 self.owners_file_for = {} | |
| 40 | |
| 41 # In-memory cache of OWNERS files and their contents | |
| 42 self.owners_files = {} | |
| 43 | |
| 44 def OwnersFor(self, files): | |
| 45 """Returns a list of sets of reviewers that will cover the set of files. | |
| 46 | |
| 47 The set of files are paths relative to (and under) self.root.""" | |
| 48 self._LoadDataNeededFor(files) | |
| 49 return self._FindCoveringSets(files) | |
| 50 | |
| 51 def AreCovered(self, files, reviewers): | |
| 52 return len(self.not_covered(files, reviewers)) == 0 | |
|
M-A Ruel
2011/02/24 16:25:57
return not self.not_covered(files, reviewers)
| |
| 53 | |
| 54 def FilesNotCoveredBy(self, files, reviewers): | |
| 55 covered_files = set() | |
| 56 for reviewer in reviewers: | |
| 57 covered_files = covered_files.union(self.files_owned_by(reviewer)) | |
| 58 return files.difference(covered_files) | |
| 59 | |
| 60 def _LoadDataNeededFor(self, files): | |
| 61 for f in files: | |
| 62 self._LoadOwnersFor(f) | |
| 63 | |
| 64 def _LoadOwnersFor(self, f): | |
| 65 if f not in self.owners_for: | |
| 66 owner_file = self._FindOwnersFileFor(f) | |
| 67 self.owners_file_for[f] = owner_file | |
| 68 self._ReadOwnersFile(owner_file, f) | |
| 69 | |
| 70 def _FindOwnersFileFor(self, f): | |
| 71 # This is really a "do ... until dirname = ''" | |
| 72 dirname = self.os_path.dirname(f) | |
| 73 while dirname: | |
| 74 owner_path = self.os_path.join(dirname, 'OWNERS') | |
| 75 if self.os_path.exists(owner_path): | |
| 76 return owner_path | |
| 77 dirname = self.os_path.dirname(dirname) | |
| 78 owner_path = self.os_path.join(dirname, 'OWNERS') | |
| 79 if self.os_path.exists(owner_path): | |
| 80 return owner_path | |
| 81 | |
| 82 raise Assertion('No OWNERS file found for %s' % f) | |
|
M-A Ruel
2011/02/24 16:25:57
Is this really an exceptional event? I think it sh
| |
| 83 | |
| 84 def _ReadOwnersFile(self, owner_file, affected_file): | |
| 85 owners_for = self.owners_for.setdefault(affected_file, set()) | |
| 86 for owner in self.open(owner_file).readlines(): | |
|
M-A Ruel
2011/02/24 16:25:57
.readlines() is implied.
| |
| 87 owner = owner.strip() | |
| 88 self.files_owned_by.setdefault(owner, set()).add(affected_file) | |
| 89 owners_for.add(owner) | |
| 90 | |
| 91 def _FindCoveringSets(self, files): | |
| 92 # TODO(dpranke): implement the greedy algorithm for covering sets. | |
| 93 # For now we return the list of every owner that touches at least | |
| 94 # one file in the set. | |
| 95 all_owners = set() | |
| 96 for f in files: | |
| 97 all_owners = all_owners.union(self.owners_for[f]) | |
| 98 return [all_owners] | |
|
M-A Ruel
2011/02/24 16:25:57
Did you mean:
return list(all_owners)
?
| |
| OLD | NEW |