Skip to content

Commit

Permalink
Merge pull request #62 from JuliaPackaging/sf/no_load_preference_setting
Browse files Browse the repository at this point in the history
Add `set_preferences!(name::String, ...)` method which pulls UUID from `Project.toml`
  • Loading branch information
staticfloat authored Feb 28, 2024
2 parents ae3184a + 5aac59c commit c8e070a
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 4 deletions.
8 changes: 8 additions & 0 deletions src/Preferences.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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...)
Expand Down
33 changes: 29 additions & 4 deletions src/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
20 changes: 20 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down

0 comments on commit c8e070a

Please sign in to comment.