diff --git a/fancy_toys.jl b/fancy_toys.jl index 57c1057ac27..e71dd6ca2ef 100644 --- a/fancy_toys.jl +++ b/fancy_toys.jl @@ -2,6 +2,9 @@ # developers. These utilities can be employed in builder files. using BinaryBuilder, Pkg, LibGit2 +# Note: if you only need `get_addable_spec`, just add the following line to your recipe +# instead of including this file. This is reexported here for backward compatibility. +using BinaryBuilderBase: get_addable_spec """ should_build_platform(platform) -> Bool @@ -33,82 +36,3 @@ function should_build_platform(platform) return iszero(length(requested_platforms)) end end - -""" - get_tree_hash(tree::LibGit2.GitTree) - -Given a `GitTree`, get the `GitHash` that identifies it. -""" -function get_tree_hash(tree::LibGit2.GitTree) - oid_ptr = Ref(LibGit2.GitHash()) - oid_ptr = ccall((:git_tree_id, :libgit2), Ptr{LibGit2.GitHash}, (Ptr{Cvoid},), tree.ptr) - oid_ptr == C_NULL && throw("bad tree ID: $tree") - return unsafe_load(oid_ptr) -end - -""" - get_addable_spec(name, version) - -Given a JLL name and registered version, return a `PackageSpec` that, when passed as a -`Dependency`, ensures that exactly that version will be installed. Example usage: - - dependencies = [ - BuildDependency(get_addable_spec("LLVM_jll", v"9.0.1+0")), - ] -""" -function get_addable_spec(name::AbstractString, version::VersionNumber) - Pkg.Registry.update() - ctx = Pkg.Types.Context() - - # First, resolve the UUID - uuid = first(Pkg.Types.registry_resolve!(ctx, Pkg.Types.PackageSpec(name=name))).uuid - - # Next, determine the tree hash from the registry - tree_hashes = Base.SHA1[] - paths = Pkg.Operations.registered_paths(ctx, uuid) - for path in paths - vers = Pkg.Operations.load_versions(ctx, path; include_yanked = true) - tree_hash = get(vers, version, nothing) - tree_hash !== nothing && push!(tree_hashes, tree_hash) - end - - if isempty(tree_hashes) - error("Unable to find mapping for $(name) v$(version)") - end - tree_hash_sha1 = first(tree_hashes) - tree_hash_bytes = tree_hash_sha1.bytes - - # Once we have a tree hash, turn that into a git commit sha - url = "https://github.com/JuliaBinaryWrappers/$(name).jl" - git_commit_sha = nothing - mktempdir() do dir - repo = LibGit2.clone(url, dir) - LibGit2.with(LibGit2.GitRevWalker(repo)) do walker - LibGit2.push_head!(walker) - for oid in walker - tree = LibGit2.peel(LibGit2.GitTree, LibGit2.GitCommit(repo, oid)) - if all(get_tree_hash(tree).val .== tree_hash_bytes) - git_commit_sha = LibGit2.string(oid) - break - end - end - end - end - - if git_commit_sha === nothing - error("Unable to find corresponding revision in $(name) v$(version) for tree hash $(bytes2hex(tree_hash_bytes))") - end - - @static if VERSION >= v"1.4" - repo=Pkg.Types.GitRepo(rev=git_commit_sha, source=url) - else - repo=Pkg.Types.GitRepo(rev=git_commit_sha, url=url) - end - return Pkg.Types.PackageSpec( - name=name, - uuid=uuid, - version=version, - tree_hash=tree_hash_sha1, - repo=repo, - ) -end