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

wizard: Support for {Runtime,Build,HostBuild}Dependency #1295

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/wizard/deploy.jl
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ function print_build_tarballs(io::IO, state::WizardState)

if length(state.dependencies) >= 1
function psrepr(ps)
s = "\n Dependency(PackageSpec(name=\"$(getname(ps))\""
s = "\n $(typeof(ps))(PackageSpec(name=\"$(getname(ps))\""
if !isnothing(getpkg(ps).uuid)
s *= ", uuid=\"$(getpkg(ps).uuid)\""
end
Expand Down
48 changes: 35 additions & 13 deletions src/wizard/interactive_build.jl
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ function step4(state::WizardState, ur::Runner, platform::AbstractPlatform,
if choice == 1
# Link dependencies into the prefix again
concrete_platform = get_concrete_platform(platform, state)
artifact_paths = setup_dependencies(prefix, getpkg.(state.dependencies), concrete_platform)
artifact_paths = setup_dependencies(prefix, Pkg.Types.PackageSpec[getpkg(dep) for dep in state.dependencies], concrete_platform)
return step3_interactive(state, prefix, platform, ur, build_path, artifact_paths)
elseif choice == 2
state.step = :step3
Expand Down Expand Up @@ -212,7 +212,10 @@ function diff_srcdir(state::WizardState, prefix::Prefix, ur::Runner)
return false
end

function bb_add(client, state::WizardState, prefix::Prefix, prefix_artifacts::Union{Dict{Prefix,Vector{String}}, Nothing}, platform::AbstractPlatform, jll::AbstractString)
function bb_add(client, state::WizardState, prefix::Prefix, prefix_artifacts::Union{Dict{Prefix,Vector{String}}, Nothing}, platform::AbstractPlatform, dep_kind::Type, jll::AbstractString)
if !endswith(jll, "_jll")
jll *= "_jll"
end
if any(dep->getpkg(dep).name == jll, state.dependencies)
println(client, "ERROR: Package was already added")
return
Expand All @@ -221,18 +224,19 @@ function bb_add(client, state::WizardState, prefix::Prefix, prefix_artifacts::Un
println(client, "ERROR: `bb add` not available in this context (if you think it should be, file an issue)!")
return
end
new_dep = Dependency(jll)
new_dep = dep_kind(jll)
try
# This will redo some work, but that may be ok
concrete_platform = get_concrete_platform(platform, state)
# Clear out the prefix artifacts directory in case this change caused
# any previous dependencies to change
cleanup_dependencies(prefix, get(prefix_artifacts, prefix, String[]), concrete_platform)
pkgs = getpkg.([state.dependencies; new_dep])
pkgs = Pkg.Types.PackageSpec[getpkg(dep) for dep in [state.dependencies; new_dep]]
prefix_artifacts[prefix] = setup_dependencies(prefix, pkgs, concrete_platform)
push!(state.dependencies, new_dep)
println(client, "[bb] Added dependency $jll. The dependency is available for use.")
catch e
showerror(client, e)
showerror(client, e, catch_backtrace())
end
end

Expand All @@ -247,10 +251,24 @@ function bb_parser()
action = :command
end

add_arg_group!(s["add"], "dependency kind", exclusive=true)
@add_arg_table! s["add"] begin
"--build"
help = "This is a build-only dependency (e.g. for header-only libraries)"
nargs = 0
"--runtime"
help = "This is a runtime-only dependency (e.g. for runtime assets)"
nargs = 0
"--hostbuild"
help = "This is a host build-time dependency (e.g. cross-compile build tools)"
nargs = 0
end

add_arg_group!(s["add"], "jll name")
@add_arg_table! s["add"] begin
"jll"
help = "The jll to add"
required = true
help = "The jll to add"
required = true
end

s
Expand All @@ -276,7 +294,11 @@ function setup_bb_service(state::WizardState, prefix, platform, prefix_artifacts
parsed = parse_args(ARGS, s)
if parsed == nothing
elseif parsed["%COMMAND%"] == "add"
bb_add(client, state, prefix, prefix_artifacts, platform, parsed["add"]["jll"])
dep_kind = parsed["add"]["build"] ? BuildDependency :
parsed["add"]["runtime"] ? RuntimeDependency :
parsed["add"]["hostbuild"] ? HostBuildDependency :
Dependency
bb_add(client, state, prefix, prefix_artifacts, platform, dep_kind, parsed["add"]["jll"])
end
close(client)
catch e
Expand Down Expand Up @@ -439,7 +461,7 @@ function step3_retry(state::WizardState)
mkpath(build_path)
concrete_platform = get_concrete_platform(platform, state)
prefix = setup_workspace(build_path, vcat(state.source_files, state.patches), concrete_platform; verbose=false)
artifact_paths = setup_dependencies(prefix, getpkg.(state.dependencies), concrete_platform)
artifact_paths = setup_dependencies(prefix, Pkg.Types.PackageSpec[getpkg(dep) for dep in state.dependencies], concrete_platform)

ur = preferred_runner()(
prefix.path;
Expand Down Expand Up @@ -526,7 +548,7 @@ function step34(state::WizardState)
concrete_platform;
verbose=false
)
artifact_paths = setup_dependencies(prefix, getpkg.(state.dependencies), concrete_platform; verbose=true)
artifact_paths = setup_dependencies(prefix, Pkg.Types.PackageSpec[getpkg(dep) for dep in state.dependencies], concrete_platform; verbose=true)

provide_hints(state, joinpath(prefix, "srcdir"))

Expand Down Expand Up @@ -571,7 +593,7 @@ function step5_internal(state::WizardState, platform::AbstractPlatform)
prefix = setup_workspace(build_path, vcat(state.source_files, state.patches), concrete_platform; verbose=true)
# Clean up artifacts in case there are some
cleanup_dependencies(prefix, get(prefix_artifacts, prefix, String[]), concrete_platform)
artifact_paths = setup_dependencies(prefix, getpkg.(state.dependencies), concrete_platform; verbose=true)
artifact_paths = setup_dependencies(prefix, Pkg.Types.PackageSpec[getpkg(dep) for dep in state.dependencies], concrete_platform; verbose=true)
# Record newly added artifacts for this prefix
prefix_artifacts[prefix] = artifact_paths
ur = preferred_runner()(
Expand Down Expand Up @@ -648,7 +670,7 @@ function step5_internal(state::WizardState, platform::AbstractPlatform)
)
# Clean up artifacts in case there are some
cleanup_dependencies(prefix, get(prefix_artifacts, prefix, String[]), concrete_platform)
artifact_paths = setup_dependencies(prefix, getpkg.(state.dependencies), platform; verbose=true)
artifact_paths = setup_dependencies(prefix, Pkg.Types.PackageSpec[getpkg(dep) for dep in state.dependencies], platform; verbose=true)
# Record newly added artifacts for this prefix
prefix_artifacts[prefix] = artifact_paths

Expand Down Expand Up @@ -782,7 +804,7 @@ function step5c(state::WizardState)
concrete_platform;
verbose=false,
)
artifact_paths = setup_dependencies(prefix, getpkg.(state.dependencies), concrete_platform; verbose=false)
artifact_paths = setup_dependencies(prefix, Pkg.Types.PackageSpec[getpkg(dep) for dep in state.dependencies], concrete_platform; verbose=false)
ur = preferred_runner()(
prefix.path;
cwd="/workspace/srcdir",
Expand Down
27 changes: 25 additions & 2 deletions src/wizard/obtain_source.jl
Original file line number Diff line number Diff line change
Expand Up @@ -231,25 +231,40 @@ function obtain_binary_deps(state::WizardState)
terminal = TTYTerminal("xterm", state.ins, state.outs, state.outs)
local resolved_deps
jll_names = String[]
dependencies = AbstractDependency[]
while true
jll_name = nonempty_line_prompt("package name", "Enter JLL package name:"; ins=state.ins, outs=state.outs)
if !endswith(jll_name, "_jll")
jll_name *= "_jll"
end

choices = Pair{String, Type}[
"Build and runtime target dependency (e.g. libraries) [default]" => Dependency,
"Build-only dependency (e.g. header-only libraries)" => BuildDependency,
"Runtime-only dependency (e.g. runtime assets)" => RuntimeDependency,
"Host-build dependency (e.g. cross-compile build tools)" => HostBuildDependency,
]

selected_kind = request(terminal, "What kind of dependency is this?",
RadioMenu(map(x->x[1], choices); charset=:ascii))

dep_kind = choices[selected_kind][2]

# Check to see if this JLL package name can be resolved:
push!(jll_names, jll_name)
all_resolved, resolved_deps = resolve_jlls(Dependency.(jll_names), outs=state.outs)
push!(dependencies, dep_kind(jll_name))
all_resolved, resolved_deps = resolve_jlls(dependencies, outs=state.outs)

if !all_resolved
pop!(jll_names)
pop!(jll_names); pop!(dependencies)
if yn_prompt(state, "Unable to resolve \"$(jll_name)\"; enter a new one?", :y) != :y
break
else
continue
end
end

println(state.outs)
q = "Would you like to provide additional dependencies? "
if yn_prompt(state, q, :n) != :y
break
Expand All @@ -260,6 +275,14 @@ function obtain_binary_deps(state::WizardState)
state.dependencies = filter(x -> getname(x) ∈ jll_names, resolved_deps)
end
println(state.outs)
print(state.outs, """
Dependency selection complete.
If you discover additional required dependencies during the build process, you
may add them using:
""")
println(state.outs)
printstyled(state.outs, "\tbb add [--build|--runtime|--hostbuild] <jll_name>\n", bold=true)
println(state.outs)
end

function obtain_source(state::WizardState)
Expand Down
2 changes: 1 addition & 1 deletion src/wizard/state.jl
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ necessary. It also holds all necessary metadata such as input/output streams.
workspace::Union{Nothing, String} = nothing
source_urls::Union{Nothing, Vector{String}} = nothing
source_files::Union{Nothing, Vector{SetupSource}} = nothing
dependencies::Union{Nothing, Vector{Dependency}} = nothing
dependencies::Union{Nothing, Vector{AbstractDependency}} = nothing
compilers::Union{Nothing, Vector{Symbol}} = nothing
preferred_gcc_version::Union{Nothing, VersionNumber} = nothing
preferred_llvm_version::Union{Nothing, VersionNumber} = nothing
Expand Down
8 changes: 6 additions & 2 deletions test/wizard.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import Pkg: PackageSpec

import BinaryBuilder.BinaryBuilderBase: available_gcc_builds, available_llvm_builds, getversion

const DO_DEBUG=false

function with_wizard_output(f::Function, state, step_func::Function)
# Create fake terminal to communicate with BinaryBuilder over
pty = VT100.create_pty(false)
Expand All @@ -16,8 +18,7 @@ function with_wizard_output(f::Function, state, step_func::Function)
while isopen(pty.master)
z = String(readavailable(pty.master))

# Un-comment this to figure out what on earth is going wrong
# print(z)
DO_DEBUG && print(z)
write(out_buff, z)
end
end
Expand Down Expand Up @@ -238,13 +239,16 @@ end
call_response(ins, outs, "Do you require any (binary) dependencies", "Y")

call_response(ins, outs, "Enter JLL package name:", "ghr_jll")
call_response(ins, outs, "What kind of dependency is this?", "\r"; newline=false)
call_response(ins, outs, "Would you like to provide additional dependencies?", "Y")
# Test auto-JLL suffixing
call_response(ins, outs, "Enter JLL package name:", "Zlib")
call_response(ins, outs, "What kind of dependency is this?", "\r"; newline=false)
call_response(ins, outs, "Would you like to provide additional dependencies?", "Y")

# Test typo detection
call_response(ins, outs, "Enter JLL package name:", "iso_codez_jll")
call_response(ins, outs, "What kind of dependency is this?", "\r"; newline=false)
call_response(ins, outs, "Unable to resolve", "N")

call_response(ins, outs, "Enter a name for this project", "check_deps")
Expand Down
Loading