← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] ~cjwatson/turnip:refs-exclude into turnip:master

 

Colin Watson has proposed merging ~cjwatson/turnip:refs-exclude into turnip:master.

Commit message:
Add exclude_prefix query param to /repo/{}/refs

This allows us to exclude some ref namespaces from being scanned by
Launchpad.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~cjwatson/turnip/+git/turnip/+merge/359204
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of ~cjwatson/turnip:refs-exclude into turnip:master.
diff --git a/turnip/api/store.py b/turnip/api/store.py
index 38d6294..6ecc55d 100644
--- a/turnip/api/store.py
+++ b/turnip/api/store.py
@@ -283,7 +283,7 @@ def repack(repo_path, ignore_alternates=False, single=False,
         stderr=subprocess.PIPE, stdout=subprocess.PIPE)
 
 
-def get_refs(repo_store, repo_name):
+def get_refs(repo_store, repo_name, exclude_prefixes=None):
     """Return all refs for a git repository."""
     with open_repo(repo_store, repo_name) as repo:
         refs = {}
@@ -292,11 +292,16 @@ def get_refs(repo_store, repo_name):
             # Filter non-unicode refs, as refs are treated as unicode
             # given json is unable to represent arbitrary byte strings.
             try:
-                ref.decode('utf-8')
+                ref = ref.decode('utf-8')
             except UnicodeDecodeError:
                 pass
             else:
-                refs.update(format_ref(ref, git_object))
+                excluded = False
+                for exclude_prefix in (exclude_prefixes or []):
+                    if ref.startswith(exclude_prefix):
+                        excluded = True
+                if not excluded:
+                    refs.update(format_ref(ref, git_object))
         return refs
 
 
diff --git a/turnip/api/tests/test_api.py b/turnip/api/tests/test_api.py
index 4ca1aac..f435d75 100644
--- a/turnip/api/tests/test_api.py
+++ b/turnip/api/tests/test_api.py
@@ -21,6 +21,10 @@ from fixtures import (
     TempDir,
     )
 from testtools import TestCase
+from testtools.matchers import (
+    Equals,
+    MatchesSetwise,
+    )
 from webtest import TestApp
 
 from turnip import api
@@ -233,6 +237,25 @@ class ApiTestCase(TestCase):
         refs = resp.json
         self.assertEqual(2, len(refs.keys()))
 
+    def test_repo_get_refs_exclude_prefixes(self):
+        """Refs matching an excluded prefix are not returned."""
+        factory = RepoFactory(self.repo_store, num_commits=1)
+        factory.build()
+        for ref_path in (
+                'refs/heads/refs/changes/1',
+                'refs/changes/2',
+                'refs/pull/3/head',
+                ):
+            factory.repo.references.create(ref_path, factory.commits[0])
+
+        resp = self.app.get(
+            '/repo/{}/refs'
+            '?exclude_prefix=refs/changes/'
+            '&exclude_prefix=refs/pull/'.format(self.repo_path))
+        refs = resp.json
+        self.assertThat(list(refs), MatchesSetwise(
+            Equals('refs/heads/master'), Equals('refs/heads/refs/changes/1')))
+
     def test_repo_get_ref(self):
         RepoFactory(self.repo_store, num_commits=1).build()
         ref = 'refs/heads/master'
diff --git a/turnip/api/views.py b/turnip/api/views.py
index abdfaca..90644dc 100644
--- a/turnip/api/views.py
+++ b/turnip/api/views.py
@@ -166,8 +166,10 @@ class RefAPI(BaseAPI):
 
     @validate_path
     def collection_get(self, repo_store, repo_name):
+        exclude_prefixes = self.request.params.getall('exclude_prefix')
         try:
-            return store.get_refs(repo_store, repo_name)
+            return store.get_refs(
+                repo_store, repo_name, exclude_prefixes=exclude_prefixes)
         except (KeyError, GitError):
             return exc.HTTPNotFound()  # 404