From: "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
To: git@vger.kernel.org
Cc: "Junio C Hamano" <gitster@pobox.com>, "Jeff King" <peff@peff.net>,
"Taylor Blau" <me@ttaylorr.com>,
"Eric Sunshine" <sunshine@sunshineco.com>,
"Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
Subject: [PATCH v2 0/6] usage API: Add and use die_message()
Date: Tue, 7 Dec 2021 19:26:28 +0100 [thread overview]
Message-ID: <cover-v2-0.6-00000000000-20211207T182419Z-avarab@gmail.com> (raw)
In-Reply-To: <cover-0.4-00000000000-20211206T165221Z-avarab@gmail.com>
A small set of fixes to usage.[ch]'s API use that will go towards
enabling nicer things down the road. See [1] for the v1 summary
I believe this should address all the feedback Junio had on the
v1.
Aside from the substantially rewritten 6/6 and much simplified 4/6 the
end-state is almost the same, but things are better split up,
explained etc. now.
1. https://lore.kernel.org/git/cover-0.4-00000000000-20211206T165221Z-avarab@gmail.com/
Ævar Arnfjörð Bjarmason (6):
usage.c: add a die_message() routine
usage.c API users: use die_message() for "fatal :" + exit 128
usage.c API users: use die_message() for error() + exit 128
gc: return from cmd_gc(), don't call exit()
usage.c + gc: add and use a die_message_errno()
config API: use get_error_routine(), not vreportf()
builtin/fast-import.c | 12 +++++++-----
builtin/gc.c | 14 ++++++++------
builtin/notes.c | 9 +++++----
config.c | 3 ++-
git-compat-util.h | 4 +++-
http-backend.c | 3 ++-
parse-options.c | 2 +-
run-command.c | 16 +++++-----------
usage.c | 42 ++++++++++++++++++++++++++++++++++++++----
9 files changed, 71 insertions(+), 34 deletions(-)
Range-diff against v1:
1: 5a9ab85fa56 ! 1: 65ae6fe7cbe usage.c: add a die_message() routine
@@ Commit message
this is so that caller can pass the return value to "exit()", instead
of having to hardcode "exit(128)".
- A subsequent commit will migrate various callers that benefit from
- this function over to it. For now we're just adding the routine and
- making die_builtin() in usage.c itself use it.
+ Note that as with the other routines the "die_message_builtin" needs
+ to return "void" and otherwise conform to the "report_fn"
+ signature.
+
+ As we'll see in a subsequent commit callers will want to replace
+ e.g. their default "die_routine" with a "die_message_routine".
+
+ For now we're just adding the routine and making die_builtin() in
+ usage.c itself use it. In order to do that we need to add a
+ get_die_message_routine() function, which works like the other
+ get_*_routine() functions in usage.c. There is no
+ set_die_message_rotine(), as it hasn't been needed yet. We can add it
+ if we ever need it.
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
@@ git-compat-util.h: NORETURN void usage(const char *err);
int error(const char *err, ...) __attribute__((format (printf, 1, 2)));
int error_errno(const char *err, ...) __attribute__((format (printf, 1, 2)));
void warning(const char *err, ...) __attribute__((format (printf, 1, 2)));
+@@ git-compat-util.h: static inline int const_error(void)
+ typedef void (*report_fn)(const char *, va_list params);
+
+ void set_die_routine(NORETURN_PTR report_fn routine);
++report_fn get_die_message_routine(void);
+ void set_error_routine(report_fn routine);
+ report_fn get_error_routine(void);
+ void set_warn_routine(report_fn routine);
## usage.c ##
@@ usage.c: static NORETURN void usage_builtin(const char *err, va_list params)
@@ usage.c: static NORETURN void usage_builtin(const char *err, va_list params)
- trace2_cmd_error_va(err, params);
-
- vreportf("fatal: ", err, params);
--
-+ die_message_builtin(err, params);
++ report_fn die_message_fn = get_die_message_routine();
+
++ die_message_fn(err, params);
exit(128);
}
+@@ usage.c: static int die_is_recursing_builtin(void)
+ * (ugh), so keep things static. */
+ static NORETURN_PTR report_fn usage_routine = usage_builtin;
+ static NORETURN_PTR report_fn die_routine = die_builtin;
++static report_fn die_message_routine = die_message_builtin;
+ static report_fn error_routine = error_builtin;
+ static report_fn warn_routine = warn_builtin;
+ static int (*die_is_recursing)(void) = die_is_recursing_builtin;
+@@ usage.c: void set_die_routine(NORETURN_PTR report_fn routine)
+ die_routine = routine;
+ }
+
++report_fn get_die_message_routine(void)
++{
++ return die_message_routine;
++}
++
+ void set_error_routine(report_fn routine)
+ {
+ error_routine = routine;
@@ usage.c: void NORETURN die_errno(const char *fmt, ...)
va_end(params);
}
@@ usage.c: void NORETURN die_errno(const char *fmt, ...)
+ va_list params;
+
+ va_start(params, err);
-+ die_message_builtin(err, params);
++ die_message_routine(err, params);
+ va_end(params);
+ return 128;
+}
2: 36c050c90c2 ! 2: f5a98901498 usage.c API users: use die_message() where appropriate
@@ Metadata
Author: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
## Commit message ##
- usage.c API users: use die_message() where appropriate
+ usage.c API users: use die_message() for "fatal :" + exit 128
- Change code that either called error() and proceeded to exit with 128,
- or emitted its own "fatal: " messages to use the die_message()
- function added in a preceding commit.
+ Change code that printed its own "fatal: " message and exited with a
+ status code of 128 to use the die_message() function added in a
+ preceding commit.
- In order to do that we need to add a get_die_message_routine()
- function, which works like the other get_*_routine() functions in
- usage.c. There is no set_die_message_rotine(), as it hasn't been
- needed yet. We can add it if we ever need it.
+ This change also demonstrates why the return value of
+ die_message_routine() needed to be that of "report_fn". We have
+ callers such as the run-command.c::child_err_spew() which would like
+ to replace its error routine with the return value of
+ "get_die_message_routine()".
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
@@ builtin/fast-import.c: static void dump_marks(void);
end_packfile();
unkeep_all_packs();
- ## builtin/notes.c ##
-@@ builtin/notes.c: static void prepare_note_data(const struct object_id *object, struct note_data *
- static void write_note_data(struct note_data *d, struct object_id *oid)
- {
- if (write_object_file(d->buf.buf, d->buf.len, blob_type, oid)) {
-- error(_("unable to write note object"));
-+ int status = die_message(_("unable to write note object"));
-+
- if (d->edit_path)
-- error(_("the note contents have been left in %s"),
-- d->edit_path);
-- exit(128);
-+ die_message(_("the note contents have been left in %s"),
-+ d->edit_path);
-+ exit(status);
- }
- }
-
-
- ## git-compat-util.h ##
-@@ git-compat-util.h: static inline int const_error(void)
- typedef void (*report_fn)(const char *, va_list params);
-
- void set_die_routine(NORETURN_PTR report_fn routine);
-+report_fn get_die_message_routine(void);
- void set_error_routine(report_fn routine);
- report_fn get_error_routine(void);
- void set_warn_routine(report_fn routine);
-
## http-backend.c ##
@@ http-backend.c: static NORETURN void die_webcgi(const char *err, va_list params)
{
@@ run-command.c: static void *run_thread(void *data)
if (in_async()) {
struct async *async = pthread_getspecific(async_key);
-
- ## usage.c ##
-@@ usage.c: static void die_message_builtin(const char *err, va_list params)
- */
- static NORETURN void die_builtin(const char *err, va_list params)
- {
-- die_message_builtin(err, params);
-+ report_fn die_message_fn = get_die_message_routine();
-+
-+ die_message_fn(err, params);
- exit(128);
- }
-
-@@ usage.c: static int die_is_recursing_builtin(void)
- * (ugh), so keep things static. */
- static NORETURN_PTR report_fn usage_routine = usage_builtin;
- static NORETURN_PTR report_fn die_routine = die_builtin;
-+static report_fn die_message_routine = die_message_builtin;
- static report_fn error_routine = error_builtin;
- static report_fn warn_routine = warn_builtin;
- static int (*die_is_recursing)(void) = die_is_recursing_builtin;
-@@ usage.c: void set_die_routine(NORETURN_PTR report_fn routine)
- die_routine = routine;
- }
-
-+report_fn get_die_message_routine(void)
-+{
-+ return die_message_routine;
-+}
-+
- void set_error_routine(report_fn routine)
- {
- error_routine = routine;
-@@ usage.c: int die_message(const char *err, ...)
- va_list params;
-
- va_start(params, err);
-- die_message_builtin(err, params);
-+ die_message_routine(err, params);
- va_end(params);
- return 128;
- }
-: ----------- > 3: c7d67fd41fa usage.c API users: use die_message() for error() + exit 128
-: ----------- > 4: f224a281a10 gc: return from cmd_gc(), don't call exit()
3: 8747afecdcd ! 5: 2b4a3910654 usage.c + gc: add and use a die_message_errno()
@@ Metadata
## Commit message ##
usage.c + gc: add and use a die_message_errno()
- Change code the "error: " output when we exit with 128 due to gc.log
- errors to use a "fatal: " prefix instead. This adds a sibling function
- to the die_errno() added in a preceding commit.
+ Change the "error: " output when we exit with 128 due to gc.log errors
+ to use a "fatal: " prefix instead. To do this add a
+ die_message_errno() a sibling function to the die_errno() added in a
+ preceding commit.
- Since it returns 128 instead of -1 (like die_message()) we'll need to
- adjust report_last_gc_error().
+ Before this we'd expect report_last_gc_error() to return -1 from
+ error_errno() in this case. It already treated a status of 0 and 1
+ specially. Let's just document that anything that's not 0 or 1 should
+ be returned.
- Let's adjust it while we're at it to not conflate the "should skip"
- and "exit with this non-zero code" conditions, as the caller is no
- longer hardcoding "128", but relying on die_errno() to return a
- nen-zero exit() status.
-
- Since we're touching this code let's also use "return ret" in place of
- an "exit(ret)". This is kinder to any cleanup our our "cmd_main()" in
- "git.c" might want to do.
+ We could also retain the "ret < 0" behavior here without hardcoding
+ 128 by returning -128, and having the caller do a "return -ret", but I
+ think this makes more sense, and preserves the path from
+ die_message*()'s return value to the "return" without hardcoding
+ "128".
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
## builtin/gc.c ##
@@ builtin/gc.c: static const char *lock_repo_for_gc(int force, pid_t* ret_pid)
+ /*
+ * Returns 0 if there was no previous error and gc can proceed, 1 if
* gc should not proceed due to an error in the last run. Prints a
- * message and returns -1 if an error occurred while reading gc.log
+- * message and returns -1 if an error occurred while reading gc.log
++ * message and returns with a non-[01] status code if an error occurred
++ * while reading gc.log
*/
--static int report_last_gc_error(void)
-+static int report_last_gc_error(int *skip)
+ static int report_last_gc_error(void)
{
- struct strbuf sb = STRBUF_INIT;
- int ret = 0;
- ssize_t len;
- struct stat st;
- char *gc_log_path = git_pathdup("gc.log");
-+ *skip = 0;
-
- if (stat(gc_log_path, &st)) {
+@@ builtin/gc.c: static int report_last_gc_error(void)
if (errno == ENOENT)
goto done;
@@ builtin/gc.c: static int report_last_gc_error(void)
else if (len > 0) {
/*
* A previous gc failed. Report the error, and don't
-@@ builtin/gc.c: static int report_last_gc_error(void)
- "until the file is removed.\n\n"
- "%s"),
- gc_log_path, sb.buf);
-- ret = 1;
-+ *skip = 1;
- }
- strbuf_release(&sb);
- done:
@@ builtin/gc.c: int cmd_gc(int argc, const char **argv, const char *prefix)
- fprintf(stderr, _("See \"git help gc\" for manual housekeeping.\n"));
- }
if (detach_auto) {
-- int ret = report_last_gc_error();
+ int ret = report_last_gc_error();
+
- if (ret < 0)
- /* an I/O error occurred, already reported */
-- exit(128);
-- if (ret == 1)
-+ int skip;
-+ int ret = report_last_gc_error(&skip);
-+
-+ if (skip)
+- return 128;
+ if (ret == 1)
/* Last gc --auto failed. Skip this one. */
return 0;
-+ if (ret)
++ else if (ret)
+ /* an I/O error occurred, already reported */
+ return ret;
4: e0e6427cbd3 ! 6: 42132406731 config API: don't use vreportf(), make it static in usage.c
@@ Metadata
Author: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
## Commit message ##
- config API: don't use vreportf(), make it static in usage.c
+ config API: use get_error_routine(), not vreportf()
- In preceding commits the rest of the vreportf() users outside of
- usage.c have been migrated to die_message(), leaving only the
- git_die_config() function added in 5a80e97c827 (config: add
- `git_die_config()` to the config-set API, 2014-08-07).
-
- Let's have its callers call error() themselves if they want to emit a
- message, which is exactly what git_die_config() was doing for them
- before emitting its own die() message.
+ Change the git_die_config() function added in 5a80e97c827 (config: add
+ `git_die_config()` to the config-set API, 2014-08-07) to use the
+ public callbacks in the usage.[ch] API instead of the the underlying
+ vreportf() function.
- This means that we can make the vreportf() in usage.c "static", and
- only expose functions such as usage(), die(), warning() etc.
+ In preceding commits the rest of the vreportf() users outside of
+ usage.c was migrated to die_message(), so we can now make it "static".
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
- ## builtin/fast-import.c ##
-@@ builtin/fast-import.c: static void git_pack_config(void)
- }
- if (!git_config_get_int("pack.indexversion", &indexversion_value)) {
- pack_idx_opts.version = indexversion_value;
-- if (pack_idx_opts.version > 2)
-- git_die_config("pack.indexversion",
-- "bad pack.indexversion=%"PRIu32, pack_idx_opts.version);
-+ if (pack_idx_opts.version > 2) {
-+ error("bad pack.indexversion=%"PRIu32, pack_idx_opts.version);
-+ git_die_config("pack.indexversion");
-+ }
- }
- if (!git_config_get_ulong("pack.packsizelimit", &packsizelimit_value))
- max_packsize = packsizelimit_value;
-
- ## builtin/notes.c ##
-@@ builtin/notes.c: static int git_config_get_notes_strategy(const char *key,
-
- if (git_config_get_string(key, &value))
- return 1;
-- if (parse_notes_merge_strategy(value, strategy))
-- git_die_config(key, _("unknown notes merge strategy %s"), value);
-+ if (parse_notes_merge_strategy(value, strategy)) {
-+ error(_("unknown notes merge strategy %s"), value);
-+ git_die_config(key);
-+ }
-
- free(value);
- return 0;
-
## config.c ##
-@@ config.c: int repo_config_get_string(struct repository *repo,
- git_config_check_init(repo);
- ret = git_configset_get_string(repo->config, key, dest);
- if (ret < 0)
-- git_die_config(key, NULL);
-+ git_die_config(key);
- return ret;
- }
-
-@@ config.c: int repo_config_get_string_tmp(struct repository *repo,
- git_config_check_init(repo);
- ret = git_configset_get_string_tmp(repo->config, key, dest);
- if (ret < 0)
-- git_die_config(key, NULL);
-+ git_die_config(key);
- return ret;
- }
-
-@@ config.c: int repo_config_get_pathname(struct repository *repo,
- git_config_check_init(repo);
- ret = git_configset_get_pathname(repo->config, key, dest);
- if (ret < 0)
-- git_die_config(key, NULL);
-+ git_die_config(key);
- return ret;
- }
-
-@@ config.c: int git_config_get_expiry(const char *key, const char **output)
- return ret;
- if (strcmp(*output, "now")) {
- timestamp_t now = approxidate("now");
-- if (approxidate(*output) >= now)
-- git_die_config(key, _("Invalid %s: '%s'"), key, *output);
-+ if (approxidate(*output) >= now) {
-+ error(_("Invalid %s: '%s'"), key, *output);
-+ git_die_config(key);
-+ }
- }
- return ret;
- }
-@@ config.c: void git_die_config_linenr(const char *key, const char *filename, int linenr)
- key, filename, linenr);
- }
-
--NORETURN __attribute__((format(printf, 2, 3)))
--void git_die_config(const char *key, const char *err, ...)
-+NORETURN
-+void git_die_config(const char *key)
+@@ config.c: void git_die_config(const char *key, const char *err, ...)
{
const struct string_list *values;
struct key_value_info *kv_info;
++ report_fn error_fn = get_error_routine();
-- if (err) {
-- va_list params;
-- va_start(params, err);
+ if (err) {
+ va_list params;
+ va_start(params, err);
- vreportf("error: ", err, params);
-- va_end(params);
-- }
++ error_fn(err, params);
+ va_end(params);
+ }
values = git_config_get_value_multi(key);
- kv_info = values->items[values->nr - 1].util;
- git_die_config_linenr(key, kv_info->filename, kv_info->linenr);
-
- ## config.h ##
-@@ config.h: struct key_value_info {
- };
-
- /**
-- * First prints the error message specified by the caller in `err` and then
-- * dies printing the line number and the file name of the highest priority
-- * value for the configuration variable `key`.
-+ * Dies printing the line number and the file name of the highest
-+ * priority value for the configuration variable `key`.
-+ *
-+ * Consider calling error() first with a more specific formatted
-+ * message of your own.
- */
--NORETURN void git_die_config(const char *key, const char *err, ...) __attribute__((format(printf, 2, 3)));
-+NORETURN void git_die_config(const char *key);
-
- /**
- * Helper function which formats the die error message according to the
## git-compat-util.h ##
@@ git-compat-util.h: static inline int git_has_dir_sep(const char *path)
@@ git-compat-util.h: static inline int git_has_dir_sep(const char *path)
NORETURN void usagef(const char *err, ...) __attribute__((format (printf, 1, 2)));
NORETURN void die(const char *err, ...) __attribute__((format (printf, 1, 2)));
- ## imap-send.c ##
-@@ imap-send.c: static int git_imap_config(const char *var, const char *val, void *cb)
- server.port = git_config_int(var, val);
- else if (!strcmp("imap.host", var)) {
- if (!val) {
-- git_die_config("imap.host", "Missing value for 'imap.host'");
-+ error("Missing value for 'imap.host'");
-+ git_die_config("imap.host");
- } else {
- if (starts_with(val, "imap:"))
- val += 5;
-
## usage.c ##
@@
#include "git-compat-util.h"
--
2.34.1.898.g5a552c2e5f0
next prev parent reply other threads:[~2021-12-07 18:26 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-12-06 16:55 [PATCH 0/4] usage API: Add and use die_message() Ævar Arnfjörð Bjarmason
2021-12-06 16:55 ` [PATCH 1/4] usage.c: add a die_message() routine Ævar Arnfjörð Bjarmason
2021-12-06 19:42 ` Junio C Hamano
2021-12-06 19:46 ` Junio C Hamano
2021-12-06 16:55 ` [PATCH 2/4] usage.c API users: use die_message() where appropriate Ævar Arnfjörð Bjarmason
2021-12-06 20:00 ` Junio C Hamano
2021-12-06 16:55 ` [PATCH 3/4] usage.c + gc: add and use a die_message_errno() Ævar Arnfjörð Bjarmason
2021-12-06 21:19 ` Junio C Hamano
2021-12-06 16:55 ` [PATCH 4/4] config API: don't use vreportf(), make it static in usage.c Ævar Arnfjörð Bjarmason
2021-12-06 21:26 ` Junio C Hamano
2021-12-07 18:05 ` Ævar Arnfjörð Bjarmason
2021-12-07 18:26 ` Ævar Arnfjörð Bjarmason [this message]
2021-12-07 18:26 ` [PATCH v2 1/6] usage.c: add a die_message() routine Ævar Arnfjörð Bjarmason
2021-12-07 18:26 ` [PATCH v2 2/6] usage.c API users: use die_message() for "fatal :" + exit 128 Ævar Arnfjörð Bjarmason
2021-12-07 18:26 ` [PATCH v2 3/6] usage.c API users: use die_message() for error() " Ævar Arnfjörð Bjarmason
2021-12-07 18:26 ` [PATCH v2 4/6] gc: return from cmd_gc(), don't call exit() Ævar Arnfjörð Bjarmason
2021-12-07 18:26 ` [PATCH v2 5/6] usage.c + gc: add and use a die_message_errno() Ævar Arnfjörð Bjarmason
2021-12-07 18:26 ` [PATCH v2 6/6] config API: use get_error_routine(), not vreportf() Ævar Arnfjörð Bjarmason
2021-12-07 21:24 ` [PATCH v2 0/6] usage API: Add and use die_message() Junio C Hamano
2021-12-22 18:57 ` Jonathan Tan
2021-12-22 19:59 ` Junio C Hamano
2021-12-24 17:01 ` Ævar Arnfjörð Bjarmason
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=cover-v2-0.6-00000000000-20211207T182419Z-avarab@gmail.com \
--to=avarab@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=me@ttaylorr.com \
--cc=peff@peff.net \
--cc=sunshine@sunshineco.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).