~andir/nixpkgs-dev

nixpkgs-ml-tools: Argument parsing, git-am and fuzzy support v1 PROPOSED

Hi.

CCing Leon here because he actually made me look at the mail from William [0]
(also in CC) with this awesome piece of bash. I saw that and started to think
that this could be done better (sorry William! :D).

So I poured myself a glas of 10 year old and started hacking away.  And here I
am, with a patchset for the notmuch-am script.

So each patch in this set builds on the previous one. The first one implements
proper argument parsing using argbash.io (an awesome tool you should
definitively check out). After that, I added options to call git-am right from
the notmuch-am script. We could debate over whether that's what we want to do
_in_ the script or not... I'd understand if calling git-am after the tool like

    notmuch am | git am

would be preffered by you guys!

Anyways, options for calling git-am with -3 and -s (--signoff) are added - I
think these are the most common arguments for git-am.

The last patch is a bit of an experiment making use of the piece of bash script
William posted in [0] - it expands on the idea by adding a --preview script for
fzf, which (currently) gives you the subjects of the individual mails in the
thread.

I tested it a bit and it seems to work - careful review (of not only the last
but all patches in here) and testing is very much welcome!

Tell me what you think!


[0]: https://lists.sr.ht/~andir/nixpkgs-dev/%3C20210326195603.29471-1-ben%40bsima.me%3E#%3C20210330174358.xpeayvf7dbbrshdn@monad%3E

Matthias Beyer (5):
  Use argbash to generate CLI framework
  Add support for calling git-am right away
  Add support for calling git-am with -3
  Add support for calling git-am with -s
  Add fuzzy-patch-thread-selecting

 notmuch-am | 156 ++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 148 insertions(+), 8 deletions(-)

-- 
2.29.3
And as always, I see the issue _after_ sending the patchset.

On 01-04-2021 20:39:46, Matthias Beyer wrote:
Next
Hey Matthias,

Just a few comments inline.

On Thu, Apr 01, 2021 at 08:39:49PM +0200, Matthias Beyer wrote:
Next
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.sr.ht/~andir/nixpkgs-dev/patches/21718/mbox | git am -3
Learn more about email & git
View this thread in the archives

[PATCH nixpkgs-ml-tools v1 1/5] Use argbash to generate CLI framework Export this patch

Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
Tested-by: Matthias Beyer <mail@beyermatthias.de>
---
 notmuch-am | 102 +++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 95 insertions(+), 7 deletions(-)

diff --git a/notmuch-am b/notmuch-am
index fb299be..cf7e1ee 100755
--- a/notmuch-am
+++ b/notmuch-am
@@ -1,12 +1,39 @@
#!/usr/bin/env bash

B4AM_ARGS=${B4AM_ARGS:-"--add-link"}
# ###
#
# Generated by argbash.io
#
# ###

usage () {
    printf %s "\
Usage: notmuch-am <thread-id>
die()
{
    local _ret="${2:-1}"
    test "${_PRINT_HELP:-no}" = yes && print_help >&2
    echo "$1" >&2
    exit "${_ret}"
}


begins_with_short_option()
{
    local first_option all_short_options='h'
    first_option="${1:0:1}"
    test "$all_short_options" = "${all_short_options/$first_option/}" && return 1 || return 0
}

Use b4 to apply a patchset from a thread.
# THE DEFAULTS INITIALIZATION - POSITIONALS
_positionals=()
# THE DEFAULTS INITIALIZATION - OPTIONALS


print_help()
{
    printf '%s\n' "Use b4 to apply a patchset from a thread."
    printf 'Usage: %s [-h|--help] <thread-id>\n' "$0"
    printf '\t%s\n' "<thread-id>: The notmuch thread id of the thread to apply"
    printf '\t%s\n' "-h, --help: Prints help"
    printf %s "\

Example

@@ -18,8 +45,68 @@ Example
      + Reviewed-by: Xinglu Chen <public@yoctocell.xyz> (✓ DKIM/yoctocell.xyz)
      + Reviewed-by: Matthias Beyer <mail@beyermatthias.de>
"
exit 0
}
parse_commandline()
{
    _positionals_count=0
    while test $# -gt 0
    do
        _key="$1"
        case "$_key" in
            -h|--help)
                print_help
                exit 0
                ;;
            -h*)
                print_help
                exit 0
                ;;
            *)
                _last_positional="$1"
                _positionals+=("$_last_positional")
                _positionals_count=$((_positionals_count + 1))
                ;;
        esac
        shift
    done
}


