On Sun, 23 Oct 2016, Mark Walters <markwalters1009@gmail.com> wrote: > On Sat, 22 Oct 2016, Jani Nikula <jani@nikula.org> wrote: >> If the given subcommand is not known to notmuch, try to execute >> external notmuch-<subcommand> instead. This allows users to have their >> own notmuch related tools be run via the notmuch command, not unlike >> git does. Also notmuch-emacs-mua will be executable via 'notmuch >> emacs-mua'. >> >> By design, this does not allow notmuch's own subcommands to be >> overriden using external commands. FWIW this is the same as in git. >> >> --- >> >> Whether internal subcommands can be overridden or not is up to debate, >> can be consider either a bug or a feature depending on how you look at >> it. > > This looks good to me +1 (note my C is not great, and I haven't tested > yet). It took me a while to realise that a nice feature of this was that > we can have some commands in languages other than C, like the emacs-mua > command in the next patch. That's mentioned right there in the commit message, you are into reading such things. ;) > My only query is whether we are setting ourselves up to annoy people if > we add official commands later. For example if we add a notmuch delete > command then it could break a user's setup if they have a notmuch-delete > command. Would it be worth saying that we guarantee some namespace such > as local-* (so commands called notmuch-local-*) won't be touched? I wouldn't worry about it. I'm inclined to say that's the risk people have to take when they add their own notmuch-stuff. We could guarantee we don't touch some namespace, but making things easier is part of the point here. I don't think people are going to name their subcommands notmuch-local-stuff just to avoid potential problems later. BR, Jani. > > Best wishes > > Mark > > > > >> --- >> notmuch.c | 39 +++++++++++++++++++++++++++++++++++++-- >> 1 file changed, 37 insertions(+), 2 deletions(-) >> >> diff --git a/notmuch.c b/notmuch.c >> index 38b73c1d2acc..b9c320329dd5 100644 >> --- a/notmuch.c >> +++ b/notmuch.c >> @@ -363,6 +363,39 @@ notmuch_command (notmuch_config_t *config, >> return EXIT_SUCCESS; >> } >> >> +/* >> + * Try to run subcommand in argv[0] as notmuch- prefixed external >> + * command. argv must be NULL terminated (argv passed to main always >> + * is). >> + * >> + * Does not return if the external command is found and >> + * executed. Return TRUE if external command is not found. Return >> + * FALSE on errors. >> + */ >> +static notmuch_bool_t try_external_command(char *argv[]) >> +{ >> + char *old_argv0 = argv[0]; >> + notmuch_bool_t ret = TRUE; >> + >> + argv[0] = talloc_asprintf (NULL, "notmuch-%s", old_argv0); >> + >> + /* >> + * This will only return on errors. Not finding an external >> + * command (ENOENT) is not an error from our perspective. >> + */ >> + execvp (argv[0], argv); >> + if (errno != ENOENT) { >> + fprintf (stderr, "Error: Running external command '%s' failed: %s\n", >> + argv[0], strerror(errno)); >> + ret = FALSE; >> + } >> + >> + talloc_free (argv[0]); >> + argv[0] = old_argv0; >> + >> + return ret; >> +} >> + >> int >> main (int argc, char *argv[]) >> { >> @@ -406,8 +439,10 @@ main (int argc, char *argv[]) >> >> command = find_command (command_name); >> if (!command) { >> - fprintf (stderr, "Error: Unknown command '%s' (see \"notmuch help\")\n", >> - command_name); >> + /* This won't return if the external command is found. */ >> + if (try_external_command(argv + opt_index)) >> + fprintf (stderr, "Error: Unknown command '%s' (see \"notmuch help\")\n", >> + command_name); >> ret = EXIT_FAILURE; >> goto DONE; >> } >> -- >> 2.1.4 >> >> _______________________________________________ >> notmuch mailing list >> notmuch@notmuchmail.org >> https://notmuchmail.org/mailman/listinfo/notmuch