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

loading: fix two bugs in project file deps parsing + tests #26580

Merged
merged 2 commits into from
Mar 23, 2018
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
11 changes: 3 additions & 8 deletions base/loading.jl
Original file line number Diff line number Diff line change
Expand Up @@ -479,13 +479,8 @@ end

# find project file root or deps `name => uuid` mapping
# - `false` means: did not find `name`
# - `true` means: found `name` without UUID
# - `true` means: found `name` without UUID (can't happen in explicit projects)
# - `uuid` means: found `name` with `uuid` in project file
#
# `true` can only be returned in the case that `name` is the project's name
# and the project file does not have a top-level `uuid` mapping
# it is not currently supported to have a name in `deps` mapped to anything
# besides a UUID, so otherwise the answer is `false` or a UUID value

function explicit_project_deps_get(project_file::String, name::String)::Union{Bool,UUID}
open(project_file) do io
Expand All @@ -507,10 +502,10 @@ function explicit_project_deps_get(project_file::String, name::String)::Union{Bo
m.captures[1] == name && return UUID(m.captures[2])
end
elseif occursin(re_section, line)
state = :deps
state = occursin(re_section_deps, line) ? :deps : :other
end
end
return false
return root_name == name && root_uuid
end
end

Expand Down
1 change: 0 additions & 1 deletion stdlib/Pkg3/src/precompile.jl
Original file line number Diff line number Diff line change
Expand Up @@ -781,7 +781,6 @@ precompile(Tuple{typeof(REPL.LineEdit.fixup_keymaps!), Base.Dict{Char, Any}, Int
precompile(Tuple{typeof(REPL.LineEdit.region_active), REPL.LineEdit.PromptState})
precompile(Tuple{typeof(REPL.LineEdit.setup_prefix_keymap), REPL.REPLHistoryProvider, REPL.LineEdit.Prompt})
precompile(Tuple{typeof(REPL.LineEdit.setup_search_keymap), REPL.REPLHistoryProvider})
precompile(Tuple{getfield(Pkg3.Types, Symbol("##printpkgstyle#56")), Bool, typeof(Pkg3.Types.printpkgstyle), Base.TTY, Symbol, String})

precompile(Tuple{typeof(REPL.LineEdit.complete_line), Pkg3.REPLMode.PkgCompletionProvider, REPL.LineEdit.PromptState})

Expand Down
64 changes: 61 additions & 3 deletions test/loading.jl
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,69 @@ mktempdir() do dir
end
end

## unit tests of project parsing ##

import Base: SHA1, PkgId, load_path, identify_package, locate_package, version_slug, dummy_uuid
import UUIDs: UUID, uuid4, uuid_version
import Random: shuffle, randstring
using Test

function subset(v::Vector{T}, m::Int) where T
T[v[j] for j = 1:length(v) if ((m >>> (j - 1)) & 1) == 1]
end

function perm(p::Vector, i::Int)
for j = length(p):-1:1
i, k = divrem(i, j)
p[j], p[k+1] = p[k+1], p[j]
end
return p
end

@testset "explicit_project_deps_get" begin
project_file = "$(tempname()).toml"
touch(project_file) # dummy_uuid calls realpath
proj_uuid = dummy_uuid(project_file)
root_uuid = UUID("43306aae-ef21-43f3-9517-81724f2885ac")
this_uuid = UUID("b36283d3-af40-4a18-9ee0-d12ee9c142ac")
lines = split("""
name = "Root"
uuid = "$root_uuid"
[deps]
This = "$this_uuid"
""", '\n')
N = length(lines)
for m = 0:2^N-1
# for every subset of lines
s = subset(lines, m)
for i = 1:factorial(count_ones(m))
# for every permutation of that subset
p = perm(s, i)
open(project_file, write=true) do io
for line in p
println(io, line)
end
end
# look at lines and their order
n = findfirst(line -> startswith(line, "name"), p)
u = findfirst(line -> startswith(line, "uuid"), p)
d = findfirst(line -> line == "[deps]", p)
t = findfirst(line -> startswith(line, "This"), p)
# look up various packages by name
root = Base.explicit_project_deps_get(project_file, "Root")
this = Base.explicit_project_deps_get(project_file, "This")
that = Base.explicit_project_deps_get(project_file, "That")
# test that the correct answers are given
@test root == (coalesce(n, N+1) ≥ coalesce(d, N+1) ? false :
coalesce(u, N+1) < coalesce(d, N+1) ? root_uuid : proj_uuid)
@test this == (coalesce(d, N+1) < coalesce(t, N+1) ≤ N ? this_uuid : false)
@test that == false
end
end
end

## functional testing of package identification, location & loading ##

saved_load_path = copy(LOAD_PATH)
saved_depot_path = copy(DEPOT_PATH)
push!(empty!(LOAD_PATH), "project")
Expand Down Expand Up @@ -415,14 +473,14 @@ function test_find(
end
end

@testset "identify_package with one env in load path" begin
@testset "find_package with one env in load path" begin
for (env, (_, _, roots, graph, paths)) in envs
push!(empty!(LOAD_PATH), env)
test_find(roots, graph, paths)
end
end

@testset "identify_package with two envs in load path" begin
@testset "find_package with two envs in load path" begin
for x = false:true,
(env1, (_, _, roots1, graph1, paths1)) in (x ? envs : rand(envs, 10)),
(env2, (_, _, roots2, graph2, paths2)) in (x ? rand(envs, 10) : envs)
Expand All @@ -434,7 +492,7 @@ end
end
end

@testset "identify_package with three envs in load path" begin
@testset "find_package with three envs in load path" begin
for (env1, (_, _, roots1, graph1, paths1)) in rand(envs, 10),
(env2, (_, _, roots2, graph2, paths2)) in rand(envs, 10),
(env3, (_, _, roots3, graph3, paths3)) in rand(envs, 10)
Expand Down