How to get dependency url from build.zig.zon in build script (recursively)

I’m trying to automate getting licenses and readmes from my dependencies, as well as urls in order to link to library source code in my gui (I’m trying to statically compile, and I want to be extra cautious about copyleft compliance). Right now, there seems to be no built-in way to parse the zon file directly, as my dependencies’ zon files aren’t available at compile time from the perspective of my build script, and I don’t know the type ahead of time since dependencies is a struct with named fields. I’m currently looking into using std.zig.Zoir directly, but I want to be sure there isn’t a better way before continuing.

Thanks!

create a script that goes through zig-pkg, you can then wire that up in the build system to provide the results to your code

The build system generates a file, dependencies.zig, which contains information about all fetched packages (more details in this recent answer of mine). This file is exposed by the build runner and can be accessed from your build script:

const build_runner = @import("root");
const packages = build_runner.dependencies.packages;
inline for (@typeInfo(packages).@"struct".decl_names |hash| {
    const package = @field(packages, hash);
    // Check for a 'const available = false;' decl;
    // a package that is a lazy dependency might not have been fetched yet.
    const available = !@hasDecl(package, "available") or package.available;
    if (available) {
        const build_zig_zon_path = b.pathJoin(&.{ package.build_root, "build.zig.zon" });
        // ...Do something with 'build_zig_zon_path'...
    }
}

This way you can programmatically iterate over all potential build.zig.zon paths for all packages.
Do with this whatever you want; for example, you could compile a utility Zig program as part of your build for processing information in build.zig.zon files, run it with b.runArtifact and pass all paths as arguments to the run step.

Note that the above loop won’t cover the root build.zig zon, which you will need to include in your processing logic manually. Also note that build.zig.zon is optional and may not exist for all packages, so your processing logic will need to account for that possibility.