From: Michael Tremer Date: Sat, 11 Jan 2025 16:32:39 +0000 (+0000) Subject: packager: Return an archive X-Git-Tag: 0.9.30~438 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f2935d55e7f9839d1edfc2a34c28e1c5619e143a;p=pakfire.git packager: Return an archive This is an attempt to have the packager return an object instead of a loose path so that we can do more things with the result. Signed-off-by: Michael Tremer --- diff --git a/src/cli/lib/dist.c b/src/cli/lib/dist.c index 684d4349d..b8a997717 100644 --- a/src/cli/lib/dist.c +++ b/src/cli/lib/dist.c @@ -26,6 +26,7 @@ #include #include +#include static const char* args_doc = "dist MAKEFILES..."; @@ -59,6 +60,41 @@ static error_t parse(int key, char* arg, struct argp_state* state, void* data) { return 0; } +static int do_dist(struct pakfire* pakfire, const char* makefile, const char* resultdir) { + struct pakfire_archive* archive = NULL; + char* filename = NULL; + char path[PATH_MAX]; + int r; + + // Create the archive + r = pakfire_dist(pakfire, makefile, &archive, &filename); + if (r < 0) + goto ERROR; + + // Make the final path + r = pakfire_path_append(path, resultdir, filename); + if (r < 0) + goto ERROR; + + // Copy or link the archive + r = pakfire_archive_link_or_copy(archive, path); + if (r < 0) + goto ERROR; + + // Unlink the temporary archive + r = pakfire_archive_unlink(archive); + if (r < 0) + goto ERROR; + +ERROR: + if (archive) + pakfire_archive_unref(archive); + if (filename) + free(filename); + + return r; +} + int cli_dist(void* data, int argc, char* argv[]) { struct cli_global_args* global_args = data; struct cli_local_args local_args = {}; @@ -82,9 +118,9 @@ int cli_dist(void* data, int argc, char* argv[]) { // Process all packages for (unsigned int i = 0; i < local_args.num_makefiles; i++) { - r = pakfire_dist(pakfire, local_args.makefiles[i], local_args.resultdir, NULL); - if (r) { - fprintf(stderr, "Could not dist %s\n", local_args.makefiles[i]); + r = do_dist(pakfire, local_args.makefiles[i], local_args.resultdir); + if (r < 0) { + fprintf(stderr, "Could not dist %s: %s\n", local_args.makefiles[i], strerror(-r)); goto ERROR; } } diff --git a/src/pakfire/build.c b/src/pakfire/build.c index b0a6857a9..a91a30803 100644 --- a/src/pakfire/build.c +++ b/src/pakfire/build.c @@ -1148,6 +1148,7 @@ static int pakfire_build_package_add_scriptlets(struct pakfire_build* build, static int pakfire_build_package(struct pakfire_build* build, struct pakfire_parser* makefile, const char* buildroot, const char* namespace) { + struct pakfire_archive* archive = NULL; struct pakfire_package* pkg = NULL; struct pakfire_packager* packager = NULL; @@ -1226,10 +1227,10 @@ static int pakfire_build_package(struct pakfire_build* build, struct pakfire_par const char* path = pakfire_repo_get_path(build->repo); - // Write the finished package - r = pakfire_packager_finish_to_directory(packager, path, NULL); - if (r) { - ERROR(build->ctx, "pakfire_packager_finish() failed: %m\n"); + // Write the archive + r = pakfire_packager_write_archive(packager, &archive); + if (r < 0) { + ERROR(build->ctx, "pakfire_packager_finish() failed: %s\n", strerror(-r)); goto ERROR; } @@ -1238,10 +1239,14 @@ static int pakfire_build_package(struct pakfire_build* build, struct pakfire_par if (r) goto ERROR; - // Success - r = 0; + // Add the package to the repository + r = pakfire_repo_add_archive(build->repo, archive, &pkg); + if (r < 0) + goto ERROR; ERROR: + if (archive) + pakfire_archive_unref(archive); if (packager) pakfire_packager_unref(packager); if (pkg) @@ -1293,11 +1298,6 @@ static int pakfire_build_packages(struct pakfire_build* build, goto ERROR; } - // Rescan the build repository to import all packages again - r = pakfire_repo_scan(build->repo, 0); - if (r) - goto ERROR; - // Create a new packagelist r = pakfire_packagelist_create(&build->packages, build->ctx); if (r) diff --git a/src/pakfire/dist.c b/src/pakfire/dist.c index 6e251ffef..71ebe0601 100644 --- a/src/pakfire/dist.c +++ b/src/pakfire/dist.c @@ -450,18 +450,19 @@ ERROR: } int pakfire_dist(struct pakfire* pakfire, const char* path, - const char* target, char** result) { - struct pakfire_parser* makefile; - struct pakfire_parser_error* error = NULL; - + struct pakfire_archive** archive, char** filename) { struct pakfire_packager* packager = NULL; struct pakfire_package* pkg = NULL; + struct pakfire_parser* makefile = NULL; + struct pakfire_parser_error* error = NULL; + struct pakfire_archive* a = NULL; + int r; // Fetch context struct pakfire_ctx* ctx = pakfire_ctx(pakfire); // Load makefile - int r = pakfire_read_makefile(&makefile, pakfire, path, &error); + r = pakfire_read_makefile(&makefile, pakfire, path, &error); if (r) { if (error) pakfire_parser_error_unref(error); @@ -498,12 +499,22 @@ int pakfire_dist(struct pakfire* pakfire, const char* path, if (r) goto ERROR; - // Write the finished package - r = pakfire_packager_finish_to_directory(packager, target, result); - if (r) + // Write the archive + r = pakfire_packager_write_archive(packager, &a); + if (r < 0) goto ERROR; - // XXX Lint the package + // Link the archive + r = pakfire_archive_lint(a, NULL, NULL); + if (r < 0) + goto ERROR; + + // Return the filename + if (filename) + *filename = pakfire_packager_filename(packager); + + // Return a reference to the archive + *archive = pakfire_archive_ref(a); ERROR: if (packager) @@ -512,6 +523,8 @@ ERROR: pakfire_package_unref(pkg); if (makefile) pakfire_parser_unref(makefile); + if (a) + pakfire_archive_unref(a); if (ctx) pakfire_ctx_unref(ctx); diff --git a/src/pakfire/dist.h b/src/pakfire/dist.h index 587757ef8..9cdc9c176 100644 --- a/src/pakfire/dist.h +++ b/src/pakfire/dist.h @@ -21,11 +21,12 @@ #ifndef PAKFIRE_DIST_H #define PAKFIRE_DIST_H +#include #include #include -int pakfire_dist(struct pakfire* pakfire, const char* path, const char* target, - char** result); +int pakfire_dist(struct pakfire* pakfire, const char* path, + struct pakfire_archive** archive, char** filename); int pakfire_read_makefile(struct pakfire_parser** parser, struct pakfire* pakfire, const char* path, struct pakfire_parser_error** error); diff --git a/src/pakfire/packager.c b/src/pakfire/packager.c index 98c807058..b5835407d 100644 --- a/src/pakfire/packager.c +++ b/src/pakfire/packager.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -219,35 +220,16 @@ struct pakfire_packager* pakfire_packager_unref( return NULL; } -const char* pakfire_packager_filename(struct pakfire_packager* packager) { +char* pakfire_packager_filename(struct pakfire_packager* packager) { const char* filename = NULL; - const char* arch = NULL; - int r; - if (!*packager->filename) { - filename = pakfire_package_get_string(packager->pkg, PAKFIRE_PKG_FILENAME); - if (!filename) - return NULL; - - // Store the string for source packages - if (pakfire_package_is_source(packager->pkg)) { - r = pakfire_string_set(packager->filename, filename); - if (r < 0) - return NULL; - - // For binary packages, we prepend the architecture - } else { - arch = pakfire_package_get_string(packager->pkg, PAKFIRE_PKG_ARCH); - if (!arch) - return NULL; - - r = pakfire_string_format(packager->filename, "%s/%s", arch, filename); - if (r < 0) - return NULL; - } - } + // Fetch the filename from the package + filename = pakfire_package_get_string(packager->pkg, PAKFIRE_PKG_FILENAME); + if (!filename) + return NULL; - return packager->filename; + // Copy the string + return strdup(filename); } static struct archive_entry* pakfire_packager_create_file( @@ -495,83 +477,53 @@ ERROR: return r; } -int pakfire_packager_finish_to_directory(struct pakfire_packager* packager, - const char* target, char** result) { - char tmppath[PATH_MAX] = ""; - char path[PATH_MAX]; +int pakfire_packager_write_archive(struct pakfire_packager* self, + struct pakfire_archive** archive) { FILE* f = NULL; - int r = 1; - - // target cannot be empty - if (!target) { - errno = EINVAL; - return 1; - } + char path[PATH_MAX]; + int r; - // Get the filename of the package - const char* filename = pakfire_packager_filename(packager); + // Fetch the filename of the package + const char* filename = pakfire_package_get_string(self->pkg, PAKFIRE_PKG_FILENAME); if (!filename) { - ERROR(packager->ctx, "Could not generate filename for package: %m\n"); - r = 1; + r = -EINVAL; goto ERROR; } - // Make the package path - r = pakfire_string_format(path, "%s/%s", target, filename); - if (r) - goto ERROR; - - // Create the parent directory - r = pakfire_mkparentdir(path, 0755); - if (r) + // Compose the path for a temporary file + r = pakfire_path_format(path, "%s/.%s.XXXXXX", PAKFIRE_TMP_DIR, filename); + if (r < 0) goto ERROR; - // Create a temporary file in the target directory - r = pakfire_string_format(tmppath, "%s.XXXXXX", path); - if (r) - goto ERROR; - - // Create a temporary result file - f = pakfire_mktemp(tmppath, 0); - if (!f) - goto ERROR; - - // Write the finished package - r = pakfire_packager_finish(packager, f); - if (r) { - ERROR(packager->ctx, "pakfire_packager_finish() failed: %m\n"); + // Create the temporary file + f = pakfire_mktemp(path, 0644); + if (!f) { + ERROR(self->ctx, "Could not create temporary file: %m\n"); + r = -errno; goto ERROR; } - // Move the temporary file to destination - r = rename(tmppath, path); - if (r) { - ERROR(packager->ctx, "Could not move %s to %s: %m\n", tmppath, path); + // Write everything to the temporary file + r = pakfire_packager_finish(self, f); + if (r < 0) goto ERROR; - } - DEBUG(packager->ctx, "Package written to %s\n", path); + // Close the file + fclose(f); + f = NULL; - // Store result path if requested - if (result) { - *result = strdup(path); - if (!*result) { - r = 1; - goto ERROR; - } + // Open the archive + r = pakfire_archive_open(archive, self->pakfire, path); + if (r < 0) { + ERROR(self->ctx, "Could not open the generated archive at %s: %s\n", + path, strerror(-r)); + goto ERROR; } - // Success - r = 0; - ERROR: if (f) fclose(f); - // Remove temporary file - if (r && *tmppath) - unlink(tmppath); - return r; } diff --git a/src/pakfire/packager.h b/src/pakfire/packager.h index 7025da6ec..f207f4401 100644 --- a/src/pakfire/packager.h +++ b/src/pakfire/packager.h @@ -37,11 +37,12 @@ int pakfire_packager_create(struct pakfire_packager** packager, struct pakfire_packager* pakfire_packager_ref(struct pakfire_packager* packager); struct pakfire_packager* pakfire_packager_unref(struct pakfire_packager* packager); -const char* pakfire_packager_filename(struct pakfire_packager* packager); +char* pakfire_packager_filename(struct pakfire_packager* packager); + +int pakfire_packager_write_archive(struct pakfire_packager* self, + struct pakfire_archive** archive); int pakfire_packager_finish(struct pakfire_packager* packager, FILE* f); -int pakfire_packager_finish_to_directory(struct pakfire_packager* packager, - const char* target, char** result); int pakfire_packager_add_file( struct pakfire_packager* packager, struct pakfire_file* file); diff --git a/src/pakfire/pakfire.c b/src/pakfire/pakfire.c index 518fd6512..76f442d8b 100644 --- a/src/pakfire/pakfire.c +++ b/src/pakfire/pakfire.c @@ -1305,23 +1305,23 @@ struct pakfire_repo* pakfire_get_installed_repo(struct pakfire* pakfire) { Convenience function to dist() a package on the fly */ static int pakfire_commandline_dist(struct pakfire* pakfire, struct pakfire_repo* repo, - const char* path, struct pakfire_package** package) { - char* result = NULL; + const char* path, struct pakfire_package** pkg) { + struct pakfire_archive* archive = NULL; int r; - // XXX result is not unique! - // Run dist() - r = pakfire_dist(pakfire, path, PAKFIRE_TMP_DIR, &result); - if (r) + r = pakfire_dist(pakfire, path, &archive, NULL); + if (r < 0) goto ERROR; - // Try to add the package to the repository - r = pakfire_repo_add(repo, result, package); + // Add the archive to the repository + r = pakfire_repo_add_archive(repo, archive, pkg); + if (r < 0) + goto ERROR; ERROR: - if (result) - free(result); + if (archive) + pakfire_archive_unref(archive); return r; } diff --git a/src/python/pakfire.c b/src/python/pakfire.c index c8596a044..0c04a31b1 100644 --- a/src/python/pakfire.c +++ b/src/python/pakfire.c @@ -366,6 +366,7 @@ static PyObject* Pakfire_version_compare(PakfireObject* self, PyObject* args) { } static PyObject* Pakfire_dist(PakfireObject* self, PyObject* args) { + struct pakfire_archive* archive = NULL; const char* path = NULL; const char* target = NULL; char* result = NULL; @@ -376,7 +377,7 @@ static PyObject* Pakfire_dist(PakfireObject* self, PyObject* args) { Py_BEGIN_ALLOW_THREADS - r = pakfire_dist(self->pakfire, path, target, &result); + r = pakfire_dist(self->pakfire, path, &archive, &result); if (r) { Py_BLOCK_THREADS PyErr_SetFromErrno(PyExc_OSError); @@ -388,6 +389,8 @@ static PyObject* Pakfire_dist(PakfireObject* self, PyObject* args) { PyObject* ret = PyUnicode_FromString(result); free(result); + // XXX This is now very broken + return ret; } diff --git a/tests/libpakfire/makefile.c b/tests/libpakfire/makefile.c index b7b7b5d63..273e3f2d6 100644 --- a/tests/libpakfire/makefile.c +++ b/tests/libpakfire/makefile.c @@ -181,14 +181,11 @@ static int test_dist_dummy(const struct test* t) { // Attempt to dist the dummy package ASSERT_SUCCESS(pakfire_dist(t->pakfire, - TEST_SRC_PATH "data/packages/dummy/dummy.nm", tmp, &filename)); + TEST_SRC_PATH "data/packages/dummy/dummy.nm", &archive, &filename)); // Check if filename is set ASSERT(filename); - // Check if we can read the archive - ASSERT_SUCCESS(pakfire_archive_open(&archive, t->pakfire, filename)); - // Extract all package metadata ASSERT_SUCCESS(pakfire_archive_make_package(archive, NULL, &package));