]> git.ipfire.org Git - pakfire.git/commitdiff
build: Refactor processing Perl dependencies
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 10 Jan 2025 17:52:49 +0000 (17:52 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 10 Jan 2025 17:52:49 +0000 (17:52 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/pakfire/build.c

index 4118102df6d2742de732836d41bdc0ec3cf8d17a..7ffc15d8acb4ede91f9385ef0d4d2fd3be95cebd 100644 (file)
@@ -302,119 +302,9 @@ static int pakfire_build_run_script(
 struct pakfire_find_deps_ctx {
        struct pakfire_build* build;
        struct pakfire_package* pkg;
-       int dep;
-       struct pakfire_scriptlet* scriptlet;
-       int class;
-
        struct pakfire_filelist* filelist;
-       unsigned int i;
 };
 
-static ssize_t pakfire_build_send_filelist(
-               struct pakfire_ctx* ctx, void* data, char* buffer, size_t length) {
-       struct pakfire_find_deps_ctx* p = (struct pakfire_find_deps_ctx*)data;
-       struct pakfire_file* file = NULL;
-       const char* path = NULL;
-       int r = 0;
-
-       for (;;) {
-               // Check if we have reached the end of the filelist
-               if (p->i >= pakfire_filelist_length(p->filelist))
-                       return 0;
-
-               // Fetch the next file
-               file = pakfire_filelist_get(p->filelist, p->i);
-               if (!file) {
-                       DEBUG(ctx, "Could not fetch file %u: %m\n", p->i);
-                       r = -errno;
-                       goto ERROR;
-               }
-
-               // Skip files that don't match what we are looking for
-               if (p->class && !pakfire_file_matches_class(file, p->class))
-                       goto SKIP;
-
-               // Fetch the path of the file
-               path = pakfire_file_get_path(file);
-               if (!path) {
-                       ERROR(ctx, "Received a file with an empty path\n");
-                       r = -errno;
-                       goto ERROR;
-               }
-
-               // Write path to the buffer
-               r = snprintf(buffer, length, "%s\n", path);
-               if (r < 0)
-                       goto ERROR;
-
-               // If the output could not be written, we ask to be called again later
-               else if (r >= (ssize_t)length) {
-                       r = -EAGAIN;
-                       goto ERROR;
-               }
-
-SKIP:
-               // Move on to the next file
-               p->i++;
-
-               pakfire_file_unref(file);
-               file = NULL;
-       }
-
-ERROR:
-       if (file)
-               pakfire_file_unref(file);
-
-       return r;
-}
-
-static int pakfire_build_process_deps(struct pakfire_ctx* ctx, void* data,
-               const char* buffer, const size_t length) {
-       const struct pakfire_find_deps_ctx* p = (struct pakfire_find_deps_ctx*)data;
-       char dep[PATH_MAX];
-       int r = 0;
-
-       // Nothing to do for an empty buffer
-       if (!buffer || !*buffer)
-               return 0;
-
-       // Copy the dependency to the stack (and remove the trailing newline)
-       r = pakfire_string_format(dep, "%.*s", (int)length - 1, buffer);
-       if (r < 0)
-               return r;
-
-       DEBUG(ctx, "Processing dependency: %s\n", dep);
-
-       // Filter out any dependencies that are provided by this package
-       if (p->dep == PAKFIRE_PKG_REQUIRES) {
-               // If this is a file, we check if it is on the filelist
-               if (pakfire_filelist_contains(p->filelist, dep))
-                       goto SKIP;
-       }
-
-       // Add dependency
-       r = pakfire_package_add_dep(p->pkg, p->dep, "%s", dep);
-       if (r < 0) {
-               ERROR(ctx, "Could not process dependency '%s': %s\n", dep, strerror(-r));
-               goto ERROR;
-       }
-
-       // We have consumed the entire buffer
-       r = length;
-
-       goto ERROR;
-
-SKIP:
-       DEBUG(ctx, "Skipping dependency that is provided by the package itself: %s\n", dep);
-
-       // Return how many bytes we have consumed
-       r = length;
-
-ERROR:
-
-       return r;
-}
-
 static int pakfire_build_process_pkgconfig_dep(struct pakfire_package* pkg,
                const enum pakfire_package_key key, const char* line, const size_t length) {
        char buffer[PATH_MAX];
@@ -809,44 +699,88 @@ static int pakfire_build_find_requires(
 }
 
 /*
-       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.
+       Perl Dependency Stuff
 */
-static int pakfire_build_find_deps(struct pakfire_build* build,
-               struct pakfire_package* pkg, int dep, const char* script,
-               struct pakfire_filelist* filelist, int class) {
-       // Construct the context
-       struct pakfire_find_deps_ctx ctx = {
-               .build    = build,
-               .pkg      = pkg,
-               .dep      = dep,
-               .class    = class,
 
-               // Filelist
-               .filelist = filelist,
-               .i        = 0,
-       };
+static int pakfire_build_find_perl_files(
+               struct pakfire_ctx* ctx, struct pakfire_file* file, void* data) {
+       struct pakfire_filelist* perlfiles = data;
+
+       // Add all perl files
+       if (pakfire_file_matches_class(file, PAKFIRE_FILE_PERL))
+               return pakfire_filelist_add(perlfiles, file);
+
+       return 0;
+}
+
+static int pakfire_build_add_perl_dep(struct pakfire_ctx* ctx, struct pakfire_package* pkg,
+               const enum pakfire_package_key key, const char* line, size_t length) {
        int r;
 
-       // Skip calling the script if class doesn't match
-       if (class && !pakfire_filelist_matches_class(filelist, class)) {
-               DEBUG(build->ctx, "Skipping calling %s as class does not match\n", script);
-               return 0;
-       }
+       // Add the dependency
+       r = pakfire_package_add_dep(pkg, key, "%.*s", (int)length, line);
+       if (r < 0)
+               return r;
 
-       // Pass the buildroot as first argument
+       return length;
+}
+
+static int pakfire_build_add_perl_provides(struct pakfire_ctx* ctx,
+               void* data, const char* line, size_t length) {
+       struct pakfire_package* pkg = data;
+
+       return pakfire_build_add_perl_dep(ctx, pkg, PAKFIRE_PKG_PROVIDES, line, length);
+}
+
+static int pakfire_build_add_perl_requires(struct pakfire_ctx* ctx,
+               void* data, const char* line, size_t length) {
+       struct pakfire_package* pkg = data;
+
+       return pakfire_build_add_perl_dep(ctx, pkg, PAKFIRE_PKG_REQUIRES, line, length);
+}
+
+static int pakfire_build_find_perl_deps(struct pakfire_build* build,
+               struct pakfire_package* pkg, struct pakfire_filelist* filelist) {
+       struct pakfire_filelist* perlfiles = NULL;
        const char* args[] = {
                build->buildroot,
                NULL,
        };
+       int r;
 
-       // Run the script
-       r = pakfire_build_run_script(build, script, args,
-                       pakfire_build_send_filelist, &ctx, pakfire_build_process_deps, &ctx);
-       if (r)
-               ERROR(build->ctx, "%s returned with error %d\n", script, r);
+       // If we don't have any Perl files at all, there is nothing to do
+       if (!pakfire_filelist_matches_class(filelist, PAKFIRE_FILE_PERL))
+               return 0;
+
+       // Create a new filelist
+       r = pakfire_filelist_create(&perlfiles, build->pakfire);
+       if (r < 0)
+               goto ERROR;
+
+       // Select all Perl files
+       r = pakfire_filelist_walk(filelist, pakfire_build_find_perl_files, perlfiles, 0, NULL);
+       if (r < 0)
+               goto ERROR;
+
+       struct pakfire_pty_filelist input = {
+               .filelist = perlfiles,
+       };
+
+       // Find provides
+       r = pakfire_build_run_script(build, "perl.prov", args,
+                       pakfire_pty_send_filelist, &input, pakfire_build_add_perl_provides, pkg);
+       if (r < 0)
+               goto ERROR;
+
+       // Find requires
+       r = pakfire_build_run_script(build, "perl.req", args,
+                       pakfire_pty_send_filelist, &input, pakfire_build_add_perl_requires, pkg);
+       if (r < 0)
+               goto ERROR;
+
+ERROR:
+       if (perlfiles)
+               pakfire_filelist_unref(perlfiles);
 
        return r;
 }
@@ -885,21 +819,14 @@ static int pakfire_build_find_dependencies(struct pakfire_build* build,
        if (r < 0)
                goto ERROR;
 
-       // Find all Perl provides
-       r = pakfire_build_find_deps(build, pkg,
-               PAKFIRE_PKG_PROVIDES, "perl.prov", filelist, PAKFIRE_FILE_PERL);
-       if (r)
-               goto ERROR;
-
        // Find all requires
        r = pakfire_filelist_walk(filelist, pakfire_build_find_requires, &deps, 0, NULL);
        if (r < 0)
                goto ERROR;
 
-       // Find all Perl requires
-       r = pakfire_build_find_deps(build, pkg,
-               PAKFIRE_PKG_REQUIRES, "perl.req", filelist, PAKFIRE_FILE_PERL);
-       if (r)
+       // Find Perl dependencies
+       r = pakfire_build_find_perl_deps(build, pkg, filelist);
+       if (r < 0)
                goto ERROR;
 
 ERROR: