]> git.notmuchmail.org Git - notmuch/commitdiff
CLI/git: replace enumeration of tags with sexp query.
authorDavid Bremner <david@tethera.net>
Sun, 10 Apr 2022 17:22:57 +0000 (14:22 -0300)
committerDavid Bremner <david@tethera.net>
Fri, 17 Jun 2022 11:40:19 +0000 (08:40 -0300)
Unlike the (current) infix query parser provided by Xapian, the
notmuch specific sexp query parser supports prefixed wildcard queries,
so use those. In addition to being somewhat faster, this avoids
needing to escape all of the user's tags to pass via the shell.

notmuch-git.py
test/T850-git.sh

index 543ef4f1066ab350a3df1b4dc765b129a1d64a4e..badf900054e64fe9c4e237b2b7c67b40cd1177c2 100644 (file)
@@ -219,16 +219,17 @@ def _get_remote():
         stdout=_subprocess.PIPE, wait=True)
     return remote.strip()
 
+def _tag_query(prefix=None):
+    if prefix is None:
+        prefix = TAG_PREFIX
+    return '(tag (starts-with "{:s}"))'.format(prefix.replace('"','\\\"'))
 
 def get_tags(prefix=None):
     "Get a list of tags with a given prefix."
-    if prefix is None:
-        prefix = TAG_PREFIX
     (status, stdout, stderr) = _spawn(
-        args=['notmuch', 'search', '--output=tags', '*'],
+        args=['notmuch', 'search', '--query=sexp', '--output=tags', _tag_query(prefix)],
         stdout=_subprocess.PIPE, wait=True)
-    return [tag for tag in stdout.splitlines() if tag.startswith(prefix)]
-
+    return [tag for tag in stdout.splitlines()]
 
 def archive(treeish='HEAD', args=()):
     """
@@ -584,13 +585,12 @@ def get_status():
 def _index_tags():
     "Write notmuch tags to the nmbug.index."
     path = _os.path.join(NOTMUCH_GIT_DIR, 'nmbug.index')
-    query = ' '.join('tag:"{tag}"'.format(tag=tag) for tag in get_tags())
     prefix = '+{0}'.format(_ENCODED_TAG_PREFIX)
     _git(
         args=['read-tree', '--empty'],
         additional_env={'GIT_INDEX_FILE': path}, wait=True)
     with _spawn(
-            args=['notmuch', 'dump', '--format=batch-tag', '--', query],
+            args=['notmuch', 'dump', '--format=batch-tag', '--query=sexp', '--', _tag_query()],
             stdout=_subprocess.PIPE) as notmuch:
         with _git(
                 args=['update-index', '--index-info'],
@@ -690,6 +690,14 @@ def _help(parser, command=None):
     else:
         parser.parse_args(['--help'])
 
+def _notmuch_config_get(key):
+    (status, stdout, stderr) = _spawn(
+        args=['notmuch', 'config', 'get', key],
+        stdout=_subprocess.PIPE, wait=True)
+    if status != 0:
+        _LOG.error("failed to run notmuch config")
+        sys.exit(1)
+    return stdout.rstrip()
 
 if __name__ == '__main__':
     import argparse
@@ -834,6 +842,10 @@ if __name__ == '__main__':
     for var in ['NOTMUCH_GIT_DIR', 'NOTMUCH_GIT_PREFIX', 'NOTMUCH_PROFILE', 'NOTMUCH_CONFIG' ]:
         _LOG.debug('env {:s} = {:s}'.format(var, _os.getenv(var,'%None%')))
 
+    if _notmuch_config_get('built_with.sexp_queries') != 'true':
+        _LOG.error("notmuch git needs sexp query support")
+        sys.exit(1)
+
     if not getattr(args, 'func', None):
         parser.print_usage()
         _sys.exit(1)
index 2badc52dee3f7630fa2a39aed01905a2585cda40..72091b5655db0c0c6a9c48ff09061eee8041d5eb 100755 (executable)
@@ -2,6 +2,11 @@
 test_description='"notmuch git" to save and restore tags'
 . $(dirname "$0")/test-lib.sh || exit 1
 
+if [ $NOTMUCH_HAVE_SFSEXP -ne 1 ]; then
+    printf "Skipping due to missing sfsexp library\n"
+    test_done
+fi
+
 add_email_corpus
 
 git config --global user.email notmuch@example.org
@@ -20,7 +25,6 @@ notmuch search --output=messages '*' | sort > EXPECTED
 test_expect_equal_file_nonempty EXPECTED OUTPUT
 
 test_begin_subtest "commit, with quoted tag"
-test_subtest_known_broken
 notmuch git -C clone2.git -p '' clone tags.git
 git -C clone2.git ls-tree -r --name-only HEAD | grep /inbox > BEFORE
 notmuch tag '+"quoted tag"' '*'