Skip to content

Commit

Permalink
Merge pull request #15 from JuliaEcosystem/MB/dep-fix
Browse files Browse the repository at this point in the history
Retrieve dependencies from a VersionRange
  • Loading branch information
mattBrzezinski authored Apr 6, 2021
2 parents fdc3ae4 + a3816f6 commit f70f26c
Show file tree
Hide file tree
Showing 15 changed files with 137 additions and 66 deletions.
3 changes: 2 additions & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
name = "PkgDeps"
uuid = "839e9fc8-855b-5b3c-a3b7-2833d3dd1f59"
license = "MIT"
version = "0.1.0"
version = "0.2.0"

[deps]
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
TOML = "fa267f1f-6049-4f14-aa54-33bafae1ed76"
UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"

Expand Down
105 changes: 52 additions & 53 deletions src/PkgDeps.jl
Original file line number Diff line number Diff line change
@@ -1,52 +1,42 @@
module PkgDeps

using Pkg.Types: VersionNumber, VersionRange
using TOML: parsefile
using UUIDs

export PkgEntry, RegistryInstance
export find_upstream_dependencies, reachable_registries
export find_downstream_dependencies, reachable_registries

struct PkgEntry
path::String
registry_path::String
name::String
uuid::UUID
end
include("pkg_entry.jl")
include("registry_instance.jl")

struct RegistryInstance
path::String
name::String
uuid::UUID
url::Union{String, Nothing}
repo::Union{String, Nothing}
description::Union{String, Nothing}
pkgs::Dict{AbstractString, PkgEntry}
end

function RegistryInstance(path::AbstractString)
d = parsefile(joinpath(path, "Registry.toml"))
pkgs = Dict{AbstractString, PkgEntry}()

for (uuid, info) in d["packages"]
uuid = UUID(uuid)
info
name = info["name"]
pkgpath = info["path"]
pkg = PkgEntry(pkgpath, path, name, uuid)
pkgs[name] = pkg
end
"""
_get_latest_version(base_path::AbstractString)
Get the latest VersionNumber for base_path/Versions.toml
return RegistryInstance(
path,
d["name"],
UUID(d["uuid"]),
get(d, "url", nothing),
get(d, "repo", nothing),
get(d, "description", nothing),
pkgs
)
# Arguments
- `base_path::AbstractString`: Base path to look for Versions.toml
# Returns
- `VersionNumber`: Highest version number found in base_path/Versions.toml
# Throws
- `VersionTOMLNotFound`: Versions.toml does not exist at the base_path
"""
function _get_latest_version(base_path::AbstractString)
versions_file_path = joinpath(base_path, "Versions.toml")

if isfile(versions_file_path)
versions_content = parsefile(versions_file_path)
versions = [VersionNumber(v) for v in collect(keys(versions_content))]

return first(findmax(versions))
end
end


