From 5e258450646813885ab639e3c205d960fd0fc678 Mon Sep 17 00:00:00 2001 From: David Anthoff Date: Fri, 21 Apr 2017 10:48:08 -0700 Subject: [PATCH 1/4] Add type for requirement --- src/MetadataTools.jl | 47 +++++++++++++++++++++++++++++++++++--------- src/pkg_graph.jl | 10 ++++------ 2 files changed, 42 insertions(+), 15 deletions(-) diff --git a/src/MetadataTools.jl b/src/MetadataTools.jl index 0be20cc..44c3ebf 100644 --- a/src/MetadataTools.jl +++ b/src/MetadataTools.jl @@ -16,6 +16,32 @@ using Compat #----------------------------------------------------------------------- +""" + PkgMetaRequire + +Represents a single requirement in METADATA.jl +""" +immutable PkgMetaRequire + name::String + lower_bound::Nullable{VersionNumber} + upper_bound::Nullable{VersionNumber} + platform::Nullable{String} +end +function printer(io::IO, pmr::PkgMetaRequire) + print(io, pmr.name) + if !(isnull(pmr.lower_bound) && isnull(pmr.upper_bound) && isnull(pmr.platform)) + print(io, "(") + limits = String[] + isnull(pmr.lower_bound) || push!(limits, ">$(get(pmr.lower_bound))") + isnull(pmr.upper_bound) || push!(limits, "<$(get(pmr.upper_bound))") + isnull(pmr.platform) || push!(limits, "@$(get(pmr.platform))") + join(io, limits, ",") + print(io, ")") + end +end +Base.print(io::IO, pmr::PkgMetaRequire) = printer(io,pmr) +Base.show(io::IO, pmr::PkgMetaRequire) = printer(io, pmr) + """ PkgMetaVersion @@ -24,7 +50,7 @@ Represents a version of a package in METADATA.jl immutable PkgMetaVersion ver::VersionNumber sha::Compat.UTF8String - requires::Vector{Compat.UTF8String} + requires::Vector{PkgMetaRequire} end function printer(io::IO, pmv::PkgMetaVersion) print(io, " ", pmv.ver, ",", pmv.sha[1:6]) @@ -93,13 +119,17 @@ function get_pkg(pkg_name::AbstractString; ver_path = joinpath(vers_path, dir) sha = strip(readstring(joinpath(ver_path,"sha1"))) req_path = joinpath(ver_path,"requires") - reqs = Compat.UTF8String[] + reqs = PkgMetaRequire[] if isfile(req_path) req_file = map(strip,split(readstring(req_path),"\n")) for req in req_file - length(req) == 0 && continue - req[1] == '#' && continue - push!(reqs, req) + m = match(r"^(@\w+\s+)?(\w+)(\s+[\d.-]+)?(\s+[\d.-]+)?", req) + m === nothing && continue + + plt, dep, lb, ub = m.captures + + require_data = PkgMetaRequire(dep, lb === nothing ? Nullable{VersionNumber}() : lstrip(lb), ub === nothing ? Nullable{VersionNumber}() : lstrip(ub), plt === nothing ? Nullable{String}() : rstrip(plt)[2:end]) + push!(reqs, require_data) end end push!(vers,PkgMetaVersion(ver_num,sha,reqs)) @@ -146,10 +176,9 @@ function get_upper_limit(pkg::PkgMeta) julia_max_ver = v"0.0.0" # Check if there is a Julia max version dependency for req in ver.requires - !contains(req,"julia") && continue - s = split(req," ") - length(s) != 3 && continue - julia_max_ver = convert(VersionNumber,s[3]) + req.name!="julia" && continue + isnull(req.upper_bound) && continue + julia_max_ver = get(req.upper_bound) break end # If there wasn't, then at least one version will work on diff --git a/src/pkg_graph.jl b/src/pkg_graph.jl index 629bf59..f3a2e35 100644 --- a/src/pkg_graph.jl +++ b/src/pkg_graph.jl @@ -72,23 +72,21 @@ function make_dep_graph(pkgs::Dict{Compat.UTF8String,PkgMeta}; reverse=false) # We use the most recent version # TODO: add an option to modify this behaviour. pkg_ver = pkg_meta.versions[end] - for req in pkg_ver.requires # Requirements are plain strings - if contains(req, "julia") + for req in pkg_ver.requires + if req.name=="julia" # Julia version dependency, skip it continue end - # Strip OS-specific conditions - other_pkg = (req[1] == '@') ? split(req," ")[2] : split(req," ")[1] # Special case the the cycle: # LibCURL -> WinRPM (on Windows only) # WinRPM -> HTTPClient (on Unix only) # HTTPClient -> LibCurl # by breaking WinRPM -> HTTPClient - if pkg_name == "WinRPM" && other_pkg == "HTTPClient" + if pkg_name == "WinRPM" && req.name == "HTTPClient" continue end # Map names to indices - src, dst = pkgname_idx[pkg_name], pkgname_idx[other_pkg] + src, dst = pkgname_idx[pkg_name], pkgname_idx[req.name] # Add the directed edge if reverse dst, src = src, dst From bfd394432f0d96a62d161775e357c1d56bb90257 Mon Sep 17 00:00:00 2001 From: David Anthoff Date: Fri, 21 Apr 2017 14:06:14 -0700 Subject: [PATCH 2/4] Use Base type for Requirement --- src/MetadataTools.jl | 44 +++++--------------------------------------- src/pkg_graph.jl | 6 +++--- 2 files changed, 8 insertions(+), 42 deletions(-) diff --git a/src/MetadataTools.jl b/src/MetadataTools.jl index 44c3ebf..d900db7 100644 --- a/src/MetadataTools.jl +++ b/src/MetadataTools.jl @@ -16,32 +16,6 @@ using Compat #----------------------------------------------------------------------- -""" - PkgMetaRequire - -Represents a single requirement in METADATA.jl -""" -immutable PkgMetaRequire - name::String - lower_bound::Nullable{VersionNumber} - upper_bound::Nullable{VersionNumber} - platform::Nullable{String} -end -function printer(io::IO, pmr::PkgMetaRequire) - print(io, pmr.name) - if !(isnull(pmr.lower_bound) && isnull(pmr.upper_bound) && isnull(pmr.platform)) - print(io, "(") - limits = String[] - isnull(pmr.lower_bound) || push!(limits, ">$(get(pmr.lower_bound))") - isnull(pmr.upper_bound) || push!(limits, "<$(get(pmr.upper_bound))") - isnull(pmr.platform) || push!(limits, "@$(get(pmr.platform))") - join(io, limits, ",") - print(io, ")") - end -end -Base.print(io::IO, pmr::PkgMetaRequire) = printer(io,pmr) -Base.show(io::IO, pmr::PkgMetaRequire) = printer(io, pmr) - """ PkgMetaVersion @@ -50,7 +24,7 @@ Represents a version of a package in METADATA.jl immutable PkgMetaVersion ver::VersionNumber sha::Compat.UTF8String - requires::Vector{PkgMetaRequire} + requires::Vector{Base.Pkg.Reqs.Requirement} end function printer(io::IO, pmv::PkgMetaVersion) print(io, " ", pmv.ver, ",", pmv.sha[1:6]) @@ -119,18 +93,10 @@ function get_pkg(pkg_name::AbstractString; ver_path = joinpath(vers_path, dir) sha = strip(readstring(joinpath(ver_path,"sha1"))) req_path = joinpath(ver_path,"requires") - reqs = PkgMetaRequire[] + reqs = Base.Pkg.Reqs.Requirement[] if isfile(req_path) req_file = map(strip,split(readstring(req_path),"\n")) - for req in req_file - m = match(r"^(@\w+\s+)?(\w+)(\s+[\d.-]+)?(\s+[\d.-]+)?", req) - m === nothing && continue - - plt, dep, lb, ub = m.captures - - require_data = PkgMetaRequire(dep, lb === nothing ? Nullable{VersionNumber}() : lstrip(lb), ub === nothing ? Nullable{VersionNumber}() : lstrip(ub), plt === nothing ? Nullable{String}() : rstrip(plt)[2:end]) - push!(reqs, require_data) - end + append!(reqs, filter(i->isa(i,Base.Pkg.Reqs.Requirement), Base.Pkg.Reqs.read(req_file))) end push!(vers,PkgMetaVersion(ver_num,sha,reqs)) end @@ -176,8 +142,8 @@ function get_upper_limit(pkg::PkgMeta) julia_max_ver = v"0.0.0" # Check if there is a Julia max version dependency for req in ver.requires - req.name!="julia" && continue - isnull(req.upper_bound) && continue + req.package!="julia" && continue + any(i->i.upper!=typemax(VersionNumber), req.versions.intervals) || continue julia_max_ver = get(req.upper_bound) break end diff --git a/src/pkg_graph.jl b/src/pkg_graph.jl index f3a2e35..e568ca0 100644 --- a/src/pkg_graph.jl +++ b/src/pkg_graph.jl @@ -73,7 +73,7 @@ function make_dep_graph(pkgs::Dict{Compat.UTF8String,PkgMeta}; reverse=false) # TODO: add an option to modify this behaviour. pkg_ver = pkg_meta.versions[end] for req in pkg_ver.requires - if req.name=="julia" + if req.package=="julia" # Julia version dependency, skip it continue end @@ -82,11 +82,11 @@ function make_dep_graph(pkgs::Dict{Compat.UTF8String,PkgMeta}; reverse=false) # WinRPM -> HTTPClient (on Unix only) # HTTPClient -> LibCurl # by breaking WinRPM -> HTTPClient - if pkg_name == "WinRPM" && req.name == "HTTPClient" + if pkg_name == "WinRPM" && req.package == "HTTPClient" continue end # Map names to indices - src, dst = pkgname_idx[pkg_name], pkgname_idx[req.name] + src, dst = pkgname_idx[pkg_name], pkgname_idx[req.package] # Add the directed edge if reverse dst, src = src, dst From 744937630ecb9d7d65d859351d68d77442b96db4 Mon Sep 17 00:00:00 2001 From: David Anthoff Date: Fri, 21 Apr 2017 14:29:13 -0700 Subject: [PATCH 3/4] Fix get_upper_limit --- src/MetadataTools.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/MetadataTools.jl b/src/MetadataTools.jl index d900db7..57e7505 100644 --- a/src/MetadataTools.jl +++ b/src/MetadataTools.jl @@ -144,7 +144,8 @@ function get_upper_limit(pkg::PkgMeta) for req in ver.requires req.package!="julia" && continue any(i->i.upper!=typemax(VersionNumber), req.versions.intervals) || continue - julia_max_ver = get(req.upper_bound) + # TODO Handle multiple entries in req.versions.intervals properly + julia_max_ver = req.versions.intervals[1].upper break end # If there wasn't, then at least one version will work on From faba2bb66defd221fa3afb259adace380251a14f Mon Sep 17 00:00:00 2001 From: David Anthoff Date: Fri, 21 Apr 2017 14:30:17 -0700 Subject: [PATCH 4/4] Add error check on multiple version intervals --- src/MetadataTools.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/MetadataTools.jl b/src/MetadataTools.jl index 57e7505..7809b4d 100644 --- a/src/MetadataTools.jl +++ b/src/MetadataTools.jl @@ -145,6 +145,9 @@ function get_upper_limit(pkg::PkgMeta) req.package!="julia" && continue any(i->i.upper!=typemax(VersionNumber), req.versions.intervals) || continue # TODO Handle multiple entries in req.versions.intervals properly + if length(req.versions.intervals[1]) > 1 + error("This package cannot handle package requirements with multiple version intervals.") + end julia_max_ver = req.versions.intervals[1].upper break end