Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Construct SBOM from a provided Manifest.toml #21

Open
hannahilea opened this issue Sep 5, 2023 · 3 comments
Open

Construct SBOM from a provided Manifest.toml #21

hannahilea opened this issue Sep 5, 2023 · 3 comments

Comments

@hannahilea
Copy link
Contributor

The current example of SBOM generation for a package involves creating a new environment, adding just that package to it, and then constructing an SBOM from there.

Rather than instantiating an environment and then constructing an SBOM from that environment, it would be nice to provide an entrypoint that works directly from the Manifest.toml, without doing any amount of environment resolution (which may re-resolve the provided Manifest.toml in a way that introduces changes, especially if the Julia version from the original manifest and the current environment are different).

@SamuraiAku
Copy link
Owner

The difficulty with this idea is that it requires a completely separate set of code to process the Manifest.toml file and then populate a new Pkg.API.PackageInfo Dictionary so that the rest of the code can use the information. And Pkg already does all that work already when it reads the Project.toml and Manifest.toml, so it's duplicative.

Reading the documentation on Pkg.instantiate, I interpret it as saying that if the Manifest.toml file is present it will not do any re-resolution. If the version of Julia in use is incompatible with items in the Manifest, that is an edge case and it would be interesting to know what Pkg will do in that situation. Possibly that is a case we don't support at this time.

If Pkg.instantiate is combined with Pkg.activate(; temp=true) then I think we can get the effect called for here, where the Manifest is instantiated within a fresh environment, the SBOM is created and the users own environment is untouched.

@SamuraiAku
Copy link
Owner

I've got a version of this idea in the tests now. I created a set of dummy packages and use a manifest to pull them in and create an SBOM. Shows it can be done.

@peteristhegreat
Copy link

peteristhegreat commented Oct 10, 2024

I wrote a bunch of code around inspection of Manifest.toml using Pkg utilities without instantiating a project. The only item it needs is using Pkg. In my use case I wasn't using private registries, but there were several "develop" packages in the local file system. It works in Julia 1.6 and I just tested it on Julia 1.11 and works fine.

using Pkg

function inspect_julia_project_dir(julia_project_dir_in)
    global julia_project_dir = realpath(abspath(julia_project_dir_in))
    global manifest_path = abspath(joinpath(julia_project_dir, "Manifest.toml"))
    global manifest_dict = Pkg.TOML.parsefile(manifest_path)
    global project_dict = Pkg.TOML.parsefile(joinpath(julia_project_dir, "Project.toml"))
    global application = get(project_dict, "name", basename(julia_project_dir))
end

function pkgdir_from_manifest(package_name::String)
    if package_name == application
        return julia_project_dir
    end
    if !haskey(manifest_dict, package_name)
        error("No such package \"$package_name\" found in $manifest_path")
    end
    if length(manifest_dict[package_name]) != 1
        error("Ambiguous entry list for \"$package_name\" in $manifest_path")
    end
    package_dict = manifest_dict[package_name][1]
    if haskey(package_dict, "path")
        return abspath(joinpath(julia_project_dir, package_dict["path"]))
    end

    if haskey(package_dict, "uuid") && haskey(package_dict, "git-tree-sha1")
        return Pkg.Operations.find_installed(package_name,
            Pkg.Types.UUID(package_dict["uuid"]),
            Pkg.Types.SHA1(package_dict["git-tree-sha1"]))
    end

    if haskey(package_dict, "uuid")
        return abspath(joinpath(dirname(Base.find_package(package_name)), ".."))
    end

    @show package_dict
    error("Missing info for \"$package_name\" in $manifest_path: " *
        "Need uuid and git-tree-sha1 or path to look up the path to $package_name")
    return ""
end

## Usage
# inspect_julia_project_dir("path/to/julia/Project")
#
# pkgdir_from_manifest("SomePackage")
# "/Users/username/.julia/packages/SomePackage/abcd1"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants