]> git.notmuchmail.org Git - notmuch/blobdiff - devel/nmbug/nmbug
test/T391-python-cffi
[notmuch] / devel / nmbug / nmbug
index 932ec12d41b9245387e89bc3ca0810f05251ad18..043c186369c1f55fce114b230746f138d7bc2345 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 #
 # Copyright (c) 2011-2014 David Bremner <david@tethera.net>
 #                         W. Trevor King <wking@tremily.us>
@@ -14,7 +14,7 @@
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program.  If not, see http://www.gnu.org/licenses/ .
+# along with this program.  If not, see https://www.gnu.org/licenses/ .
 
 """
 Manage notmuch tags with Git
@@ -51,10 +51,10 @@ except ImportError:  # Python 2
     from urllib import unquote as _unquote
 
 
-__version__ = '0.2'
+__version__ = '0.3'
 
 _LOG = _logging.getLogger('nmbug')
-_LOG.setLevel(_logging.ERROR)
+_LOG.setLevel(_logging.WARNING)
 _LOG.addHandler(_logging.StreamHandler())
 
 NMBGIT = _os.path.expanduser(
@@ -65,7 +65,8 @@ if _os.path.isdir(_NMBGIT):
 
 TAG_PREFIX = _os.getenv('NMBPREFIX', 'notmuch::')
 _HEX_ESCAPE_REGEX = _re.compile('%[0-9A-F]{2}')
-_TAG_FILE_REGEX = _re.compile('tags/(?P<id>[^/]*)/(?P<tag>[^/]*)')
+_TAG_DIRECTORY = 'tags/'
+_TAG_FILE_REGEX = _re.compile(_TAG_DIRECTORY + '(?P<id>[^/]*)/(?P<tag>[^/]*)')
 
 # magic hash for Git (git hash-object -t blob /dev/null)
 _EMPTYBLOB = 'e69de29bb2d1d6434b8b29ae775ad8c2e48c5391'
@@ -80,7 +81,7 @@ except AttributeError:  # Python < 3.2
 
         See PEP 343 for details on context managers [1].
 
-        [1]: http://legacy.python.org/dev/peps/pep-0343/
+        [1]: https://www.python.org/dev/peps/pep-0343/
         """
         def __init__(self, **kwargs):
             self.name = _tempfile.mkdtemp(**kwargs)
@@ -119,9 +120,9 @@ def _xapian_quote(string):
     Xapian uses double-quotes for quoting strings.  You can escape
     internal quotes by repeating them [1,2,3].
 
-    [1]: http://trac.xapian.org/ticket/128#comment:2
-    [2]: http://trac.xapian.org/ticket/128#comment:17
-    [3]: http://trac.xapian.org/changeset/13823/svn
+    [1]: https://trac.xapian.org/ticket/128#comment:2
+    [2]: https://trac.xapian.org/ticket/128#comment:17
+    [3]: https://trac.xapian.org/changeset/13823/svn
     """
     return '"{0}"'.format(string.replace('"', '""'))
 
@@ -169,8 +170,9 @@ class _SubprocessContextManager(object):
                 stream.close()
                 setattr(self._process, name, None)
         status = self._process.wait()
-        _LOG.debug('collect {args} with status {status}'.format(
-            args=self._args, status=status))
+        _LOG.debug(
+            'collect {args} with status {status} (expected {expect})'.format(
+                args=self._args, status=status, expect=self._expect))
         if status not in self._expect:
             raise SubprocessError(args=self._args, status=status)
 
@@ -211,13 +213,14 @@ def _spawn(args, input=None, additional_env=None, wait=False, stdin=None,
             input = input.encode(encoding)
         (stdout, stderr) = p.communicate(input=input)
         status = p.wait()
-        _LOG.debug('collect {args} with status {status}'.format(
-            args=args, status=status))
+        _LOG.debug(
+            'collect {args} with status {status} (expected {expect})'.format(
+                args=args, status=status, expect=expect))
         if stdout is not None:
             stdout = stdout.decode(encoding)
         if stderr is not None:
             stderr = stderr.decode(encoding)
-        if status:
+        if status not in expect:
             raise SubprocessError(
                 args=args, status=status, stdout=stdout, stderr=stderr)
         return (status, stdout, stderr)
@@ -306,8 +309,16 @@ def clone(repository):
                 'git', 'clone', '--no-checkout', '--separate-git-dir', NMBGIT,
                 repository, workdir],
             wait=True)
-    _git(args=['config', '--unset', 'core.worktree'], wait=True)
+    _git(args=['config', '--unset', 'core.worktree'], wait=True, expect=(0, 5))
     _git(args=['config', 'core.bare', 'true'], wait=True)
+    _git(args=['branch', 'config', 'origin/config'], wait=True)
+    existing_tags = get_tags()
+    if existing_tags:
+        _LOG.warning(
+            'Not checking out to avoid clobbering existing tags: {}'.format(
+            ', '.join(existing_tags)))
+    else:
+        checkout()
 
 
 def _is_committed(status):
@@ -474,7 +485,7 @@ def log(args=()):
     'nmbug log HEAD..@{upstream}'.
     """
     # we don't want output trapping here, because we want the pager.
-    args = ['log', '--name-status'] + list(args)
+    args = ['log', '--name-status', '--no-renames'] + list(args)
     with _git(args=args, expect=(0, 1, -13)) as p:
         p.wait()
 
@@ -607,6 +618,8 @@ def _index_tags():
                 stdin=_subprocess.PIPE,
                 additional_env={'GIT_INDEX_FILE': path}) as git:
             for line in notmuch.stdout:
+                if line.strip().startswith('#'):
+                    continue
                 (tags_string, id) = [_.strip() for _ in line.split(' -- id:')]
                 tags = [
                     _unquote(tag[len(prefix):])
@@ -671,8 +684,11 @@ def _unpack_diff_lines(stream):
     for line in stream:
         match = _TAG_FILE_REGEX.match(line.strip())
         if not match:
-            raise ValueError(
-                'Invalid line in diff: {!r}'.format(line.strip()))
+            message = 'non-tag line in diff: {!r}'.format(line.strip())
+            if line.startswith(_TAG_DIRECTORY):
+                raise ValueError(message)
+            _LOG.info(message)
+            continue
         id = _unquote(match.group('id'))
         tag = _unquote(match.group('tag'))
         yield (id, tag)