Skip to content

Commit

Permalink
Merge pull request JuliaLang#135 from JuliaLang/sk/slugs
Browse files Browse the repository at this point in the history
slugs: use Base's SHA1 and version_slug
  • Loading branch information
StefanKarpinski authored Feb 15, 2018
2 parents 9f8debd + bac6bf0 commit 49528c5
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 66 deletions.
17 changes: 9 additions & 8 deletions src/API.jl
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,8 @@ function gc(ctx::Context=Context(); period = Dates.Week(6), kwargs...)
@assert length(_stanzas) == 1
stanzas = _stanzas[1]
if stanzas isa Dict && haskey(stanzas, "uuid") && haskey(stanzas, "git-tree-sha1")
push!(paths_to_keep, Pkg3.Operations.find_installed(UUID(stanzas["uuid"]), SHA1(stanzas["git-tree-sha1"])))
push!(paths_to_keep,
Pkg3.Operations.find_installed(name, UUID(stanzas["uuid"]), SHA1(stanzas["git-tree-sha1"])))
end
end
end
Expand All @@ -203,9 +204,9 @@ function gc(ctx::Context=Context(); period = Dates.Week(6), kwargs...)
for depot in depots()
packagedir = abspath(depot, "packages")
if isdir(packagedir)
for uuidslug in readdir(packagedir)
for shaslug in readdir(joinpath(packagedir, uuidslug))
versiondir = joinpath(packagedir, uuidslug, shaslug)
for name in readdir(packagedir)
for slug in readdir(joinpath(packagedir, name))
versiondir = joinpath(packagedir, name, slug)
if !(versiondir in paths_to_keep)
push!(paths_to_delete, versiondir)
end
Expand All @@ -227,10 +228,10 @@ function gc(ctx::Context=Context(); period = Dates.Week(6), kwargs...)
for depot in depots()
packagedir = abspath(depot, "packages")
if isdir(packagedir)
for uuidslug in readdir(packagedir)
uuidslug_path = joinpath(packagedir, uuidslug)
if isempty(readdir(uuidslug_path))
!ctx.preview && Base.rm(uuidslug_path)
for name in readdir(packagedir)
name_path = joinpath(packagedir, name)
if isempty(readdir(name_path))
!ctx.preview && Base.rm(name_path)
end
end
end
Expand Down
48 changes: 7 additions & 41 deletions src/Operations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,47 +14,13 @@ import Pkg3.BinaryProvider
import Pkg3: depots
import Pkg3.Types: uuid_julia

#########
# Slugs #
#########
const SlugInt = UInt32 # max p = 4
const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
const nchars = SlugInt(length(chars))
const max_p = floor(Int, log(nchars, typemax(SlugInt) >>> 8))

function slug(x::SlugInt, p::Int)
1 p max_p || # otherwise previous steps are wrong
error("invalid slug size: $p (need 1 ≤ p ≤ $max_p)")
return sprint() do io
for i = 1:p
x, d = divrem(x, nchars)
write(io, chars[1+d])
end
end
end
slug(x::Integer, p::Int) = slug(SlugInt(x), p)

function slug(bytes::Vector{UInt8}, p::Int)
n = nchars^p
x = zero(SlugInt)
for (i, b) in enumerate(bytes)
x = (x + b*powermod(2, 8(i-1), n)) % n
end
slug(x, p)
end

slug(uuid::UUID, p::Int=4) = slug(uuid.value % nchars^p, p)
slug(sha1::SHA1, p::Int=4) = slug(sha1.bytes, p)

version_slug(uuid::UUID, sha1::SHA1) = joinpath(slug(uuid), slug(sha1))

function find_installed(uuid::UUID, sha1::SHA1)
slug = version_slug(uuid, sha1)
function find_installed(name::String, uuid::UUID, sha1::SHA1)
slug = Base.version_slug(uuid, sha1)
for depot in depots()
path = abspath(depot, "packages", slug)
path = abspath(depot, "packages", name, slug)
ispath(path) && return path
end
return abspath(depots()[1], "packages", slug)
return abspath(depots()[1], "packages", name, slug)
end

function load_versions(path::String)
Expand Down Expand Up @@ -349,7 +315,7 @@ function apply_versions(ctx::Context, pkgs::Vector{PackageSpec})::Vector{UUID}
pkgs_to_install = Tuple{PackageSpec, String}[]
for pkg in pkgs
pkg.uuid in ctx.stdlib_uuids && continue
path = find_installed(pkg.uuid, hashes[pkg.uuid])
path = find_installed(pkg.name, pkg.uuid, hashes[pkg.uuid])
if !ispath(path)
push!(pkgs_to_install, (pkg, path))
push!(new_versions, pkg.uuid)
Expand Down Expand Up @@ -517,7 +483,7 @@ function build_versions(ctx::Context, uuids::Vector{UUID})
# TODO: handle development packages?
haskey(info, "git-tree-sha1") || continue
hash = SHA1(info["git-tree-sha1"])
path = find_installed(uuid, hash)
path = find_installed(name, uuid, hash)
ispath(path) || error("Build path for $name does not exist: $path")
build_file = joinpath(path, "deps", "build.jl")
ispath(build_file) && push!(builds, (uuid, name, hash, build_file))
Expand Down Expand Up @@ -684,7 +650,7 @@ function test(ctx::Context, pkgs::Vector{PackageSpec}; coverage=false)
for pkg in pkgs
info = manifest_info(ctx.env, pkg.uuid)
haskey(info, "git-tree-sha1") || cmderror("Could not find git-tree-sha1 for package $(pkg.name)")
version_path = find_installed(pkg.uuid, SHA1(info["git-tree-sha1"]))
version_path = find_installed(pkg.name, pkg.uuid, SHA1(info["git-tree-sha1"]))
testfile = joinpath(version_path, "test", "runtests.jl")
if !isfile(testfile)
push!(missing_runtests, pkg.name)
Expand Down
18 changes: 1 addition & 17 deletions src/Types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ using Pkg3.TOML
import Pkg3
import Pkg3: depots, logdir

import Base: SHA1
using SHA

export UUID, pkgID, SHA1, VersionRange, VersionSpec, empty_versionspec,
Expand Down Expand Up @@ -50,23 +51,6 @@ function pkgID(p::UUID, uuid_to_name::Dict{UUID,String})
return "$name [$uuid_short]"
end

## SHA1 ##
struct SHA1
bytes::Vector{UInt8}
function SHA1(bytes::Vector{UInt8})
length(bytes) == 20 ||
throw(ArgumentError("wrong number of bytes for SHA1 hash: $(length(bytes))"))
return new(bytes)
end
SHA1(s::String) = SHA1(hex2bytes(s))
end

Base.string(hash::SHA1) = bytes2hex(hash.bytes)
Base.show(io::IO, hash::SHA1) = print(io, "SHA1(", String(hash.bytes), ")")
Base.isless(a::SHA1, b::SHA1) = lexless(a.bytes, b.bytes)
Base.hash(a::SHA1, h::UInt) = hash((SHA1, a.bytes), h)
Base.:(==)(a::SHA1, b::SHA1) = a.bytes == b.bytes

## VersionRange ##

struct VersionBound
Expand Down

0 comments on commit 49528c5

Please sign in to comment.