diff --git a/gerrit_util.py b/gerrit_util.py index 6312b1622..3b13f19dd 100644 --- a/gerrit_util.py +++ b/gerrit_util.py @@ -770,6 +770,23 @@ def SetCommitMessage(host, change, description, notify='ALL'): 'in change %s' % change) +def GetOwnersForFile(host, project, branch, path, limit=100, + o_params=('DETAILS',)): + """Gets information about owners attached to a file.""" + path = 'projects/%s/branches/%s/code_owners/%s' % ( + urllib.parse.quote(project, ''), + urllib.parse.quote(branch, ''), + urllib.parse.quote(path, '')) + q = [] + if limit: + q.append('n=%d' % limit) + if o_params: + q.extend(['o=%s' % p for p in o_params]) + if q: + path = '%s?%s' % (path, '&'.join(q)) + return ReadHttpJsonResponse(CreateHttpConn(host, path)) + + def GetReviewers(host, change): """Gets information about all reviewers attached to a change.""" path = 'changes/%s/reviewers' % change diff --git a/owners_client.py b/owners_client.py index 01b3f181c..5ceec08b5 100644 --- a/owners_client.py +++ b/owners_client.py @@ -194,3 +194,16 @@ class DepotToolsClient(OwnersClient): [f for f in files if os.path.basename(f) == 'OWNERS']) except Exception as e: raise InvalidOwnersConfig('Error parsing OWNERS files:\n%s' % e) + + +class GerritClient(OwnersClient): + """Implement OwnersClient using OWNERS REST API.""" + def __init__(self, host): + super(GerritClient, self).__init__(host) + + def ListOwnersForFile(self, project, branch, path): + # GetOwnersForFile returns a list of account details sorted by order of + # best reviewer for path. If code owners have the same score, the order is + # random. + data = gerrit_util.GetOwnersForFile(self._host, project, branch, path) + return [d['account']['email'] for d in data] diff --git a/tests/owners_client_test.py b/tests/owners_client_test.py index 489bb718d..e25c1c48f 100644 --- a/tests/owners_client_test.py +++ b/tests/owners_client_test.py @@ -63,6 +63,27 @@ def _get_change(): +def _get_owners(): + return [ + { + "account": { + "email": 'approver@example.com' + } + }, + { + "account": { + "email": 'reviewer@example.com' + }, + }, + { + "account": { + "email": 'missing@example.com' + }, + } + ] + + + class DepotToolsClientTest(unittest.TestCase): def setUp(self): self.repo = filesystem_mock.MockFileSystem(files={ @@ -118,6 +139,18 @@ class DepotToolsClientTest(unittest.TestCase): self.client.ValidateOwnersConfig('changeid') +class GerritClientTest(unittest.TestCase): + def setUp(self): + self.client = owners_client.GerritClient('host') + + @mock.patch('gerrit_util.GetOwnersForFile', return_value=_get_owners()) + def testListOwners(self, get_owners_mock): + self.assertEquals( + ['approver@example.com', 'reviewer@example.com', 'missing@example.com'], + self.client.ListOwnersForFile('project', 'branch', + 'bar/everyone/foo.txt')) + + class TestClient(owners_client.OwnersClient): def __init__(self, host, owners_by_path): super(TestClient, self).__init__(host)