diff --git a/src/Preferences.jl b/src/Preferences.jl index cc7ae04..99ad2c5 100644 --- a/src/Preferences.jl +++ b/src/Preferences.jl @@ -285,6 +285,14 @@ end function set_preferences!(m::Module, prefs::Pair{String,<:Any}...; kwargs...) return set_preferences!(get_uuid(m), prefs...; kwargs...) end +function set_preferences!(name::String, prefs::Pair{String,<:Any}...; kwargs...) + # Look up UUID + uuid = get_uuid(name) + if uuid === nothing + throw(ArgumentError("Cannot resolve package '$(name)' in load path; have you added the package as a top-level dependency?")) + end + return set_preferences!(uuid, prefs...; kwargs...) +end """ @set_preferences!(prefs...) diff --git a/src/utils.jl b/src/utils.jl index 9b466dc..24f7b80 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -52,22 +52,47 @@ function get_uuid(m::Module) end end -function find_first_project_with_uuid(uuid::UUID) - # Find first element in `Base.load_path()` that contains this UUID - # This code should look similar to the search in `Base.get_preferences()` +function load_path_walk(f::Function) for env in Base.load_path() project_toml = Base.env_project_file(env) if !isa(project_toml, String) continue end + ret = f(project_toml) + if ret !== nothing + return ret + end + end + return nothing +end + +function get_uuid(name::String) + return load_path_walk() do project_toml + project = Base.parsed_toml(project_toml) + if haskey(project, "uuid") && get(project, "name", "") == name + return project["uuid"] + end + for key in ["deps", "extras"] + if haskey(project, key) && haskey(project[key], name) + return parse(Base.UUID, project[key][name]) + end + end + return nothing + end +end + +function find_first_project_with_uuid(uuid::UUID) + # Find first element in `Base.load_path()` that contains this UUID + # This code should look similar to the search in `Base.get_preferences()` + return load_path_walk() do project_toml # Check to see if this project has a name mapping pkg_name = Base.get_uuid_name(project_toml, uuid) if pkg_name !== nothing return (project_toml, pkg_name) end + return nothing end - return (nothing, nothing) end # Drop any nested `__clear__` keys: diff --git a/test/runtests.jl b/test/runtests.jl index 9426d56..0ef52b0 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -154,6 +154,26 @@ up_path = joinpath(@__DIR__, "UsesPreferences") end end +@testset "Loading UUID from Project.toml" begin + with_temp_depot() do; mktempdir() do dir + activate(dir) do + push!(Base.LOAD_PATH, dir) + try + # Can't do this unless `UsesPreferences` is added as a dep + @test_throws ArgumentError Preferences.set_preferences!("UsesPreferences", "location" => "exists") + + Pkg.develop(;path=up_path) + + # After `dev`'ing `up_path`, it works. + Preferences.set_preferences!("UsesPreferences", "location" => "exists") + @test load_preference(up_uuid, "location") == "exists" + finally + pop!(Base.LOAD_PATH) + end + end + end; end +end + # Load UsesPreferences, as we need it loaded to satisfy `set_preferences!()` below, # otherwise it can't properly map from a UUID to a name when installing into a package # that doesn't have UsesPreferences added yet.