handle_passed_args_count()
{
    local _required_args_string="'thread-id'"
    test "${_positionals_count}" -ge 1 || _PRINT_HELP=yes die "FATAL ERROR: Not enough positional arguments - we require exactly 1 (namely: $_required_args_string), but got only ${_positionals_count}." 1
    test "${_positionals_count}" -le 1 || _PRINT_HELP=yes die "FATAL ERROR: There were spurious positional arguments --- we expect exactly 1 (namely: $_required_args_string), but got ${_positionals_count} (the last one was: '${_last_positional}')." 1
}


assign_positional_args()
{
    local _positional_name _shift_for=$1
    _positional_names="_arg_thread_id "

    shift "$_shift_for"
    for _positional_name in ${_positional_names}
    do
        test $# -gt 0 || break
        eval "$_positional_name=\${1}" || die "Error during argument parsing, possibly an Argbash bug." 1
        shift
    done
}

parse_commandline "$@"
handle_passed_args_count
assign_positional_args 1 "${_positionals[@]}"

# ###
#
# / Generated by argbash.io
#
# ###



B4AM_ARGS=${B4AM_ARGS:-"--add-link"}

main () {
    mbox=$(mktemp)
@@ -29,4 +116,5 @@ main () {
    rm -f "$mbox"
}

[ -n "$1" ] || usage && main "$@"
[ -n "$1" ] || usage && main "$_arg_thread_id"

-- 
2.29.3

[PATCH nixpkgs-ml-tools v1 2/5] Add support for calling git-am right away Export this patch

Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
Tested-by: Matthias Beyer <mail@beyermatthias.de>
---
 notmuch-am | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/notmuch-am b/notmuch-am
index cf7e1ee..f2da66a 100755
--- a/notmuch-am
+++ b/notmuch-am
@@ -25,13 +25,15 @@ begins_with_short_option()
# THE DEFAULTS INITIALIZATION - POSITIONALS
_positionals=()
# THE DEFAULTS INITIALIZATION - OPTIONALS
_arg_am="off"


print_help()
{
    printf '%s\n' "Use b4 to apply a patchset from a thread."
    printf 'Usage: %s [-h|--help] <thread-id>\n' "$0"
    printf 'Usage: %s [-h|--help] [--(no-)am] <thread-id>\n' "$0"
    printf '\t%s\n' "<thread-id>: The notmuch thread id of the thread to apply"
    printf '\t%s\n' "--am, --no-am: Call git-am instead of generating a mbox file (off by default)"
    printf '\t%s\n' "-h, --help: Prints help"
    printf %s "\

@@ -61,6 +63,10 @@ parse_commandline()
                print_help
                exit 0
                ;;
            --no-am|--am)
                _arg_am="on"
                test "${1:0:5}" = "--no-" && _arg_am="off"
                ;;
            *)
                _last_positional="$1"
                _positionals+=("$_last_positional")
@@ -112,7 +118,13 @@ main () {
    mbox=$(mktemp)
    notmuch show --format=mbox "$1" > "$mbox"
    msgid=$(grep -i ^message-id "$mbox" | cut -d" " -f2 | head -n1)
    b4 am "$B4AM_ARGS" "$msgid" -m "$mbox"

    if [[ "$_arg_am" == "on" ]]; then
        b4 am "msgid" -m "$mbox" -o - | git am
    else
        b4 am "$B4AM_ARGS" "$msgid" -m "$mbox"
    fi

    rm -f "$mbox"
}