"""
reachable_registries(registry_names::Array)
Expand Down Expand Up @@ -92,7 +82,7 @@ reachable_registries(registry_name::String; depots::Union{String, Vector{String}


"""
find_upstream_dependencies(pkg_name::AbstractString; registries::Array{PkgDeps.RegistryInstance}=reachable_registries())
find_downstream_dependencies(pkg_name::AbstractString; registries::Array{PkgDeps.RegistryInstance}=reachable_registries())
Find all dependents of `pkg_name` for the current master version.
Expand All @@ -105,29 +95,38 @@ Find all dependents of `pkg_name` for the current master version.
# Returns
- `Array{String}`: List of packages which depend on `pkg_name`
"""
function find_upstream_dependencies(pkg_name::AbstractString; registries::Array{RegistryInstance}=reachable_registries())
upstream_dependencies = String[]
function find_downstream_dependencies(
pkg_name::AbstractString;
registries::Array{RegistryInstance}=reachable_registries()
)
downstream_dependencies = String[]

for rego in registries
for (pkg, v) in rego.pkgs
path = joinpath(v.registry_path, v.path, "Deps.toml")

if isfile(path)
file_contents = parsefile(path)

dep_keys = [k for k in collect(keys(file_contents)) if endswith(k, "-0") || k == "0"]

deps = getindex.(Ref(file_contents), dep_keys)
deps = vcat(collect.(keys.(deps))...)

if pkg_name in deps
push!(upstream_dependencies, pkg)
base_path = joinpath(v.registry_path, v.path)
deps_file_path = joinpath(base_path, "Deps.toml")

if isfile(deps_file_path)
deps_content = parsefile(deps_file_path)
dependency_versions = collect(keys(deps_content))
latest_version = _get_latest_version(base_path)

# Use the latest_version of pkg, and check to see if pkg_name is in its dependents
for version_range in dependency_versions
if in(latest_version, VersionRange(version_range))
dependencies = collect(keys(deps_content[version_range]))

# Check if pkg_name is used in the latest version of pkg
if pkg_name in dependencies
push!(downstream_dependencies, pkg)
end
end
end
end
end
end

return upstream_dependencies
return downstream_dependencies
end

end
6 changes: 6 additions & 0 deletions src/pkg_entry.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
struct PkgEntry
path::String
registry_path::String
name::String
uuid::UUID
end
33 changes: 33 additions & 0 deletions src/registry_instance.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
struct RegistryInstance
path::String
name::String
uuid::UUID
url::Union{String, Nothing}
repo::Union{String, Nothing}
description::Union{String, Nothing}
pkgs::Dict{AbstractString, PkgEntry}
end

function RegistryInstance(path::AbstractString)
d = parsefile(joinpath(path, "Registry.toml"))
pkgs = Dict{AbstractString, PkgEntry}()

for (uuid, info) in d["packages"]
uuid = UUID(uuid)
info
name = info["name"]
pkgpath = info["path"]
pkg = PkgEntry(pkgpath, path, name, uuid)
pkgs[name] = pkg
end

return RegistryInstance(
path,
d["name"],
UUID(d["uuid"]),
get(d, "url", nothing),
get(d, "repo", nothing),
get(d, "description", nothing),
pkgs
)
end
2 changes: 1 addition & 1 deletion test/resources/registries/Foobar/Case1/Deps.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
[0]
UpDep = "000eeb74-f857-587a-a816-be5685e97e75"
DownDep = "000eeb74-f857-587a-a816-be5685e97e75"
2 changes: 2 additions & 0 deletions test/resources/registries/Foobar/Case1/Versions.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
["0.0.1"]
git-tree-sha1 = "7bbdd841302ae0708824fa57d77a3e4780097531"
2 changes: 1 addition & 1 deletion test/resources/registries/Foobar/Case2/Deps.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
["0.1-0"]
UpDep = "000eeb74-f857-587a-a816-be5685e97e75"
DownDep = "000eeb74-f857-587a-a816-be5685e97e75"
2 changes: 2 additions & 0 deletions test/resources/registries/Foobar/Case2/Versions.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
["0.1.0"]
git-tree-sha1 = "7bbdd841302ae0708824fa57d77a3e4780097531"
4 changes: 2 additions & 2 deletions test/resources/registries/General/Case3/Deps.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
["0"]
UpDep = "000eeb74-f857-587a-a816-be5685e97e75"
["1"]
DownDep = "000eeb74-f857-587a-a816-be5685e97e75"
2 changes: 2 additions & 0 deletions test/resources/registries/General/Case3/Versions.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
["1.1.1"]
git-tree-sha1 = "7bbdd841302ae0708824fa57d77a3e4780097531"
2 changes: 2 additions & 0 deletions test/resources/registries/General/Case4/Deps.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
["0-0.1"]
DownDep = "000eeb74-f857-587a-a816-be5685e97e75"
5 changes: 5 additions & 0 deletions test/resources/registries/General/Case4/Versions.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
["0.1.0"]
git-tree-sha1 = "7bbdd841302ae0708824fa57d77a3e4780097531"

["0.2.0"]
git-tree-sha1 = "36895c2e78b43dea83b9fdba6655886c107cdc98"
1 change: 1 addition & 0 deletions test/resources/registries/General/Registry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ some amount of consideration when choosing package names.

[packages]
000eeb74-f857-587a-a816-be5685e97e75 = { name = "Case3", path = "Case3" }
001eeb74-f857-587a-a816-be5685e97e75 = { name = "Case4", path = "Case4" }
19 changes: 19 additions & 0 deletions test/resources/registries/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
## Creating test cases
When adding test cases please create another test case in any existing registry.
Include `Deps.toml` and `Versions.toml` files to specify when a package has been dependent
on another.


## Overview of Cases

### Case1
Single patch pre-1.0 release that has always been dependent on `DownDep`.

### Case2
Single minor pre-1.0 release that has always been dependent on `DownDep`.

### Case3
Single post-1.0 release that is dependent on `DownDep`.

### Case4
Two releases where `DownDep` was previously a depdenency and no longer is.
15 changes: 7 additions & 8 deletions test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
using PkgDeps
using Test
# Create some temp package TOML files
# Test that we get them properly

depot = joinpath(@__DIR__, "resources")

Expand All @@ -20,21 +18,22 @@ depot = joinpath(@__DIR__, "resources")
end
end

@testset "find_upstream_dependencies" begin
@testset "specific registry" begin
foobar_registry = reachable_registries("Foobar"; depots=depot)
@testset "find_downstream_dependencies" begin
foobar_registry = reachable_registries("Foobar"; depots=depot)
all_registries = reachable_registries(; depots=depot)

dependents = find_upstream_dependencies("UpDep"; registries=foobar_registry)
@testset "specific registry" begin
dependents = find_downstream_dependencies("DownDep"; registries=foobar_registry)

@test length(dependents) == 2
[@test case in dependents for case in ["Case1", "Case2"]]
end

@testset "all registries" begin
registries = reachable_registries(; depots=depot)
dependents = find_upstream_dependencies("UpDep"; registries=registries)
dependents = find_downstream_dependencies("DownDep"; registries=all_registries)

@test length(dependents) == 3
@test !("Case4" in dependents)
[@test case in dependents for case in ["Case1", "Case2", "Case3"]]
end
end

4 comments on commit f70f26c

@mattBrzezinski
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mattBrzezinski
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mattBrzezinski
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/33925

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.2.0 -m "<description of version>" f70f26c8d104af4f4f5fb364f0c9bc6a58d1785f
git push origin v0.2.0

Please sign in to comment.