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

Unique package paths #38

Open
wants to merge 2 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
8 changes: 3 additions & 5 deletions src/register.jl
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,8 @@ function find_package_in_registry(pkg::Pkg.Types.Project,
end

@debug("Creating directory for new package $(pkg.name)")
package_path = joinpath(registry_path, package_relpath(pkg))
package_path = joinpath(registry_path,
package_relpath(registry_data, pkg))
mkpath(package_path)

@debug("Adding package UUID to registry")
Expand Down Expand Up @@ -674,10 +675,7 @@ function register(

Registrator tree SHA: $(regtreesha)
"""
registry_file = joinpath(registry_path, "Registry.toml")
package_path = joinpath(registry_path, package_relpath(pkg))
run(pipeline(`$git add -- $package_path`; stdout=devnull))
run(pipeline(`$git add -- $registry_file`; stdout=devnull))
run(pipeline(`$git add --all`; stdout=devnull))
run(pipeline(`$git commit -m $message`; stdout=devnull))

# push -f branch to remote
Expand Down
26 changes: 23 additions & 3 deletions src/types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -150,13 +150,33 @@ end

# Not using `joinpath` here since we don't want backslashes in
# Registry.toml when running on Windows.
function package_relpath(pkg::Pkg.Types.Project)
string(uppercase(pkg.name[1]), "/", pkg.name)
function package_relpath(registry_data::RegistryData,
pkg::Pkg.Types.Project)
relpath = string(uppercase(pkg.name[1]), "/", pkg.name)
# Check if this path is free from case insensitive collisions with
# previously registered packages.
existing_relpaths = Set(lowercase(package["path"])
for package in values(registry_data.packages))
if lowercase(relpath) in existing_relpaths
# Otherwise suffix with a sufficient part of the uuid to make
# the path unique.
uuid = string(pkg.uuid)
for n = 4:length(uuid)
uuid[n] == '-' && continue
extended_relpath = string(relpath, ".", uuid[1:n])
if !(lowercase(extended_relpath) in existing_relpaths)
return extended_relpath
end
end
@assert false "UUID $(uuid) already exists in registry"
end

return relpath
end

function Base.push!(reg::RegistryData, pkg::Pkg.Types.Project)
reg.packages[string(pkg.uuid)] = Dict(
"name" => pkg.name, "path" => package_relpath(pkg)
"name" => pkg.name, "path" => package_relpath(reg, pkg)
)
reg
end
58 changes: 58 additions & 0 deletions test/regedit.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ using RegistryTools: DEFAULT_REGISTRY_URL,
using LibGit2
using Pkg.TOML
using Pkg.Types: Project
using UUIDs

using Test

Expand Down Expand Up @@ -763,4 +764,61 @@ end
end
end

@testset "Relative Path" begin
registry_data = RegistryTools.RegistryData(
"BlankRegistry", "d4e2f5cd-0f48-4704-9988-f1754e755b45")

packages = [("Example",
"7876af07-990d-54b4-ab0e-23690620f79a",
"E/Example"),
("example",
"0000af07-990d-54b4-ab0e-23690620f79a",
"E/example.0000"),
("eXampLe",
"7800af07-990d-54b4-ab0e-23690620f79a",
"E/eXampLe.7800"),
("exAmPlE",
"7876a007-990d-54b4-ab0e-23690620f79a",
"E/exAmPlE.7876"),
("EXAMPLE",
"7876af07-990d-54b4-ab0e-00690620f79a",
"E/EXAMPLE.7876a"),
("example",
"7876af07-990d-54b4-ab0e-23000620f79a",
"E/example.7876af")]

for (name, uuid, expected_path) in packages
project = Project(Dict("name" => name, "uuid" => uuid))
push!(registry_data, project)
@test registry_data.packages[uuid]["name"] == name
@test registry_data.packages[uuid]["path"] == expected_path
end

# Stress the path names.
for i = 8:32
name, uuid, _ = packages[1]
modified_uuid = string(UUID(xor(UUID(uuid).value,
UInt128(1) << (4 * (32 - i)))))
project = Project(Dict("name" => name, "uuid" => modified_uuid))
push!(registry_data, project)
relpath = registry_data.packages[modified_uuid]["path"]
uuid_part = split(relpath, ".")[end]
@test startswith(uuid, uuid_part)
@test relpath[end] != '-'
@test length(replace(uuid_part, "-" => "")) == i - 1
end

# Keep stressing. This requires all the characters of the uuid in
# the path.
name, uuid, = "Example", "7876af07-990d-54b4-ab0e-23690620f790"
project = Project(Dict("name" => name, "uuid" => uuid))
push!(registry_data, project)
@test registry_data.packages[uuid]["path"] == "E/Example.$(uuid)"

# This tries to add the same uuid again and is thus misusing the
# function but adds coverage by reaching an assertion that should
# never fail with correct use.
@test_throws AssertionError push!(registry_data, project)
end

end