From: Michael Tremer Date: Mon, 16 Oct 2023 14:00:28 +0000 (+0000) Subject: ctx: Move the confirm callback into the context X-Git-Tag: 0.9.30~1489 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=19bcc9766297a28bf22b9758dc4ac87062d567df;p=pakfire.git ctx: Move the confirm callback into the context Signed-off-by: Michael Tremer --- diff --git a/src/_pakfire/pakfire.c b/src/_pakfire/pakfire.c index 27df75610..c039251db 100644 --- a/src/_pakfire/pakfire.c +++ b/src/_pakfire/pakfire.c @@ -56,50 +56,6 @@ static PyObject* Pakfire_new(PyTypeObject* type, PyObject* args, PyObject* kwds) return (PyObject *)self; } -static int Pakfire_confirm_callback(struct pakfire* pakfire, void* data, - const char* message, const char* question) { - PyObject* callback = (PyObject*)data; - PyObject* result = NULL; - int r = 0; - - // Do nothing if callback isn't set - if (!callback) - return 0; - - // Acquire GIL - PyGILState_STATE state = PyGILState_Ensure(); - - PyObject* args = Py_BuildValue("(ss)", message, question); - if (!args) { - r = -1; - goto ERROR; - } - - result = PyObject_CallObject(callback, args); - - // If the callback raised an exception, we will ignore it and indicate - // that an error happened, but we cannot re-raise the exception - if (!result) { - r = -1; - goto ERROR; - } - - // Set the return code - if (result == Py_True) - r = 0; - else - r = 1; - -ERROR: - Py_DECREF(args); - Py_DECREF(result); - - // Release the GIL - PyGILState_Release(state); - - return r; -} - static int Pakfire_init(PakfireObject* self, PyObject* args, PyObject* kwds) { char* kwlist[] = { "path", @@ -107,7 +63,6 @@ static int Pakfire_init(PakfireObject* self, PyObject* args, PyObject* kwds) { "logger", "offline", "conf", - "confirm_callback", NULL, }; const char* path = NULL; @@ -118,16 +73,10 @@ static int Pakfire_init(PakfireObject* self, PyObject* args, PyObject* kwds) { FILE* fconf = NULL; - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|zzpOO", kwlist, - &path, &arch, &offline, &conf, &self->callbacks.confirm)) + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|zzpO", kwlist, + &path, &arch, &offline, &conf)) goto ERROR; - // Check if confirm callback is callable - if (self->callbacks.confirm && !PyCallable_Check(self->callbacks.confirm)) { - PyErr_SetString(PyExc_TypeError, "Confirm callback is not callable"); - goto ERROR; - } - // Map the configuration if (conf != Py_None) { fconf = PyObject_AsFileHandle(conf, "r"); @@ -166,14 +115,6 @@ static int Pakfire_init(PakfireObject* self, PyObject* args, PyObject* kwds) { goto ERROR; } - // Configure confirm callback - if (self->callbacks.confirm) { - pakfire_set_confirm_callback(self->pakfire, - Pakfire_confirm_callback, self->callbacks.confirm); - - Py_INCREF(self->callbacks.confirm); - } - ERROR: if (fconf) fclose(fconf); @@ -183,12 +124,6 @@ ERROR: static void Pakfire_dealloc(PakfireObject* self) { if (self->pakfire) { - // Reset confirm callback - if (self->callbacks.confirm) { - pakfire_set_confirm_callback(self->pakfire, NULL, NULL); - Py_DECREF(self->callbacks.confirm); - } - Py_BEGIN_ALLOW_THREADS pakfire_unref(self->pakfire); diff --git a/src/cli/lib/pakfire.c b/src/cli/lib/pakfire.c index 6d9b048a8..9582da5f1 100644 --- a/src/cli/lib/pakfire.c +++ b/src/cli/lib/pakfire.c @@ -101,14 +101,7 @@ int cli_setup_pakfire(struct pakfire** pakfire, struct cli_config* config) { // Setup progress callback pakfire_set_setup_progress_callback(p, cli_setup_progressbar, NULL); - // If the user wants to answer yes to everything we only configure that - if (config->yes) { - pakfire_set_confirm_callback(p, cli_term_confirm_yes, NULL); - - } else if (!pakfire_has_flag(p, PAKFIRE_FLAGS_BUILD)) { - // Configure confirm callback - pakfire_set_confirm_callback(p, cli_term_confirm, NULL); - + if (!pakfire_has_flag(p, PAKFIRE_FLAGS_BUILD)) { // Configure pick solution callback pakfire_set_pick_solution_callback(p, cli_term_pick_solution, NULL); diff --git a/src/cli/lib/terminal.c b/src/cli/lib/terminal.c index 45b78c35e..3822b80fd 100644 --- a/src/cli/lib/terminal.c +++ b/src/cli/lib/terminal.c @@ -85,7 +85,7 @@ int cli_term_is_interactive(void) { return isatty(STDIN_FILENO) && isatty(STDOUT_FILENO) && isatty(STDERR_FILENO); } -int cli_term_confirm(struct pakfire* pakfire, +int cli_term_confirm(struct pakfire_ctx* ctx, struct pakfire* pakfire, void* data, const char* message, const char* question) { char* line = NULL; size_t length = 0; @@ -140,7 +140,7 @@ END: return r; } -int cli_term_confirm_yes(struct pakfire* pakfire, +int cli_term_confirm_yes(struct pakfire_ctx* ctx, struct pakfire* pakfire, void* data, const char* message, const char* question) { return 0; } diff --git a/src/cli/lib/terminal.h b/src/cli/lib/terminal.h index f48b77806..88b622667 100644 --- a/src/cli/lib/terminal.h +++ b/src/cli/lib/terminal.h @@ -21,6 +21,7 @@ #ifndef PAKFIRE_CLI_TERMINAL_H #define PAKFIRE_CLI_TERMINAL_H +#include #include #include @@ -28,9 +29,9 @@ int cli_term_get_dimensions(int* rows, int* cols); int cli_term_is_interactive(void); -int cli_term_confirm(struct pakfire* pakfire, +int cli_term_confirm(struct pakfire_ctx* ctx, struct pakfire* pakfire, void* data, const char* message, const char* question); -int cli_term_confirm_yes(struct pakfire* pakfire, +int cli_term_confirm_yes(struct pakfire_ctx* ctx, struct pakfire* pakfire, void* data, const char* message, const char* question); int cli_term_pick_solution( diff --git a/src/cli/pakfire.c b/src/cli/pakfire.c index 7d0c41021..6940ad536 100644 --- a/src/cli/pakfire.c +++ b/src/cli/pakfire.c @@ -32,6 +32,7 @@ #include "lib/requires.h" #include "lib/search.h" #include "lib/sync.h" +#include "lib/terminal.h" #include "lib/update.h" #include "lib/version.h" @@ -55,9 +56,10 @@ enum { OPT_DEBUG = 2, OPT_OFFLINE = 3, OPT_ROOT = 4, + OPT_YES = 5, - OPT_ENABLE_REPO = 5, - OPT_DISABLE_REPO = 6, + OPT_ENABLE_REPO = 6, + OPT_DISABLE_REPO = 7, }; static struct argp_option options[] = { @@ -67,6 +69,7 @@ static struct argp_option options[] = { { "root", OPT_ROOT, "PATH", 0, "The path to operate in", 0 }, { "enable-repo", OPT_ENABLE_REPO, "REPO", 0, "Enable a repository", 0 }, { "disable-repo", OPT_DISABLE_REPO, "REPO", 0, "Disable a repository", 0 }, + { "yes", OPT_YES, NULL, 0, "Answer all questions with yes", 0 }, { NULL }, }; @@ -104,6 +107,10 @@ static error_t parse(int key, char* arg, void* data) { config->root = arg; break; + case OPT_YES: + pakfire_ctx_set_confirm_callback(config->ctx, cli_term_confirm_yes, NULL); + break; + // Enable/Disable Repositories case OPT_ENABLE_REPO: @@ -137,6 +144,9 @@ int main(int argc, char* argv[]) { if (r) goto ERROR; + // Make this all interactive + pakfire_ctx_set_confirm_callback(ctx, cli_term_confirm, NULL); + struct cli_config config = { .ctx = ctx, // XXX hard-coded path diff --git a/src/libpakfire/ctx.c b/src/libpakfire/ctx.c index d22af95f7..84d511b11 100644 --- a/src/libpakfire/ctx.c +++ b/src/libpakfire/ctx.c @@ -41,6 +41,12 @@ struct pakfire_ctx { pakfire_log_callback callback; void* data; } log; + + // Confirm + struct pakfire_ctx_confirm { + pakfire_confirm_callback callback; + void* data; + } confirm; }; static int parse_log_level(const char* level) { @@ -83,6 +89,14 @@ static int pakfire_ctx_setup_logging(struct pakfire_ctx* ctx) { return 0; } +static int pakfire_ctx_default_confirm_callback(struct pakfire_ctx* ctx, + struct pakfire* pakfire, void* data, const char* message, const char* question) { + // Just log the message + CTX_INFO(ctx, "%s\n", message); + + return 0; +} + static void pakfire_ctx_free(struct pakfire_ctx* ctx) { free(ctx); } @@ -104,6 +118,9 @@ PAKFIRE_EXPORT int pakfire_ctx_create(struct pakfire_ctx** ctx) { if (r) goto ERROR; + // Set the default confirm callback + pakfire_ctx_set_confirm_callback(c, pakfire_ctx_default_confirm_callback, NULL); + // Return the pointer *ctx = c; @@ -158,3 +175,20 @@ void pakfire_ctx_log(struct pakfire_ctx* ctx, int level, const char* file, int l ctx->log.callback(ctx->log.data, level, file, line, fn, format, args); va_end(args); } + +// Confirm + +PAKFIRE_EXPORT void pakfire_ctx_set_confirm_callback(struct pakfire_ctx* ctx, + pakfire_confirm_callback callback, void* data) { + ctx->confirm.callback = callback; + ctx->confirm.data = data; +} + +int pakfire_ctx_confirm(struct pakfire_ctx* ctx, struct pakfire* pakfire, + const char* message, const char* question) { + // Run callback + if (!ctx->confirm.callback) + return 0; + + return ctx->confirm.callback(ctx, pakfire, ctx->confirm.data, message, question); +} diff --git a/src/libpakfire/include/pakfire/ctx.h b/src/libpakfire/include/pakfire/ctx.h index e5c4980f3..74dc33ce0 100644 --- a/src/libpakfire/include/pakfire/ctx.h +++ b/src/libpakfire/include/pakfire/ctx.h @@ -24,6 +24,7 @@ struct pakfire_ctx; #include +#include int pakfire_ctx_create(struct pakfire_ctx** ctx); @@ -38,11 +39,24 @@ void pakfire_ctx_set_log_level(struct pakfire_ctx* ctx, int level); void pakfire_ctx_set_log_callback(struct pakfire_ctx* ctx, pakfire_log_callback callback, void* data); +// Confirm + +typedef int (*pakfire_confirm_callback)(struct pakfire_ctx* ctx, struct pakfire* pakfire, + void* data, const char* message, const char* question); + +void pakfire_ctx_set_confirm_callback(struct pakfire_ctx* ctx, + pakfire_confirm_callback callback, void* data); + #ifdef PAKFIRE_PRIVATE void pakfire_ctx_log(struct pakfire_ctx* ctx, int level, const char* file, int line, const char* fn, const char* format, ...) __attribute__((format(printf, 6, 7))); +// Confirm + +int pakfire_ctx_confirm(struct pakfire_ctx* ctx, struct pakfire* pakfire, + const char* message, const char* question); + #endif /* PAKFIRE_PRIVATE */ #endif /* PAKFIRE_CTX_H */ diff --git a/src/libpakfire/include/pakfire/pakfire.h b/src/libpakfire/include/pakfire/pakfire.h index cd3ab2941..08584df07 100644 --- a/src/libpakfire/include/pakfire/pakfire.h +++ b/src/libpakfire/include/pakfire/pakfire.h @@ -46,10 +46,6 @@ enum pakfire_flags { }; // Callbacks -typedef int (*pakfire_confirm_callback)(struct pakfire* pakfire, void* data, - const char* message, const char* question); -void pakfire_set_confirm_callback(struct pakfire* pakfire, - pakfire_confirm_callback callback, void* data); typedef void (*pakfire_status_callback)(struct pakfire* pakfire, void* data, int progress, const char* status); diff --git a/src/libpakfire/libpakfire.sym b/src/libpakfire/libpakfire.sym index a57458d3a..cbc234601 100644 --- a/src/libpakfire/libpakfire.sym +++ b/src/libpakfire/libpakfire.sym @@ -27,6 +27,7 @@ global: pakfire_ctx_get_log_level; pakfire_ctx_set_log_level; pakfire_ctx_set_log_callback; + pakfire_ctx_set_confirm_callback; # pakfire pakfire_check; diff --git a/src/libpakfire/pakfire.c b/src/libpakfire/pakfire.c index 9a7caf8ae..ac9992f4d 100644 --- a/src/libpakfire/pakfire.c +++ b/src/libpakfire/pakfire.c @@ -1653,26 +1653,6 @@ void pakfire_log(struct pakfire* pakfire, int priority, int r, pakfire_ctx_log(pakfire->ctx, priority, file, line, fn, "%s", buffer); } -// UI - -PAKFIRE_EXPORT void pakfire_set_confirm_callback(struct pakfire* pakfire, - pakfire_confirm_callback callback, void* data) { - pakfire->callbacks.confirm = callback; - pakfire->callbacks.confirm_data = data; -} - -int pakfire_confirm(struct pakfire* pakfire, const char* message, const char* question) { - // Run callback - if (pakfire->callbacks.confirm) - return pakfire->callbacks.confirm( - pakfire, pakfire->callbacks.confirm_data, message, question); - - // If no callback is set, we just log the message - INFO(pakfire, "%s\n", message); - - return 0; -} - static const char* pakfire_user_lookup(void* data, la_int64_t uid) { struct pakfire* pakfire = (struct pakfire*)data; diff --git a/src/libpakfire/transaction.c b/src/libpakfire/transaction.c index 2274c04be..7c112e1cf 100644 --- a/src/libpakfire/transaction.c +++ b/src/libpakfire/transaction.c @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -45,6 +46,7 @@ #include struct pakfire_transaction { + struct pakfire_ctx* ctx; struct pakfire* pakfire; int nrefs; @@ -173,7 +175,10 @@ static void pakfire_transaction_free(struct pakfire_transaction* transaction) { transaction_free(transaction->transaction); if (transaction->solver) solver_free(transaction->solver); - pakfire_unref(transaction->pakfire); + if (transaction->pakfire) + pakfire_unref(transaction->pakfire); + if (transaction->ctx) + pakfire_ctx_unref(transaction->ctx); free(transaction); } @@ -321,6 +326,9 @@ PAKFIRE_EXPORT int pakfire_transaction_create(struct pakfire_transaction** trans if (!t) return -errno; + // Store a reference to the context + t->ctx = pakfire_ctx(pakfire); + // Store reference to Pakfire t->pakfire = pakfire_ref(pakfire); @@ -1940,7 +1948,7 @@ PAKFIRE_EXPORT int pakfire_transaction_run(struct pakfire_transaction* transacti dump = pakfire_transaction_dump(transaction, 80); // Check if we should continue - r = pakfire_confirm(transaction->pakfire, dump, _("Is this okay?")); + r = pakfire_ctx_confirm(transaction->ctx, transaction->pakfire, dump, _("Is this okay?")); if (r) { ERROR(transaction->pakfire, "Transaction aborted upon user request\n"); goto ERROR;