-- 
2.29.3
And as always, I see the issue _after_ sending the patchset.

On 01-04-2021 20:39:46, Matthias Beyer wrote:

[PATCH nixpkgs-ml-tools v1 3/5] Add support for calling git-am with -3 Export this patch

Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
Tested-by: Matthias Beyer <mail@beyermatthias.de>
---
 notmuch-am | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/notmuch-am b/notmuch-am
index f2da66a..85275f1 100755
--- a/notmuch-am
+++ b/notmuch-am
@@ -26,6 +26,7 @@ begins_with_short_option()
_positionals=()
# THE DEFAULTS INITIALIZATION - OPTIONALS
_arg_am="off"
_arg_3="off"


print_help()
@@ -34,6 +35,7 @@ print_help()
    printf 'Usage: %s [-h|--help] [--(no-)am] <thread-id>\n' "$0"
    printf '\t%s\n' "<thread-id>: The notmuch thread id of the thread to apply"
    printf '\t%s\n' "--am, --no-am: Call git-am instead of generating a mbox file (off by default)"
    printf '\t%s\n' "-3: Call git-am with -3 (off by default, only effective with --am)"
    printf '\t%s\n' "-h, --help: Prints help"
    printf %s "\

@@ -67,6 +69,9 @@ parse_commandline()
                _arg_am="on"
                test "${1:0:5}" = "--no-" && _arg_am="off"
                ;;
            -3)
                _arg_3="on"
                ;;
            *)
                _last_positional="$1"
                _positionals+=("$_last_positional")
@@ -120,7 +125,12 @@ main () {
    msgid=$(grep -i ^message-id "$mbox" | cut -d" " -f2 | head -n1)

    if [[ "$_arg_am" == "on" ]]; then
        b4 am "msgid" -m "$mbox" -o - | git am
        AM_ARGS=""
        if [[ "$_arg_3" == "on" ]]; then
            AM_ARGS="-3"
        fi

        b4 am "$msgid" -m "$mbox" -o - | git am $AM_ARGS
    else
        b4 am "$B4AM_ARGS" "$msgid" -m "$mbox"
    fi
-- 
2.29.3

[PATCH nixpkgs-ml-tools v1 4/5] Add support for calling git-am with -s Export this patch

Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
---
 notmuch-am | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/notmuch-am b/notmuch-am
index 85275f1..2da1a17 100755
--- a/notmuch-am
+++ b/notmuch-am
@@ -27,6 +27,7 @@ _positionals=()
# THE DEFAULTS INITIALIZATION - OPTIONALS
_arg_am="off"
_arg_3="off"
_arg_amsignoff="off"


print_help()
@@ -36,6 +37,7 @@ print_help()
    printf '\t%s\n' "<thread-id>: The notmuch thread id of the thread to apply"
    printf '\t%s\n' "--am, --no-am: Call git-am instead of generating a mbox file (off by default)"
    printf '\t%s\n' "-3: Call git-am with -3 (off by default, only effective with --am)"
    printf '\t%s\n' "-s, --signoff: Call git-am with --signoff (off by default, only effective with --am)"
    printf '\t%s\n' "-h, --help: Prints help"
    printf %s "\

@@ -72,6 +74,9 @@ parse_commandline()
            -3)
                _arg_3="on"
                ;;
            -s|--signoff)
                _arg_amsignoff="on"
                ;;
            *)
                _last_positional="$1"
                _positionals+=("$_last_positional")
