]> git.ipfire.org Git - people/ms/pakfire.git/commitdiff
repo: Implement adding more files to repositories
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 20 Aug 2021 10:59:32 +0000 (10:59 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 20 Aug 2021 10:59:32 +0000 (10:59 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/_pakfire/pakfire.c
src/libpakfire/include/pakfire/repo.h
src/libpakfire/repo.c
src/scripts/pakfire-builder.in

index f3675e44a6b87cc19b94f1e96280d2dd3179cb5a..f6784db9e50953e7d88ee425a20710da371aa62a 100644 (file)
@@ -1052,21 +1052,69 @@ static PyObject* Pakfire_open(PakfireObject* self, PyObject* args) {
 }
 
 static PyObject* Pakfire_repo_compose(PakfireObject* self, PyObject* args, PyObject* kwargs) {
-       char* kwlist[] = { "path", NULL };
+       char* kwlist[] = { "path", "files", NULL };
        const char* path = NULL;
+       PyObject* list = NULL;
 
-       if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s", kwlist, &path))
+       PyObject* ret = NULL;
+
+       if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sO", kwlist, &path, &list))
+               return NULL;
+
+       // List must be a sequence
+       if (!PySequence_Check(list)) {
+               PyErr_SetString(PyExc_ValueError, "Expected a sequence.");
                return NULL;
+       }
 
        const int flags = 0;
 
-       int r = pakfire_repo_compose(self->pakfire, path, flags);
+       // How many new files do we have?
+       ssize_t num_files = PySequence_Length(list);
+       if (num_files < 0)
+               return NULL;
+
+       // Allocate files array
+       const char** files = calloc(num_files + 1, sizeof(*files));
+       if (!files) {
+               PyErr_SetFromErrno(PyExc_OSError);
+               return NULL;
+       }
+
+       for (int i = 0; i < num_files; i++) {
+               PyObject* file = PySequence_GetItem(list, i);
+               if (!file)
+                       goto ERROR;
+
+               // Check if file is a Unicode object
+               if (!PyUnicode_Check(file)) {
+                       PyErr_SetString(PyExc_ValueError, "Expected a string.");
+                       goto ERROR;
+               }
+
+               // Add pointer to string to files array
+               files[i] = PyUnicode_AsUTF8(file);
+               if (!files[i])
+                       goto ERROR;
+
+               Py_DECREF(file);
+       }
+
+       int r = pakfire_repo_compose(self->pakfire, path, flags, files);
        if (r) {
                PyErr_SetFromErrno(PyExc_OSError);
                return NULL;
        }
 
-       Py_RETURN_NONE;
+       // Return None on success
+       ret = Py_None;
+       Py_INCREF(ret);
+
+ERROR:
+       if (files)
+               free(files);
+
+       return ret;
 }
 
 static struct PyMethodDef Pakfire_methods[] = {
index c7700f27755b8e9f463f8d93bd3d4d5ef4797610..0972d200d986c1ac641251844b0282cce3a83319 100644 (file)
@@ -84,7 +84,8 @@ int pakfire_repo_refresh(struct pakfire_repo* repo, int force);
 
 // Compose
 
-int pakfire_repo_compose(struct pakfire* pakfire, const char* path, int flags);
+int pakfire_repo_compose(struct pakfire* pakfire, const char* path, int flags,
+       const char** files);
 
 #ifdef PAKFIRE_PRIVATE
 
index fa46606fbb092bc842a238fb13a07af18b2626f8..d07d5931e73f035cb48d763ee2a943554ea8e772 100644 (file)
@@ -1103,7 +1103,8 @@ static int pakfire_repo_write_metadata(struct pakfire_repo* repo) {
        return 0;
 }
 
-PAKFIRE_EXPORT int pakfire_repo_compose(struct pakfire* pakfire, const char* path, int flags) {
+PAKFIRE_EXPORT int pakfire_repo_compose(struct pakfire* pakfire, const char* path,
+               int flags, const char** files) {
        struct pakfire_repo* repo = NULL;
        int r;
 
@@ -1113,6 +1114,14 @@ PAKFIRE_EXPORT int pakfire_repo_compose(struct pakfire* pakfire, const char* pat
                return 1;
        }
 
+       size_t num_files = 0;
+
+       // Count files
+       if (files) {
+               for (const char** file = files; *file; file++)
+                       num_files++;
+       }
+
        char baseurl[PATH_MAX];
 
        // Prefix path with file:// to form baseurl
@@ -1141,7 +1150,64 @@ PAKFIRE_EXPORT int pakfire_repo_compose(struct pakfire* pakfire, const char* pat
                goto ERROR;
        }
 
-       // XXX Add more files
+       struct pakfire_archive* archive = NULL;
+       struct pakfire_package* package = NULL;
+       char destination_path[PATH_MAX];
+
+       DEBUG(pakfire, "Adding %zu file(s) to the repository\n", num_files);
+
+       // Add more files
+       if (files) {
+               for (const char** file = files; *file; file++) {
+                       DEBUG(pakfire, "Adding %s to repository...\n", *file);
+
+                       // Open source archive
+                       r = pakfire_archive_open(&archive, pakfire, *file);
+                       if (r) {
+                               ERROR(pakfire, "Could not open %s: %m\n", *file);
+                               goto OUT;
+                       }
+
+                       // Add package metadata
+                       r = pakfire_repo_add_archive(repo, archive, &package);
+                       if (r) {
+                               ERROR(pakfire, "Could not add %s to the repository: %m\n", *file);
+                               goto OUT;
+                       }
+
+                       const char* filename = pakfire_package_get_filename(package);
+
+                       // Make new path
+                       r = pakfire_path_join(destination_path, path, filename);
+                       if (r < 0)
+                               goto OUT;
+
+                       // Copying archive to destination
+                       r = pakfire_archive_copy(archive, destination_path);
+                       if (r) {
+                               ERROR(pakfire, "Could not copy archive to %s: %m\n", destination_path);
+                               goto OUT;
+                       }
+
+                       const char* repo_path = pakfire_path_relpath(path, destination_path);
+
+                       // Update package location relative to the repository directory
+                       pakfire_package_set_path(package, repo_path);
+
+OUT:
+                       if (archive) {
+                               pakfire_archive_unref(archive);
+                               archive = NULL;
+                       }
+                       if (package) {
+                               pakfire_package_unref(package);
+                               package = NULL;
+                       }
+
+                       if (r)
+                               goto ERROR;
+               }
+       }
 
        // Write metadata to disk
        r = pakfire_repo_write_metadata(repo);
index c5419e34934dc5466044464ecc34ede343cdf97e..80b4e1fadcde5b7fad46b725f8f34641f80c76e9 100644 (file)
@@ -137,8 +137,8 @@ class Cli(object):
                repo_compose.add_argument("path",
                        help=_("The path to the repository"),
                )
-               repo_compose.add_argument("archive", nargs="+",
-                       help=_("Archives to be added to this repository")
+               repo_compose.add_argument("file", nargs="+",
+                       help=_("Files to be added to this repository")
                )
                repo_compose.add_argument("--key",
                        help=_("Key used to sign archives"),
@@ -294,7 +294,7 @@ class Cli(object):
                        Composes a repository
                """
                p = self.pakfire(ns)
-               p.repo_compose(ns.path)
+               p.repo_compose(ns.path, files=ns.file)
 
        def _shell(self, ns):
                """