diff --git a/swh/graphql/backends/archive.py b/swh/graphql/backends/archive.py --- a/swh/graphql/backends/archive.py +++ b/swh/graphql/backends/archive.py @@ -82,6 +82,7 @@ first: int = 50, target_types: Optional[List[str]] = None, name_include: Optional[bytes] = None, + name_exclude_prefix: Optional[bytes] = None, ) -> Optional[PartialBranches]: return self.storage.snapshot_get_branches( snapshot_id=snapshot, @@ -89,6 +90,7 @@ branches_count=first, target_types=target_types, branch_name_include_substring=name_include, + branch_name_exclude_prefix=name_exclude_prefix, ) def get_revisions(self, revision_ids: List[Sha1Git]) -> List[Optional[Revision]]: diff --git a/swh/graphql/resolvers/snapshot_branch.py b/swh/graphql/resolvers/snapshot_branch.py --- a/swh/graphql/resolvers/snapshot_branch.py +++ b/swh/graphql/resolvers/snapshot_branch.py @@ -96,6 +96,7 @@ first=self._get_first_arg(), target_types=self.kwargs.get("types"), name_include=self._get_name_include_arg(), + name_exclude_prefix=self._get_name_exclude_prefix_arg(), ) # endCursor is the last branch name, logic for that end_cusrsor = ( @@ -119,6 +120,10 @@ name_include = self.kwargs.get("nameInclude", None) return name_include.encode() if name_include else None + def _get_name_exclude_prefix_arg(self): + name_exclude_prefix = self.kwargs.get("nameExcludePrefix", None) + return name_exclude_prefix.encode() if name_exclude_prefix else None + def _get_index_cursor(self, index: int, node: BaseSnapshotBranchNode): # Snapshot branch is using a different cursor, hence the override return utils.get_encoded_cursor(node.name) diff --git a/swh/graphql/schema/schema.graphql b/swh/graphql/schema/schema.graphql --- a/swh/graphql/schema/schema.graphql +++ b/swh/graphql/schema/schema.graphql @@ -401,9 +401,14 @@ types: [BranchTargetType] """ - Filter by branch name + Return branches whose name contains the given substring """ nameInclude: String + + """ + Do not return branches whose name contains the given prefix + """ + nameExcludePrefix: String ): BranchConnection } diff --git a/swh/graphql/tests/functional/test_branch_connection.py b/swh/graphql/tests/functional/test_branch_connection.py --- a/swh/graphql/tests/functional/test_branch_connection.py +++ b/swh/graphql/tests/functional/test_branch_connection.py @@ -127,6 +127,14 @@ assert name in node["name"]["text"] +@pytest.mark.parametrize("name", ["target", "target/dir"]) +def test_get_name_exclude_prefix_filter(client, name): + swhid = "swh:1:snp:0e7f84ede9a254f2cd55649ad5240783f557e65f" + data, _ = get_branches(client, swhid, 10, nameExcludePrefix=f'"{name}"') + for node in data["snapshot"]["branches"]["nodes"]: + assert not node["name"]["text"].startswith(name) + + @pytest.mark.parametrize("count", [1, 2]) def test_get_first_arg(client, count): swhid = "swh:1:snp:0e7f84ede9a254f2cd55649ad5240783f557e65f"