@@ -129,6 +134,9 @@ main () {
        if [[ "$_arg_3" == "on" ]]; then
            AM_ARGS="-3"
        fi
        if [[ "$_arg_amsignoff" == "on" ]]; then
            AM_ARGS+=" --signoff"
        fi

        b4 am "$msgid" -m "$mbox" -o - | git am $AM_ARGS
    else
-- 
2.29.3

[PATCH nixpkgs-ml-tools v1 5/5] Add fuzzy-patch-thread-selecting Export this patch

Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
Tested-by: Matthias Beyer <mail@beyermatthias.de>
---
 notmuch-am | 28 +++++++++++++++++++++++++---
 1 file changed, 25 insertions(+), 3 deletions(-)

diff --git a/notmuch-am b/notmuch-am
index 2da1a17..9e7470e 100755
--- a/notmuch-am
+++ b/notmuch-am
@@ -28,6 +28,7 @@ _positionals=()
_arg_am="off"
_arg_3="off"
_arg_amsignoff="off"
_arg_fuzzy="off"


print_help()
@@ -38,6 +39,7 @@ print_help()
    printf '\t%s\n' "--am, --no-am: Call git-am instead of generating a mbox file (off by default)"
    printf '\t%s\n' "-3: Call git-am with -3 (off by default, only effective with --am)"
    printf '\t%s\n' "-s, --signoff: Call git-am with --signoff (off by default, only effective with --am)"
    printf '\t%s\n' "--fuzzy: Use fzf to interactively select the thread for the patchset to apply"
    printf '\t%s\n' "-h, --help: Prints help"
    printf %s "\

@@ -77,6 +79,9 @@ parse_commandline()
            -s|--signoff)
                _arg_amsignoff="on"
                ;;
            --fuzzy)
                _arg_fuzzy="on"
                ;;
            *)
                _last_positional="$1"
                _positionals+=("$_last_positional")
@@ -91,8 +96,12 @@ parse_commandline()
handle_passed_args_count()
{
    local _required_args_string="'thread-id'"
    test "${_positionals_count}" -ge 1 || _PRINT_HELP=yes die "FATAL ERROR: Not enough positional arguments - we require exactly 1 (namely: $_required_args_string), but got only ${_positionals_count}." 1
    test "${_positionals_count}" -le 1 || _PRINT_HELP=yes die "FATAL ERROR: There were spurious positional arguments --- we expect exactly 1 (namely: $_required_args_string), but got ${_positionals_count} (the last one was: '${_last_positional}')." 1
    if [[ "${_positionals_count}" -ge 1 ]] && [[ "$_arg_fuzzy" == "off" ]]; then
        _PRINT_HELP=yes die "FATAL ERROR: Not enough positional arguments - we require exactly 1 (namely: $_required_args_string), but got only ${_positionals_count}." 1
    fi
    if [[ "${_positionals_count}" -le 1 ]] && [[ "$_arg_fuzzy" == "off" ]]; then
        _PRINT_HELP=yes die "FATAL ERROR: There were spurious positional arguments --- we expect exactly 1 (namely: $_required_args_string), but got ${_positionals_count} (the last one was: '${_last_positional}')." 1
    fi
}


@@ -146,5 +155,18 @@ main () {
    rm -f "$mbox"
}

[ -n "$1" ] || usage && main "$_arg_thread_id"
thread_id="$_arg_thread_id"

if [[ "$_arg_fuzzy" == "on" ]]; then
    preview_script='echo {} | sed "s,\t.*,,; s,^,thread:," | xargs notmuch search --output=files --format=text | xargs grep -ihE "^Subject" | sort'

    local user_email="$(git config user.email)"

    thread_id=$(notmuch search --output=summary --format=json "to:$user_email" and subject:PATCH | \
        jq -rcC '.[] | [.thread,.date_relative,.subject,.authors] | @tsv' | \
        fzf -m --preview "$preview_script" | \
        sed 's,\t.*,,; s,^,thread:,')
fi

[ -n "$1" ] || usage && main "$thread_id"

-- 
2.29.3
Hey Matthias,

Just a few comments inline.

On Thu, Apr 01, 2021 at 08:39:49PM +0200, Matthias Beyer wrote: