Chromium Code Reviews

Unified Diff: owners.py

Issue 6581030: Add first changes needed for OWNERS file support. (Closed) Base URL: http://src.chromium.org/svn/trunk/tools/depot_tools
Patch Set: Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
« no previous file with comments | « no previous file | presubmit_canned_checks.py » ('j') | presubmit_canned_checks.py » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: owners.py
diff --git a/owners.py b/owners.py
new file mode 100644
index 0000000000000000000000000000000000000000..921b21a7ba7996c07623294583c0cfbf0d7ef1bb
--- /dev/null
+++ b/owners.py
@@ -0,0 +1,98 @@
+# Copyright (c) 2010 The Chromium Authors. All rights reserved.
M-A Ruel 2011/02/24 16:25:57 2011
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""A database of OWNERS files."""
+
+import os
+import pdb
M-A Ruel 2011/02/24 16:25:57 remove
+
+
+class Assertion(AssertionError):
+ pass
+
+class Database(object):
+ 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
+ open=file,
+ os_path=os.path):
+ """Initialize the database of owners for a repository.
M-A Ruel 2011/02/24 16:25:57 Initializes
+
+ Args:
+ root: the path to the root of the Repository
+ all_owners: the list of every owner in the system
+ open: function callback to open a text file for reading
+ os_path: module/object callback with fields for 'exists',
+ 'dirname', and 'join'
+ """
+ self.root = root
+ self.all_owners = all_owners or set()
+ self.open = open
+ self.os_path = os_path
+
+ # Mapping of files to authorized owners.
+ self.files_owned_by = {}
+
+ # Mapping of owners to the files they own.
+ self.owners_for = {}
+
+ # In-memory cached map of files to their OWNERS files.
+ self.owners_file_for = {}
+
+ # In-memory cache of OWNERS files and their contents
+ self.owners_files = {}
+
+ def OwnersFor(self, files):
+ """Returns a list of sets of reviewers that will cover the set of files.
+
+ The set of files are paths relative to (and under) self.root."""
+ self._LoadDataNeededFor(files)
+ return self._FindCoveringSets(files)
+
+ def AreCovered(self, files, reviewers):
+ return len(self.not_covered(files, reviewers)) == 0
M-A Ruel 2011/02/24 16:25:57 return not self.not_covered(files, reviewers)
+
+ def FilesNotCoveredBy(self, files, reviewers):
+ covered_files = set()
+ for reviewer in reviewers:
+ covered_files = covered_files.union(self.files_owned_by(reviewer))
+ return files.difference(covered_files)
+
+ def _LoadDataNeededFor(self, files):
+ for f in files:
+ self._LoadOwnersFor(f)
+
+ def _LoadOwnersFor(self, f):
+ if f not in self.owners_for:
+ owner_file = self._FindOwnersFileFor(f)
+ self.owners_file_for[f] = owner_file
+ self._ReadOwnersFile(owner_file, f)
+
+ def _FindOwnersFileFor(self, f):
+ # This is really a "do ... until dirname = ''"
+ dirname = self.os_path.dirname(f)
+ while dirname:
+ owner_path = self.os_path.join(dirname, 'OWNERS')
+ if self.os_path.exists(owner_path):
+ return owner_path
+ dirname = self.os_path.dirname(dirname)
+ owner_path = self.os_path.join(dirname, 'OWNERS')
+ if self.os_path.exists(owner_path):
+ return owner_path
+
+ 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
+
+ def _ReadOwnersFile(self, owner_file, affected_file):
+ owners_for = self.owners_for.setdefault(affected_file, set())
+ for owner in self.open(owner_file).readlines():
M-A Ruel 2011/02/24 16:25:57 .readlines() is implied.
+ owner = owner.strip()
+ self.files_owned_by.setdefault(owner, set()).add(affected_file)
+ owners_for.add(owner)
+
+ def _FindCoveringSets(self, files):
+ # TODO(dpranke): implement the greedy algorithm for covering sets.
+ # For now we return the list of every owner that touches at least
+ # one file in the set.
+ all_owners = set()
+ for f in files:
+ all_owners = all_owners.union(self.owners_for[f])
+ return [all_owners]
M-A Ruel 2011/02/24 16:25:57 Did you mean: return list(all_owners) ?
« no previous file with comments | « no previous file | presubmit_canned_checks.py » ('j') | presubmit_canned_checks.py » ('J')

Powered by Google App Engine