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",
"logger",
"offline",
"conf",
- "confirm_callback",
NULL,
};
const char* path = NULL;
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");
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);
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);
// 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);
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;
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;
}
#ifndef PAKFIRE_CLI_TERMINAL_H
#define PAKFIRE_CLI_TERMINAL_H
+#include <pakfire/ctx.h>
#include <pakfire/pakfire.h>
#include <pakfire/transaction.h>
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(
#include "lib/requires.h"
#include "lib/search.h"
#include "lib/sync.h"
+#include "lib/terminal.h"
#include "lib/update.h"
#include "lib/version.h"
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[] = {
{ "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 },
};
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:
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
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) {
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);
}
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;
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);
+}
struct pakfire_ctx;
#include <pakfire/logging.h>
+#include <pakfire/pakfire.h>
int pakfire_ctx_create(struct pakfire_ctx** ctx);
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 */
};
// 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);
pakfire_ctx_get_log_level;
pakfire_ctx_set_log_level;
pakfire_ctx_set_log_callback;
+ pakfire_ctx_set_confirm_callback;
# pakfire
pakfire_check;
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;
#include <solv/solverdebug.h>
#include <pakfire/archive.h>
+#include <pakfire/ctx.h>
#include <pakfire/db.h>
#include <pakfire/dependencies.h>
#include <pakfire/digest.h>
#include <pakfire/util.h>
struct pakfire_transaction {
+ struct pakfire_ctx* ctx;
struct pakfire* pakfire;
int nrefs;
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);
}
if (!t)
return -errno;
+ // Store a reference to the context
+ t->ctx = pakfire_ctx(pakfire);
+
// Store reference to Pakfire
t->pakfire = pakfire_ref(pakfire);
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;