From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp11.migadu.com ([2001:41d0:8:6d80::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms5.migadu.com with LMTPS id eOuQFSiVm2LQTgEAbAwnHQ (envelope-from ) for ; Sat, 04 Jun 2022 19:23:52 +0200 Received: from aspmx1.migadu.com ([2001:41d0:8:6d80::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp11.migadu.com with LMTPS id QMuJFSiVm2Kv9QAA9RJhRA (envelope-from ) for ; Sat, 04 Jun 2022 19:23:52 +0200 Received: from mail.notmuchmail.org (yantan.tethera.net [IPv6:2a01:4f9:c011:7a79::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id BEF951CB6B for ; Sat, 4 Jun 2022 19:23:51 +0200 (CEST) Received: from yantan.tethera.net (localhost [127.0.0.1]) by mail.notmuchmail.org (Postfix) with ESMTP id 658825F7D3; Sat, 4 Jun 2022 17:23:34 +0000 (UTC) Received: from fethera.tethera.net (fethera.tethera.net [198.245.60.197]) by mail.notmuchmail.org (Postfix) with ESMTP id 33F8E5F7C8 for ; Sat, 4 Jun 2022 17:23:32 +0000 (UTC) Received: by fethera.tethera.net (Postfix, from userid 1001) id 861715FC11; Sat, 4 Jun 2022 13:23:31 -0400 (EDT) Received: (nullmailer pid 1150094 invoked by uid 1000); Sat, 04 Jun 2022 17:23:25 -0000 From: David Bremner To: notmuch@notmuchmail.org Subject: [PATCH v3 14/17] CLI/git: change defaults for repo and prefix Date: Sat, 4 Jun 2022 14:23:10 -0300 Message-Id: <20220604172313.1149879-15-david@tethera.net> X-Mailer: git-send-email 2.35.2 In-Reply-To: <20220604172313.1149879-1-david@tethera.net> References: <20220604172313.1149879-1-david@tethera.net> MIME-Version: 1.0 Message-ID-Hash: PZTK6Q6BDIX33QKRAOE2D2PEW25WLUN5 X-Message-ID-Hash: PZTK6Q6BDIX33QKRAOE2D2PEW25WLUN5 X-MailFrom: bremner@tethera.net X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-notmuch.notmuchmail.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.3 Precedence: list List-Id: "Use and development of the notmuch mail system." List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Migadu-Flow: FLOW_IN X-Migadu-To: larch@yhetil.org X-Migadu-Country: DE ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1654363431; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-owner:list-unsubscribe:list-subscribe:list-post; bh=YdbaYrNAaTlV88hr41uxSk3aJLPa/U5Q/Ciq2gmrZDk=; b=f12JJAJzr3EsBbCUpntdY8gGgMTrQVvY44zz2YQY8NyLzPf1P3uBNcwsAfE7fhOeHM7LMX DFumHOKHA8NSt8wMYEieS6YDJewKtThRbOZ7keHfddSgyg8jjCCo+ldBtPaRvYnPfpIvlQ SIKeBaOcNmPu/KEwu4/vKeIhdH9C8ohTAbQyWHhuaxFp4WJeQlOxjT5F1mvrdC50l1iR+Q aQ0SPxXqx7YuRSE5d0yWVcPsTAZ8mF84bAAh+OJihabibn3/tG4eXhUQBJqVEpUMl9PDkK tD5ddcoSXWWYhIi/qmhyM9DVLvSa9QrmdYnFX68Is546hAjMrYOyBVnMDo80hQ== ARC-Seal: i=1; s=key1; d=yhetil.org; t=1654363431; a=rsa-sha256; cv=none; b=AIFvKCSgSVlnivhAvl8r7/fbVJZEWS9xtU/uDUIu+G9Oxwbfr2a36BH6ebz48MwIykdjj1 7GDKvFJQNkzjtX7X+5oYtuXhJP9uK9gdoMenf4DPusoiTtPmUxD42b8y1SM0kIfSgC49UE zQZfFN+79IdujKwgrIoStVxvJWjXfHl8kdFpfUXYgzEP06iiasi4XGECXli+uWnNahzN0J IA71h3hqtvVOr6VxJb6liHfCmdOW9FzZoEQl/FkHeXk2BCdcaOIL7gaKf7ZmAzKvbnYjnL baH97hQl3iuoLb0Y0JVsMXHBf1jwLrKROfOhVPNy2cuqZDeAUluEVHZlh06Nyw== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=none; dmarc=none; spf=pass (aspmx1.migadu.com: domain of notmuch-bounces@notmuchmail.org designates 2a01:4f9:c011:7a79::1 as permitted sender) smtp.mailfrom=notmuch-bounces@notmuchmail.org X-Migadu-Spam-Score: -1.05 Authentication-Results: aspmx1.migadu.com; dkim=none; dmarc=none; spf=pass (aspmx1.migadu.com: domain of notmuch-bounces@notmuchmail.org designates 2a01:4f9:c011:7a79::1 as permitted sender) smtp.mailfrom=notmuch-bounces@notmuchmail.org X-Migadu-Queue-Id: BEF951CB6B X-Spam-Score: -1.05 X-Migadu-Scanner: scn0.migadu.com X-TUID: yXbYNHyZxsM8 The previous defaults were not suitable for personal (i.e. not bugtracking for notmuch development) use. Provide two ways for the user to select nmbug compatible defaults; command line argument and checking the name of the script. --- Makefile.local | 6 ++- doc/Makefile.local | 1 + doc/man1/notmuch-git.rst | 21 +++++++- notmuch-git.py | 62 +++++++++++++++++++---- test/T850-git.sh | 103 +++++++++++++++++++++++++++++++-------- 5 files changed, 162 insertions(+), 31 deletions(-) diff --git a/Makefile.local b/Makefile.local index d2e0c7a8..7699c208 100644 --- a/Makefile.local +++ b/Makefile.local @@ -1,7 +1,7 @@ # -*- makefile-gmake -*- .PHONY: all -all: notmuch notmuch-shared build-man build-info ruby-bindings python-cffi-bindings notmuch-git +all: notmuch notmuch-shared build-man build-info ruby-bindings python-cffi-bindings notmuch-git nmbug ifeq ($(MAKECMDGOALS),) ifeq ($(shell cat .first-build-message 2>/dev/null),) @NOTMUCH_FIRST_BUILD=1 $(MAKE) --no-print-directory all @@ -50,6 +50,10 @@ notmuch-git: notmuch-git.py cp $< $@ chmod ugo+x $@ +CLEAN := $(CLEAN) nmbug +nmbug: notmuch-git + ln -s $< $@ + .PHONY: dist dist: $(TAR_FILE) diff --git a/doc/Makefile.local b/doc/Makefile.local index d43ef269..2f67f4de 100644 --- a/doc/Makefile.local +++ b/doc/Makefile.local @@ -131,6 +131,7 @@ install-man: ${MAN_GZIP_FILES} install -m0644 $(filter %.5.gz,$(MAN_GZIP_FILES)) $(DESTDIR)/$(mandir)/man5 install -m0644 $(filter %.7.gz,$(MAN_GZIP_FILES)) $(DESTDIR)/$(mandir)/man7 cd $(DESTDIR)/$(mandir)/man1 && ln -sf notmuch.1.gz notmuch-setup.1.gz + cd $(DESTDIR)/$(mandir)/man1 && ln -sf notmuch-git.1.gz nmbug.1.gz endif ifneq ($(HAVE_SPHINX)$(HAVE_MAKEINFO),11) diff --git a/doc/man1/notmuch-git.rst b/doc/man1/notmuch-git.rst index 86f246b6..6a2d7fcd 100644 --- a/doc/man1/notmuch-git.rst +++ b/doc/man1/notmuch-git.rst @@ -7,7 +7,9 @@ notmuch-git SYNOPSIS ======== -**notmuch** **git** [-h] [-C *repo*] [-p *prefix*] [-v] [-l *log level*] *subcommand* +**notmuch** **git** [-h] [-N] [-C *repo*] [-p *prefix*] [-v] [-l *log level*] *subcommand* + +**nmbug** [-h] [-C *repo*] [-p *prefix*] [-v] [-l *log level*] *subcommand* DESCRIPTION =========== @@ -25,12 +27,17 @@ Supported options for `notmuch git` include show help message and exit +.. option:: -N, --nmbug + + Set defaults for :option:`--tag-prefix` and :option:`--git-dir` suitable for the + :any:`notmuch` bug tracker + .. option:: -C , --git-dir Operate on git repository *repo*. See :ref:`repo_location` for defaults. -.. option:: -p , --tag-prefix +.. option:: -p , --tag-prefix Operate only on tags with prefix *prefix*. See :ref:`prefix_val` for defaults. @@ -239,6 +246,10 @@ value to locate the git repository. - Environment variable :envvar:`NOTMUCH_GIT_DIR`. +- If invoked as `nmbug` or with the :option:`--nmbug` option, + :code:`$HOME/.nmbug`; otherwise + :code:`$XDG_DATA_HOME/notmuch/$NOTMUCH_PROFILE/git`. + .. _prefix_val: PREFIX VALUE @@ -251,9 +262,15 @@ value to define the tag prefix. - Environment variable :envvar:`NOTMUCH_GIT_PREFIX`. +- If invoked as `nmbug` or with the :option:`--nmbug` option, + :code:`notmuch::`, otherwise the empty string. + ENVIRONMENT =========== +Variable :envvar:`NOTMUCH_PROFILE` influences :ref:`repo_location`. +If it is unset, 'default' is assumed. + .. envvar:: NOTMUCH_GIT_DIR Default location of git repository. Overriden by :option:`--git-dir`. diff --git a/notmuch-git.py b/notmuch-git.py index e419cdf7..9d5c7876 100644 --- a/notmuch-git.py +++ b/notmuch-git.py @@ -425,6 +425,13 @@ def init(remote=None): This wraps 'git init' with a few extra steps to support subsequent status and commit commands. """ + from pathlib import Path + parent = Path(NOTMUCH_GIT_DIR).parent + try: + _os.makedirs(parent) + except FileExistsError: + pass + _spawn(args=['git', '--git-dir', NOTMUCH_GIT_DIR, 'init', '--initial-branch=master', '--quiet', '--bare'], wait=True) _git(args=['config', 'core.logallrefupdates', 'true'], wait=True) @@ -861,9 +868,19 @@ def _notmuch_config_get(key): stdout=_subprocess.PIPE, wait=True) if status != 0: _LOG.error("failed to run notmuch config") - sys.exit(1) + _sys.exit(1) return stdout.rstrip() +# based on BaseDirectory.save_data_path from pyxdg (LGPL2+) +def xdg_data_path(profile): + resource = _os.path.join('notmuch',profile,'git') + assert not resource.startswith('/') + _home = _os.path.expanduser('~') + xdg_data_home = _os.environ.get('XDG_DATA_HOME') or \ + _os.path.join(_home, '.local', 'share') + path = _os.path.join(xdg_data_home, resource) + return path + if __name__ == '__main__': import argparse @@ -875,8 +892,11 @@ if __name__ == '__main__': help='Git repository to operate on.') parser.add_argument( '-p', '--tag-prefix', metavar='PREFIX', - default = _os.getenv('NOTMUCH_GIT_PREFIX', 'notmuch::'), + default = None, help='Prefix of tags to operate on.') + parser.add_argument( + '-N', '--nmbug', action='store_true', + help='Set defaults for --tag-prefix and --git-dir for the notmuch bug tracker') parser.add_argument( '-l', '--log-level', choices=['critical', 'error', 'warning', 'info', 'debug'], @@ -987,16 +1007,36 @@ if __name__ == '__main__': args = parser.parse_args() + nmbug_mode = False + notmuch_profile = _os.getenv('NOTMUCH_PROFILE','default') + + if args.nmbug or _os.path.basename(__file__) == 'nmbug': + nmbug_mode = True + if args.git_dir: NOTMUCH_GIT_DIR = args.git_dir else: - NOTMUCH_GIT_DIR = _os.path.expanduser( - _os.getenv('NOTMUCH_GIT_DIR', _os.path.join('~', '.nmbug'))) - _NOTMUCH_GIT_DIR = _os.path.join(NOTMUCH_GIT_DIR, '.git') - if _os.path.isdir(_NOTMUCH_GIT_DIR): - NOTMUCH_GIT_DIR = _NOTMUCH_GIT_DIR + if nmbug_mode: + default = _os.path.join('~', '.nmbug') + else: + default = xdg_data_path(notmuch_profile) + + NOTMUCH_GIT_DIR = _os.path.expanduser(_os.getenv('NOTMUCH_GIT_DIR', default)) + + _NOTMUCH_GIT_DIR = _os.path.join(NOTMUCH_GIT_DIR, '.git') + if _os.path.isdir(_NOTMUCH_GIT_DIR): + NOTMUCH_GIT_DIR = _NOTMUCH_GIT_DIR + + if args.tag_prefix: + TAG_PREFIX = args.tag_prefix + else: + if nmbug_mode: + prefix = 'notmuch::' + else: + prefix = '' + + TAG_PREFIX = _os.getenv('NOTMUCH_GIT_PREFIX', prefix) - TAG_PREFIX = args.tag_prefix _ENCODED_TAG_PREFIX = _hex_quote(TAG_PREFIX, safe='+@=,') # quote ':' if args.log_level: @@ -1009,12 +1049,16 @@ if __name__ == '__main__': if _notmuch_config_get('built_with.sexp_queries') != 'true': _LOG.error("notmuch git needs sexp query support") - sys.exit(1) + _sys.exit(1) if not getattr(args, 'func', None): parser.print_usage() _sys.exit(1) + # The following two lines are used by the test suite. + _LOG.debug('prefix = {:s}'.format(TAG_PREFIX)) + _LOG.debug('repository = {:s}'.format(NOTMUCH_GIT_DIR)) + if args.func == help: arg_names = ['command'] else: diff --git a/test/T850-git.sh b/test/T850-git.sh index db76dae9..98233055 100755 --- a/test/T850-git.sh +++ b/test/T850-git.sh @@ -19,28 +19,28 @@ test_begin_subtest "clone" test_expect_success "notmuch git -p '' -C tags.git clone remote.git" test_begin_subtest "commit" -notmuch git -C tags.git -p '' commit +notmuch git -C tags.git commit git -C tags.git ls-tree -r --name-only HEAD | xargs dirname | sort -u | sed s,tags/,id:, > OUTPUT notmuch search --output=messages '*' | sort > EXPECTED test_expect_equal_file_nonempty EXPECTED OUTPUT test_begin_subtest "commit, with quoted tag" -notmuch git -C clone2.git -p '' clone tags.git +notmuch git -C clone2.git clone tags.git git -C clone2.git ls-tree -r --name-only HEAD | grep /inbox > BEFORE notmuch tag '+"quoted tag"' '*' -notmuch git -C clone2.git -p '' commit +notmuch git -C clone2.git commit notmuch tag '-"quoted tag"' '*' git -C clone2.git ls-tree -r --name-only HEAD | grep /inbox > AFTER test_expect_equal_file_nonempty BEFORE AFTER test_begin_subtest "commit (incremental)" notmuch tag +test id:20091117190054.GU3165@dottiness.seas.harvard.edu -notmuch git -C tags.git -p '' commit +notmuch git -C tags.git commit git -C tags.git ls-tree -r --name-only HEAD | grep 20091117190054 | sort > OUTPUT echo "--------------------------------------------------" >> OUTPUT notmuch tag -test id:20091117190054.GU3165@dottiness.seas.harvard.edu -notmuch git -C tags.git -p '' commit +notmuch git -C tags.git commit git -C tags.git ls-tree -r --name-only HEAD | grep 20091117190054 | sort >> OUTPUT cat < EXPECTED @@ -62,7 +62,7 @@ git -C tags.git ls-tree -r --name-only HEAD | grep 20091117190054 | sort > OUTPUT echo "--------------------------------------------------" >> OUTPUT notmuch tag -test::one id:20091117190054.GU3165@dottiness.seas.harvard.edu -notmuch git -C tags.git -p '' commit +notmuch git -C tags.git commit git -C tags.git ls-tree -r --name-only HEAD | grep 20091117190054 | sort >> OUTPUT cat < EXPECTED @@ -77,12 +77,12 @@ test_expect_equal_file_nonempty EXPECTED OUTPUT test_begin_subtest "checkout" notmuch dump > BEFORE notmuch tag -inbox '*' -notmuch git -C tags.git -p '' checkout +notmuch git -C tags.git checkout notmuch dump > AFTER test_expect_equal_file_nonempty BEFORE AFTER test_begin_subtest "archive" -notmuch git -C tags.git -p '' archive | tar tf - | \ +notmuch git -C tags.git archive | tar tf - | \ grep 20091117190054.GU3165@dottiness.seas.harvard.edu | sort > OUTPUT cat < EXPECTED tags/20091117190054.GU3165@dottiness.seas.harvard.edu/ @@ -90,32 +90,32 @@ tags/20091117190054.GU3165@dottiness.seas.harvard.edu/inbox tags/20091117190054.GU3165@dottiness.seas.harvard.edu/signed tags/20091117190054.GU3165@dottiness.seas.harvard.edu/unread EOF -notmuch git -C tags.git -p '' checkout +notmuch git -C tags.git checkout test_expect_equal_file EXPECTED OUTPUT test_begin_subtest "status" notmuch tag +test id:20091117190054.GU3165@dottiness.seas.harvard.edu -notmuch git -C tags.git -p '' status > OUTPUT +notmuch git -C tags.git status > OUTPUT cat < EXPECTED A 20091117190054.GU3165@dottiness.seas.harvard.edu test EOF -notmuch git -C tags.git -p '' checkout +notmuch git -C tags.git checkout test_expect_equal_file EXPECTED OUTPUT test_begin_subtest "fetch" notmuch tag +test2 id:20091117190054.GU3165@dottiness.seas.harvard.edu -notmuch git -C remote.git -p '' commit +notmuch git -C remote.git commit notmuch tag -test2 id:20091117190054.GU3165@dottiness.seas.harvard.edu -notmuch git -C tags.git -p '' fetch -notmuch git -C tags.git -p '' status > OUTPUT +notmuch git -C tags.git fetch +notmuch git -C tags.git status > OUTPUT cat < EXPECTED a 20091117190054.GU3165@dottiness.seas.harvard.edu test2 EOF -notmuch git -C tags.git -p '' checkout +notmuch git -C tags.git checkout test_expect_equal_file EXPECTED OUTPUT test_begin_subtest "merge" -notmuch git -C tags.git -p '' merge +notmuch git -C tags.git merge notmuch dump id:20091117190054.GU3165@dottiness.seas.harvard.edu | grep -v '^#' > OUTPUT cat < EXPECTED +inbox +signed +test2 +unread -- id:20091117190054.GU3165@dottiness.seas.harvard.edu @@ -124,10 +124,10 @@ test_expect_equal_file EXPECTED OUTPUT test_begin_subtest "push" notmuch tag +test3 id:20091117190054.GU3165@dottiness.seas.harvard.edu -notmuch git -C tags.git -p '' commit +notmuch git -C tags.git commit notmuch tag -test3 id:20091117190054.GU3165@dottiness.seas.harvard.edu -notmuch git -C tags.git -p '' push -notmuch git -C remote.git -p '' checkout +notmuch git -C tags.git push +notmuch git -C remote.git checkout notmuch dump id:20091117190054.GU3165@dottiness.seas.harvard.edu | grep -v '^#' > OUTPUT cat < EXPECTED +inbox +signed +test2 +test3 +unread -- id:20091117190054.GU3165@dottiness.seas.harvard.edu @@ -145,4 +145,69 @@ env NOTMUCH_CONFIG = CWD/notmuch-config EOF test_expect_equal_file EXPECTED OUTPUT +test_begin_subtest "--nmbug argument sets defaults" +notmuch git -ldebug --nmbug status |& grep '^\(prefix\|repository\)' | notmuch_dir_sanitize > OUTPUT +cat < EXPECTED +prefix = notmuch:: +repository = CWD/home/.nmbug +EOF +test_expect_equal_file EXPECTED OUTPUT + +test_begin_subtest "invoke as nmbug sets defaults" +"$NOTMUCH_BUILDDIR"/nmbug -ldebug status |& grep '^\(prefix\|repository\)' | notmuch_dir_sanitize > OUTPUT +cat < EXPECTED +prefix = notmuch:: +repository = CWD/home/.nmbug +EOF +test_expect_equal_file EXPECTED OUTPUT + +test_begin_subtest "env variable NOTMUCH_GIT_DIR works when invoked as nmbug" +NOTMUCH_GIT_DIR=`pwd`/foo "$NOTMUCH_BUILDDIR"/nmbug -ldebug status |& grep '^repository' | notmuch_dir_sanitize > OUTPUT +cat < EXPECTED +repository = CWD/foo +EOF +test_expect_equal_file EXPECTED OUTPUT + +test_begin_subtest "env variable NOTMUCH_GIT_DIR works when invoked as 'notmuch git'" +NOTMUCH_GIT_DIR=`pwd`/remote.git notmuch git -ldebug status |& grep '^repository' | notmuch_dir_sanitize > OUTPUT +cat < EXPECTED +repository = CWD/remote.git +EOF +test_expect_equal_file EXPECTED OUTPUT + +test_begin_subtest "env variable NOTMUCH_GIT_PREFIX works when invoked as nmbug" +NOTMUCH_GIT_PREFIX=foo:: "$NOTMUCH_BUILDDIR"/nmbug -ldebug status |& grep '^prefix' | notmuch_dir_sanitize > OUTPUT +cat < EXPECTED +prefix = foo:: +EOF +test_expect_equal_file EXPECTED OUTPUT + +test_begin_subtest "env variable NOTMUCH_GIT_PREFIX works when invoked as 'notmuch git'" +NOTMUCH_GIT_PREFIX=env:: notmuch git -ldebug status |& grep '^prefix' | notmuch_dir_sanitize > OUTPUT +cat < EXPECTED +prefix = env:: +EOF +test_expect_equal_file EXPECTED OUTPUT + + +test_begin_subtest "init, xdg default location" +repo=home/.local/share/notmuch/default/git +notmuch git -ldebug init |& grep '^repository' | notmuch_dir_sanitize > OUTPUT +git -C $repo rev-parse --absolute-git-dir | notmuch_dir_sanitize >> OUTPUT +cat < EXPECTED +repository = CWD/$repo +CWD/$repo +EOF +test_expect_equal_file EXPECTED OUTPUT + +test_begin_subtest "init, xdg default location, with profile" +repo=home/.local/share/notmuch/work/git +NOTMUCH_PROFILE=work notmuch git -ldebug init |& grep '^repository' | notmuch_dir_sanitize > OUTPUT +git -C $repo rev-parse --absolute-git-dir | notmuch_dir_sanitize >> OUTPUT +cat < EXPECTED +repository = CWD/$repo +CWD/$repo +EOF +test_expect_equal_file EXPECTED OUTPUT + test_done -- 2.35.2