diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 0d7d3af..edc8b69 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -13,8 +13,7 @@ jobs: fail-fast: false matrix: version: - - '1.4' - - '1.5' + - '1.6' - '1' # automatically expands to the latest stable 1.x release of Julia - 'nightly' os: @@ -24,21 +23,6 @@ jobs: arch: - x64 include: - - os: ubuntu-latest - version: 1.1 - arch: x64 - - os: ubuntu-latest - version: 1.2 - arch: x64 - - os: ubuntu-latest - version: 1.3 - arch: x64 - - os: windows-latest - version: 1.4 - arch: x86 - - os: windows-latest - version: 1.5 - arch: x86 - os: windows-latest version: nightly arch: x86 diff --git a/Project.toml b/Project.toml index 78f8abc..7fc534c 100644 --- a/Project.toml +++ b/Project.toml @@ -12,7 +12,7 @@ UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" [compat] AutoHashEquals = "0.2" -julia = "1.1" +julia = "1.6" [extras] Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" diff --git a/src/RegistryTools.jl b/src/RegistryTools.jl index 6a10ae3..d362f21 100644 --- a/src/RegistryTools.jl +++ b/src/RegistryTools.jl @@ -11,6 +11,14 @@ using Pkg: Pkg, TOML, GitTools using UUIDs const DEFAULT_REGISTRY_URL = "https://github.com/JuliaRegistries/General" +const PKG_HAS_WEAK = hasfield(Pkg.Types.Project, :_deps_weak) + +function __init__() + if !PKG_HAS_WEAK + @warn "Running Registrator on a Julia version that does not support weak dependencies. " * + "Weak dependencies will not be registered." + end +end include("Compress.jl") include("builtin_pkgs.jl") diff --git a/src/register.jl b/src/register.jl index 8c1c1dd..9e5f054 100644 --- a/src/register.jl +++ b/src/register.jl @@ -47,6 +47,13 @@ for the project file in that tree and a hash string for the tree. # end # end +function getdeps(pkg) + if PKG_HAS_WEAK + return merge(pkg.deps, pkg._deps_weak) + end + return pkg.deps +end + # These can compromise the integrity of the registry and cannot be # opted out of. const mandatory_errors = [:version_exists, @@ -404,16 +411,20 @@ end function check_deps!(pkg::Pkg.Types.Project, regdata::Vector{RegistryData}, status::ReturnStatus) - if pkg.name in keys(pkg.deps) - err = :package_self_dep - @debug(err) - add!(status, err, (name = pkg.name,)) - haserror(status) && return - end + depses = [getdeps(pkg)] + PKG_HAS_WEAK && push!(depses, pkg.weakdeps) + for deps in depses + if pkg.name in keys(deps) + err = :package_self_dep + @debug(err) + add!(status, err, (name = pkg.name,)) + haserror(status) && return + end - @debug("Verifying package name and uuid in deps") - for (name, uuid) in pkg.deps - findpackageerror!(name, uuid, regdata, status) + @debug("Verifying package name and uuid in deps/weakdeps") + for (name, uuid) in deps + findpackageerror!(name, uuid, regdata, status) + end end end @@ -425,15 +436,19 @@ end function update_deps_file(pkg::Pkg.Types.Project, package_path::AbstractString, old_versions::Vector{VersionNumber}) - deps_file = joinpath(package_path, "Deps.toml") - if isfile(deps_file) - deps_data = Compress.load(deps_file, old_versions) - else - deps_data = Dict() - end + file_depses = [("Deps.toml", getdeps(pkg))] + PKG_HAS_WEAK && push!(file_depses, ("WeakDeps.toml", pkg.weakdeps)) + for (file, deps) in file_depses + deps_file = joinpath(package_path, file) + if isfile(deps_file) + deps_data = Compress.load(deps_file, old_versions) + else + deps_data = Dict() + end - deps_data[pkg.version] = pkg.deps - Compress.save(deps_file, deps_data) + deps_data[pkg.version] = deps + Compress.save(deps_file, deps_data) + end end function check_compat!(pkg::Pkg.Types.Project, @@ -443,7 +458,7 @@ function check_compat!(pkg::Pkg.Types.Project, if haskey(pkg.compat, "julia") if Base.VERSION >= v"1.7-" ver = pkg.compat["julia"].val - else + else ver = Pkg.Types.semver_spec(pkg.compat["julia"]) end if any(map(x -> !isempty(intersect(Pkg.Types.VersionRange("0-0.6"), x)), ver.ranges)) @@ -459,9 +474,10 @@ function check_compat!(pkg::Pkg.Types.Project, # entries not mentioned in deps, nor in extras. invalid_compats = [] for name in keys(pkg.compat) - indeps = haskey(pkg.deps, name) + indeps = haskey(getdeps(pkg), name) inextras = haskey(pkg.extras, name) - if !indeps && !inextras && name != "julia" + inweaks = PKG_HAS_WEAK ? haskey(pkg.weakdeps, name) : false + if !(indeps || inextras || inweaks || name == "julia") push!(invalid_compats, name) end end @@ -482,11 +498,11 @@ function check_compat!(pkg::Pkg.Types.Project, # anyway. for name in keys(pkg.compat) if name != "julia" - indeps = haskey(pkg.deps, name) + indeps = haskey(getdeps(pkg), name) inextras = haskey(pkg.extras, name) if indeps - uuidofdep = string(pkg.deps[name]) + uuidofdep = string(getdeps(pkg)[name]) findpackageerror!(name, uuidofdep, regdata, status) elseif inextras uuidofdep = string(pkg.extras[name]) @@ -506,36 +522,45 @@ function update_compat_file(pkg::Pkg.Types.Project, package_path::AbstractString, old_versions::Vector{VersionNumber}) @debug("update package data: compat file") - compat_file = joinpath(package_path, "Compat.toml") - if isfile(compat_file) - compat_data = Compress.load(compat_file, old_versions) - else - compat_data = Dict() - end - d = Dict() - for (name, version) in pkg.compat - if !haskey(pkg.deps, name) && name != "julia" - @debug("$name is a test-only dependency; omitting from Compat.toml") - continue + file_depses = [("Compat.toml", getdeps(pkg))] + PKG_HAS_WEAK && push!(file_depses, ("WeakCompat.toml", pkg.weakdeps)) + for (file, deps) in file_depses + compat_file = joinpath(package_path, file) + if isfile(compat_file) + compat_data = Compress.load(compat_file, old_versions) + else + compat_data = Dict() end - if Base.VERSION >= v"1.7-" - spec = version.val - else - spec = Pkg.Types.semver_spec(version) + d = Dict() + for (name, version) in pkg.compat + # Ignore julia compat for weak + if file == "WeakCompat.toml" && name == "julia" + continue + end + if !haskey(deps, name) && name != "julia" + @debug("$name is a not in relevant dependency list; omitting from Compat.toml") + continue + end + + if Base.VERSION >= v"1.7-" + spec = version.val + else + spec = Pkg.Types.semver_spec(version) + end + # The call to `map(versionrange, )` can be removed + # once Pkg is updated to a version including + # https://github.com/JuliaLang/Pkg.jl/pull/1181 + # and support for older versions is dropped. + ranges = map(r->versionrange(r.lower, r.upper), spec.ranges) + ranges = VersionSpec(ranges).ranges # this combines joinable ranges + d[name] = length(ranges) == 1 ? string(ranges[1]) : map(string, ranges) end - # The call to `map(versionrange, )` can be removed - # once Pkg is updated to a version including - # https://github.com/JuliaLang/Pkg.jl/pull/1181 - # and support for older versions is dropped. - ranges = map(r->versionrange(r.lower, r.upper), spec.ranges) - ranges = VersionSpec(ranges).ranges # this combines joinable ranges - d[name] = length(ranges) == 1 ? string(ranges[1]) : map(string, ranges) - end - compat_data[pkg.version] = d - Compress.save(compat_file, compat_data) + compat_data[pkg.version] = d + Compress.save(compat_file, compat_data) + end end function get_registrator_tree_sha() diff --git a/test/project_files/Example19.toml b/test/project_files/Example19.toml new file mode 100644 index 0000000..e0cf87c --- /dev/null +++ b/test/project_files/Example19.toml @@ -0,0 +1,19 @@ +name = "Example" +uuid = "d7508571-2240-4c50-b21c-240e414cc6d2" +version = "1.1.0" + +[deps] +UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" + +[weakdeps] +UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" + +[compat] +julia = "1.1" +UUIDs = "1.8" + +[extras] +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[targets] +test = ["Test"] diff --git a/test/regedit.jl b/test/regedit.jl index f14fa7e..0cd85f7 100644 --- a/test/regedit.jl +++ b/test/regedit.jl @@ -20,6 +20,13 @@ const TEST_SIGNATURE = LibGit2.Signature( TEST_GITCONFIG["user.email"], ) +function create_empty_registry(registry_path, registry_name, registry_uuid) + mkpath(registry_path) + registry_file = joinpath(registry_path, "Registry.toml") + registry_data = RegistryTools.RegistryData(registry_name, registry_uuid) + RegistryTools.write_registry(registry_file, registry_data) +end + @testset "RegistryTools" begin @testset "Utilities" begin @@ -240,13 +247,6 @@ end end end -function create_empty_registry(registry_path, registry_name, registry_uuid) - mkpath(registry_path) - registry_file = joinpath(registry_path, "Registry.toml") - registry_data = RegistryTools.RegistryData(registry_name, registry_uuid) - RegistryTools.write_registry(registry_file, registry_data) -end - @testset "find_package_in_registry" begin import RegistryTools: find_package_in_registry mktempdir(@__DIR__) do temp_dir @@ -772,6 +772,49 @@ end end end +if RegistryTools.PKG_HAS_WEAK +@testset "weakdeps" begin + import RegistryTools: ReturnStatus, check_and_update_registry_files + import Pkg.Types: read_project + + temp_dir = mktempdir(; cleanup=false) + mktempdir(@__DIR__) do temp_dir + registry_path = joinpath(temp_dir, "registry") + projects_path = joinpath(@__DIR__, "project_files") + registry_deps_paths = String[] + tree_hash = repeat("0", 40) + # Start with an empty registry. + create_empty_registry(registry_path, "TestRegistry", + "d4e2f5cd-0f48-4704-9988-f1754e755b45") + project_file = joinpath(projects_path, "Example19.toml") + pkg = read_project(project_file) + status = ReturnStatus() + package_repo = "http://example.com/Example1.git" + check_and_update_registry_files(pkg, package_repo, tree_hash, + registry_path, + registry_deps_paths, status) + path = RegistryTools.package_relpath("Example") + @test read(joinpath(registry_path, path, "Compat.toml"), String) == + """ + [1] + UUIDs = "1.8.0-1" + julia = "1.1.0-1" + """ + @test read(joinpath(registry_path, path, "WeakCompat.toml"), String) == + """ + [1] + UUIDs = "1.8.0-1" + """ + @test read(joinpath(registry_path, path, "Deps.toml"), String) == + read(joinpath(registry_path, path, "WeakDeps.toml"), String) == + """ + [1] + UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" + """ + end +end +end + @testset "The `RegistryTools.package_relpath` function" begin @test RegistryTools.package_relpath("Example") == "E/Example" end