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

Add set_preferences!(name::String, ...) method which pulls UUID from Project.toml #62

Merged
merged 1 commit into from
Feb 28, 2024
Merged
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
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 @@
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"]

Check warning on line 74 in src/utils.jl

View check run for this annotation

Codecov / codecov/patch

src/utils.jl#L74

Added line #L74 was not covered by tests
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
Loading