From: Michael Tremer Date: Fri, 10 Jan 2025 17:52:49 +0000 (+0000) Subject: build: Refactor processing Perl dependencies X-Git-Tag: 0.9.30~474 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=dc127df238c140bf455c05abf46e263066f0b48a;p=pakfire.git build: Refactor processing Perl dependencies Signed-off-by: Michael Tremer --- diff --git a/src/pakfire/build.c b/src/pakfire/build.c index 4118102df..7ffc15d8a 100644 --- a/src/pakfire/build.c +++ b/src/pakfire/build.c @@ -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: