]> git.ipfire.org Git - pakfire.git/commitdiff
packager: Return an archive
authorMichael Tremer <michael.tremer@ipfire.org>
Sat, 11 Jan 2025 16:32:39 +0000 (16:32 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sat, 11 Jan 2025 16:32:39 +0000 (16:32 +0000)
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 <michael.tremer@ipfire.org>
src/cli/lib/dist.c
src/pakfire/build.c
src/pakfire/dist.c
src/pakfire/dist.h
src/pakfire/packager.c
src/pakfire/packager.h
src/pakfire/pakfire.c
src/python/pakfire.c
tests/libpakfire/makefile.c

index 684d4349dfa0de33636126fa3eeb30b372e9f4a7..b8a9977179b043007acb43ad3203eb5478139348 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <pakfire/dist.h>
 #include <pakfire/pakfire.h>
+#include <pakfire/path.h>
 
 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;
                }
        }
index b0a6857a91326f20f5fea233089a99d3ed4cf735..a91a30803e2a4111e7041ae23d89b4759db5fabb 100644 (file)
@@ -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)
index 6e251ffef5ff1294cf6faed5e86bef4faba1e09b..71ebe06014bb799717303edf70cb494f84d905aa 100644 (file)
@@ -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);
 
index 587757ef89426b33805e4d8a85ba80f487d4d118..9cdc9c176c6855d371b7b9b0e47f39cbf1d65799 100644 (file)
 #ifndef PAKFIRE_DIST_H
 #define PAKFIRE_DIST_H
 
+#include <pakfire/archive.h>
 #include <pakfire/pakfire.h>
 #include <pakfire/parser.h>
 
-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);
index 98c807058fe09b95409ba4636577b0a9f19bbf80..b5835407d56512eb35e2e3ec3b9238f0e7745b41 100644 (file)
@@ -40,6 +40,7 @@
 #include <pakfire/package.h>
 #include <pakfire/packager.h>
 #include <pakfire/pakfire.h>
+#include <pakfire/path.h>
 #include <pakfire/pwd.h>
 #include <pakfire/string.h>
 #include <pakfire/util.h>
@@ -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;
 }
 
index 7025da6ec333a637714fe98535155275a14de85c..f207f440149e0b63d84c3229a9273bc6e71470d7 100644 (file)
@@ -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);
index 518fd6512a5c8bee371088405897222acc7001bb..76f442d8bde8d6f4b11619cba7806d2c9d84256e 100644 (file)
@@ -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;
 }
index c8596a044b04d897f99e6d98e5009b2e8c10896f..0c04a31b141df7ba04a9dd61ac8c696821561e88 100644 (file)
@@ -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;
 }
 
index b7b7b5d63bf82ba4a2c876d8ecd9a384198a87c3..273e3f2d631b70f26776d8afd7084f4d9a0d7851 100644 (file)
@@ -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));