]> git.ipfire.org Git - pakfire.git/commitdiff
build: Refactor dependency scanning
authorMichael Tremer <michael.tremer@ipfire.org>
Tue, 6 Dec 2022 19:20:52 +0000 (19:20 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 6 Dec 2022 19:20:52 +0000 (19:20 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/build.c

index de97066724a11c986d2c688c48cc3abd5f173962..48c405378c149cc0b6a45e59921fb1ab7d64770f 100644 (file)
@@ -253,23 +253,25 @@ static int pakfire_build_run_script(
        return r;
 }
 
-struct pakfire_build_filelist_streamer {
+struct pakfire_find_deps_ctx {
+       struct pakfire_package* pkg;
+       int dep;
        struct pakfire_filelist* filelist;
-       char* output;
 };
 
-static int pakfire_build_filelist_streamer_one(struct pakfire* pakfire,
+static int pakfire_build_send_file(struct pakfire* pakfire,
                struct pakfire_file* file, void* data) {
        int* fd = (int*)data;
        int r;
 
+       // Fetch the path of the file
        const char* path = pakfire_file_get_path(file);
        if (!path) {
                ERROR(pakfire, "Received a file with an empty path\n");
                return 1;
        }
 
-       // Write path
+       // Write path to stdin
        r = dprintf(*fd, "%s\n", path);
        if (r < 0)
                return r;
@@ -277,102 +279,101 @@ static int pakfire_build_filelist_streamer_one(struct pakfire* pakfire,
        return 0;
 }
 
-static int pakfire_build_filelist_streamer_in(struct pakfire* pakfire, void* data, int fd) {
-       struct pakfire_build_filelist_streamer* streamer =
-               (struct pakfire_build_filelist_streamer*)data;
+static int pakfire_build_send_filelist(struct pakfire* pakfire, void* data, int fd) {
+       const struct pakfire_find_deps_ctx* ctx = (struct pakfire_find_deps_ctx*)data;
 
-       return pakfire_filelist_export(streamer->filelist, pakfire_build_filelist_streamer_one, &fd);
+       return pakfire_filelist_walk(ctx->filelist, pakfire_build_send_file, &fd);
 }
 
-static int pakfire_build_filelist_streamer_out(struct pakfire* pakfire,
+static int pakfire_build_process_deps(struct pakfire* pakfire,
                void* data, int priority, const char* buffer, const size_t length) {
-       struct pakfire_build_filelist_streamer* streamer =
-               (struct pakfire_build_filelist_streamer*)data;
+       const struct pakfire_find_deps_ctx* ctx = (struct pakfire_find_deps_ctx*)data;
+       int r;
+
+       switch (priority) {
+               // Add every dependency that we have received
+               case LOG_INFO:
+                       r = pakfire_package_add_dep(ctx->pkg, ctx->dep, buffer);
+                       if (r) {
+                               ERROR(pakfire, "Could not process dependency '%s': %m\n", buffer);
+                               return r;
+                       }
+                       break;
 
-       return pakfire_jail_capture_stdout(pakfire, streamer->output, priority, buffer, length);
+               // Send everything else to the default logger
+               default:
+                       ERROR(pakfire, "%s\n", buffer);
+                       break;
+       }
+
+       return 0;
 }
 
-static int pakfire_build_run_dependency_script(struct pakfire_build* build,
-               struct pakfire_package* pkg, int dep, const char* script, const char** args,
+/*
+       This function is a special way to run a script.
+
+       It will pipe the filelist into the standard input of the called script
+       and will read any dependencies from the standard output.
+*/
+static int pakfire_build_find_deps(struct pakfire_build* build,
+               struct pakfire_package* pkg, int dep, const char* script,
                struct pakfire_filelist* filelist) {
-       struct pakfire_build_filelist_streamer streamer = {
+
+       // Construct the context
+       struct pakfire_find_deps_ctx ctx = {
+               .pkg      = pkg,
+               .dep      = dep,
                .filelist = filelist,
-               .output   = NULL,
        };
        int r;
 
-       printf("streamer 1 = %p\n", &streamer);
+       // Pass the buildroot as first argument
+       const char* args[] = {
+               pakfire_relpath(build->pakfire, build->buildroot),
+               NULL,
+       };
 
        // Run the script
        r = pakfire_build_run_script(build, script, args,
-               pakfire_build_filelist_streamer_in, pakfire_build_filelist_streamer_out, &streamer);
-       if (r) {
+               pakfire_build_send_filelist, pakfire_build_process_deps, &ctx);
+       if (r)
                ERROR(build->pakfire, "%s returned with error %d\n", script, r);
-               goto ERROR;
-       }
-
-       // Add all output to the package
-       if (streamer.output) {
-               r = pakfire_str2deps(build->pakfire, pkg, dep, streamer.output);
-               if (r) {
-                       ERROR(build->pakfire, "Could not add dependencies: %m\n");
-                       goto ERROR;
-               }
-       }
-
-ERROR:
-       if (streamer.output)
-               free(streamer.output);
 
        return r;
 }
 
 static int pakfire_build_find_dependencies(struct pakfire_build* build,
-               struct pakfire_package* pkg, struct pakfire_filelist* filelist, const char* buildroot) {
-       char path[PATH_MAX];
+               struct pakfire_package* pkg, struct pakfire_filelist* filelist) {
        int r;
 
-       const char* root = pakfire_get_path(build->pakfire);
-
-       // Pass buildroot and the filelist as arguments
-       const char* args[] = {
-               buildroot, pakfire_path_relpath(root, path), NULL
-       };
-
        // Find all provides
-       r = pakfire_build_run_dependency_script(build, pkg,
-               PAKFIRE_PKG_PROVIDES, "find-provides", args, filelist);
+       r = pakfire_build_find_deps(build, pkg,
+               PAKFIRE_PKG_PROVIDES, "find-provides", filelist);
        if (r)
-               goto ERROR;
+               return r;
 
        // Find all Perl provides
-       r = pakfire_build_run_dependency_script(build, pkg,
-               PAKFIRE_PKG_PROVIDES, "perl.prov", args, filelist);
+       r = pakfire_build_find_deps(build, pkg,
+               PAKFIRE_PKG_PROVIDES, "perl.prov", filelist);
        if (r)
-               goto ERROR;
+               return r;
 
        // Find all requires
-       r = pakfire_build_run_dependency_script(build, pkg,
-               PAKFIRE_PKG_REQUIRES, "find-requires", args, filelist);
+       r = pakfire_build_find_deps(build, pkg,
+               PAKFIRE_PKG_REQUIRES, "find-requires", filelist);
        if (r)
-               goto ERROR;
+               return r;
 
        // Find all Perl requires
-       r = pakfire_build_run_dependency_script(build, pkg,
-               PAKFIRE_PKG_REQUIRES, "perl.req", args, filelist);
+       r = pakfire_build_find_deps(build, pkg,
+               PAKFIRE_PKG_REQUIRES, "perl.req", filelist);
        if (r)
-               goto ERROR;
-
-       // Success
-       r = 0;
-
-ERROR:
-       unlink(path);
+               return r;
 
-       return r;
+       return 0;
 }
 
-static int append_to_array(const char*** array, const char* s) {
+static int append_to_array(char*** array, const char* s) {
        unsigned int length = 0;
 
        // Determine the length of the existing array
@@ -448,8 +449,11 @@ static int pakfire_build_package_add_files(struct pakfire_build* build,
        if (!length)
                goto ERROR;
 
+       // Dump the filelist
+       pakfire_filelist_dump(filelist, 1);
+
        // Find dependencies
-       r = pakfire_build_find_dependencies(build, pkg, filelist, buildroot);
+       r = pakfire_build_find_dependencies(build, pkg, filelist);
        if (r) {
                ERROR(build->pakfire, "Finding dependencies failed: %m\n");
                goto ERROR;