changeset 6261:a2491c578d2b

topic: namespace revset predicate
author Anton Shestakov <av6@dwimlabs.net>
date Tue, 24 May 2022 10:24:36 +0400
parents d1a6d83a7109
children b4e1d34ad1e9
files hgext3rd/topic/revset.py tests/test-namespaces.t
diffstat 2 files changed, 72 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/hgext3rd/topic/revset.py	Tue May 31 12:25:49 2022 +0400
+++ b/hgext3rd/topic/revset.py	Tue May 24 10:24:36 2022 +0400
@@ -21,6 +21,53 @@
         return x[1]
     raise error.ParseError(err)
 
+@revsetpredicate(b'topicnamespace([string or set])')
+def topicnamespaceset(repo, subset, x):
+    """All changesets with the specified topic namespace or the topic
+    namespaces of the given changesets. Without the argument, all changesets
+    with any non-default topic namespace.
+
+     Pattern matching is supported for `string`. See
+    :hg:`help revisions.patterns`.
+    """
+    args = revset.getargs(x, 0, 1, b'topicnamespace takes one or no arguments')
+
+    mutable = revset._notpublic(repo, revset.fullreposet(repo), ())
+
+    if not args:
+        return (subset & mutable).filter(lambda r: repo[r].topic_namespace() != b'default')
+
+    try:
+        tns = getstringstrict(args[0], b'')
+    except error.ParseError:
+        # not a string, but another revset
+        pass
+    else:
+        kind, pattern, matcher = stringutil.stringmatcher(tns)
+
+        if tns.startswith(b'literal:') and pattern not in repo.topic_namespaces:
+            raise error.RepoLookupError(b"topic namespace '%s' does not exist" % pattern)
+
+        def matches(r):
+            tns = repo[r].topic_namespace()
+            if tns == b'default':
+                return False
+            return matcher(tns)
+
+        return (subset & mutable).filter(matches)
+
+    s = revset.getset(repo, revset.fullreposet(repo), x)
+    namespaces = {repo[r].topic_namespace() for r in s}
+    namespaces.discard(b'default')
+
+    def matches(r):
+        tns = repo[r].topic_namespace()
+        if tns == b'default':
+            return False
+        return tns in namespaces
+
+    return (subset & mutable).filter(matches)
+
 @revsetpredicate(b'topic([string or set])')
 def topicset(repo, subset, x):
     """All changesets with the specified topic or the topics of the given
--- a/tests/test-namespaces.t	Tue May 31 12:25:49 2022 +0400
+++ b/tests/test-namespaces.t	Tue May 24 10:24:36 2022 +0400
@@ -62,6 +62,31 @@
   $ hg topics
    * feature (1 changesets)
 
+Revsets
+
+  $ nslog() {
+  >   hg log -T '{rev}: {topic_namespace}\n' -r "$1"
+  > }
+
+  $ nslog 'topicnamespace(:)'
+  0: alice
+  $ nslog 'topicnamespace(all())'
+  0: alice
+  $ nslog 'topicnamespace(topicnamespace("alice"))'
+  0: alice
+  $ nslog 'topicnamespace(wdir())'
+  0: alice
+  $ nslog 'topicnamespace("re:ice$")'
+  0: alice
+  $ nslog 'topicnamespace(nonsense)'
+  abort: unknown revision 'nonsense'
+  [10]
+
+  $ nslog 'topicnamespace("re:nonsense")'
+  $ nslog 'topicnamespace("literal:nonsense")'
+  abort: topic namespace 'nonsense' does not exist
+  [10]
+
 Parsing
 
   $ hg debugparsefqbn foo/bar//user26/feature -T '[{branch}] <{topic_namespace}> ({topic})\n'