Skip to content

Commit

Permalink
Introduce query API
Browse files Browse the repository at this point in the history
  • Loading branch information
00vareladavid committed May 31, 2019
1 parent cee1d07 commit 885594a
Show file tree
Hide file tree
Showing 7 changed files with 143 additions and 48 deletions.
1 change: 1 addition & 0 deletions docs/src/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Pkg.gc
Pkg.status
Pkg.precompile
Pkg.setprotocol!
Pkg.info
```


Expand Down
33 changes: 22 additions & 11 deletions src/API.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,28 @@ preview_info() = printstyled("───── Preview mode ─────\n"; c

include("generate.jl")

info(;kwargs...) = info(Context(), PackageSpec[]; kwargs...)
info(uuid::UUID; kwargs...) = info([uuid]; kwargs...)
info(uuids::Vector{UUID}; kwargs...) = info(Context(), [PackageSpec(;uuid=uuid) for uuid in uuids]; kwargs...)
function info(ctx::Context, pkgs::Vector{PackageSpec};
active=false, direct=false, all=false, kwargs...
)::Dict{UUID, PackageInfo}
if active
if ctx.env.pkg === nothing
@warn "Active environment is not a project"
else
pkg = deepcopy(ctx.env.pkg)
pkg.path = dirname(ctx.env.project_file)
push!(pkgs, pkg)
end
end
direct && Operations.load_direct_deps!(ctx, pkgs)
all && Opeartions.load_all_deps!(ctx, pkgs)

find_registered!(ctx.env, UUID[pkg.uuid for pkg in pkgs])
return Dict(pkg.uuid => Operations.package_info(ctx, pkg; kwargs...) for pkg in pkgs)
end

function check_package_name(x::AbstractString, mode=nothing)
if !(occursin(Pkg.REPLMode.name_re, x))
message = "$x is not a valid packagename."
Expand Down Expand Up @@ -246,17 +268,6 @@ function test(ctx::Context, pkgs::Vector{PackageSpec};
return
end

installed() = __installed(PKGMODE_PROJECT)
function __installed(mode::PackageMode=PKGMODE_MANIFEST)
diffs = Display.status(Context(), PackageSpec[], mode=mode, use_as_api=true)
version_status = Dict{String, Union{VersionNumber,Nothing}}()
diffs == nothing && return version_status
for entry in diffs
version_status[entry.name] = entry.new.ver
end
return version_status
end

function gc(ctx::Context=Context(); kwargs...)
Context!(ctx; kwargs...)
ctx.preview && preview_info()
Expand Down
13 changes: 13 additions & 0 deletions src/Operations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ end

function load_all_deps!(ctx::Context, pkgs::Vector{PackageSpec}; version::Bool=true)
for (uuid, entry) in ctx.env.manifest
pkgs[uuid] === nothing || continue # dont duplicate packages
push!(pkgs, PackageSpec(name=entry.name, uuid=uuid, path=entry.path,
version = version ? something(entry.version, VersionSpec()) : VersionSpec(),
repo=entry.repo, tree_hash=entry.tree_hash))
Expand Down Expand Up @@ -1298,4 +1299,16 @@ function test(ctx::Context, pkgs::Vector{PackageSpec}; coverage=false, test_fn=n
end
end

function package_info(ctx::Context, pkg::PackageSpec;
name=false, version=false, pinned=false, developed=false, source=false
)::PackageInfo
info = PackageInfo()
name && (info.name = pkg.name)
version && (info.version = (pkg.version == VersionSpec() ? nothing : pkg.version))
pinned && (info.pinned = pkg.pinned)
source && (info.source = project_rel_path(ctx, source_path(pkg)))
developed && (info.developed = pkg.path !== nothing)
return info
end

end # module
44 changes: 41 additions & 3 deletions src/Pkg.jl
Original file line number Diff line number Diff line change
Expand Up @@ -198,9 +198,6 @@ redirecting to the `build.log` file.
"""
const build = API.build

# TODO: decide what to do with this
const installed = API.installed

"""
Pkg.pin(pkg::Union{String, Vector{String}})
Pkg.pin(pkgs::Union{PackageSpec, Vector{PackageSpec}})
Expand Down Expand Up @@ -264,6 +261,47 @@ const develop = API.develop
#TODO: Will probably be deprecated for something in PkgDev
const generate = API.generate

"""
Pkg.info(; keywords...)::Dict{UUID, PackageInfo}
Pkg.info(uuid::UUID; keywords...)::Dict{UUID, PackageInfo}
Pkg.info(uuids::Vector{UUID}; keywords...)::Dict{UUID, PackageInfo}
Query the dependecy graph.
You can choose which packages to query by specyfing a list of uuids or by using *selector* keywords.
`Pkg.info` accepts two classes of keywords **selectors** and **properties**.
**Selectors** will add certain packages to the set of packages to be queried.
**Properties** determine which package properties will be queried and written to the `PackageInfo` structs.
`nothing` is used as the default value of `PackageInfo` fields when no query has been executed.
Selectors:
| `keyword` | `API` |
|:----------|:------------------------------------------------------------------------------------|
| `active` | If the active environment is a project, add it to the set of packages to be queried |
| `direct` | Add all direct dependecies to the set of packages to be queried |
| `all` | Add all dependencies to the set of packages to be queried |
Properites:
| `keyword` | `Type` | `Description` |
|:------------|:----------------|:---------------------------------------------------|
| `name` | `String` | The name of the package |
| `version` | `VersionNumber` | The version of the package |
| `developed` | `Bool` | Whether a package is directly tracking a directory |
| `pinned` | `Bool` | Whether a package is pinned |
| `source` | `String` | The directory containing the package's source code |
# Examples
```
Pkg.info(;direct=true, name=true, version=true)
Pkg.info(UUID("7876af07-990d-54b4-ab0e-23690620f79a"); developed=true)
Pkg.info(UUID("7876af07-990d-54b4-ab0e-23690620f79a"); direct=true, developed=true)
```
"""
const info = API.info

"""
Pkg.instantiate()
Expand Down
14 changes: 13 additions & 1 deletion src/Types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ using SHA

export UUID, pkgID, SHA1, VersionRange, VersionSpec, empty_versionspec,
Requires, Fixed, merge_requires!, satisfies, ResolverError,
PackageSpec, EnvCache, Context, GitRepo, Context!, get_deps,
PackageSpec, EnvCache, Context, PackageInfo, GitRepo, Context!, get_deps,
PkgError, pkgerror, has_name, has_uuid, is_stdlib, write_env, parse_toml, find_registered!,
project_resolve!, project_deps_resolve!, manifest_resolve!, registry_resolve!, stdlib_resolve!, handle_repos_develop!, handle_repos_add!, ensure_resolved, instantiate_pkg_repo!,
manifest_info, registered_uuids, registered_paths, registered_uuid, registered_name,
Expand Down Expand Up @@ -1348,4 +1348,16 @@ function write_env(ctx::Context; display_diff=true)
write_manifest(env.manifest, env, old_env, ctx; display_diff=display_diff)
end

###
### PackageInfo
###

Base.@kwdef mutable struct PackageInfo
name::Union{Nothing,String} = nothing
version::Union{Nothing,VersionNumber} = nothing
pinned::Union{Nothing,Bool} = nothing
developed::Union{Nothing,Bool} = nothing
source::Union{Nothing,String} = nothing
end

end # module
53 changes: 35 additions & 18 deletions test/pkg.jl
Original file line number Diff line number Diff line change
Expand Up @@ -147,21 +147,21 @@ temp_pkg_dir() do project_path
@testset "adding and upgrading different versions" begin
# VersionNumber
Pkg.add(PackageSpec(TEST_PKG.name, v"0.3"))
@test Pkg.API.__installed()[TEST_PKG.name] == v"0.3"
@test Pkg.info(;direct=true,version=true)[TEST_PKG.uuid].version == v"0.3"
Pkg.add(PackageSpec(TEST_PKG.name, v"0.3.1"))
@test Pkg.API.__installed()[TEST_PKG.name] == v"0.3.1"
@test Pkg.info(;direct=true,version=true)[TEST_PKG.uuid].version == v"0.3.1"
Pkg.rm(TEST_PKG.name)

# VersionRange
Pkg.add(PackageSpec(TEST_PKG.name, VersionSpec(VersionRange("0.3.0-0.3.2"))))
@test Pkg.API.__installed()[TEST_PKG.name] == v"0.3.2"
@test Pkg.info(;direct=true,version=true)[TEST_PKG.uuid].version == v"0.3.2"
# Check that adding another packages doesn't upgrade other packages
Pkg.add("Test")
@test Pkg.API.__installed()[TEST_PKG.name] == v"0.3.2"
@test Pkg.info(;direct=true,version=true)[TEST_PKG.uuid].version == v"0.3.2"
Pkg.update(; level = UPLEVEL_PATCH)
@test Pkg.API.__installed()[TEST_PKG.name] == v"0.3.3"
@test Pkg.info(;direct=true,version=true)[TEST_PKG.uuid].version == v"0.3.3"
Pkg.update(; level = UPLEVEL_MINOR)
@test Pkg.API.__installed()[TEST_PKG.name].minor != 3
@test Pkg.info(;direct=true,version=true)[TEST_PKG.uuid].version.minor != 3
Pkg.rm(TEST_PKG.name)
end

Expand All @@ -177,27 +177,27 @@ temp_pkg_dir() do project_path

@testset "pinning / freeing" begin
Pkg.add(TEST_PKG.name)
old_v = Pkg.API.__installed()[TEST_PKG.name]
old_v = Pkg.info(;direct=true,version=true)[TEST_PKG.uuid].version
Pkg.pin(PackageSpec(TEST_PKG.name, v"0.2"))
@test Pkg.API.__installed()[TEST_PKG.name].minor == 2
@test Pkg.info(;direct=true,version=true)[TEST_PKG.uuid].version.minor == 2
Pkg.update(TEST_PKG.name)
@test Pkg.API.__installed()[TEST_PKG.name].minor == 2
@test Pkg.info(;direct=true,version=true)[TEST_PKG.uuid].version.minor == 2
Pkg.free(TEST_PKG.name)
Pkg.update()
@test Pkg.API.__installed()[TEST_PKG.name] == old_v
@test Pkg.info(;direct=true,version=true)[TEST_PKG.uuid].version == old_v
Pkg.rm(TEST_PKG.name)
end

@testset "develop / freeing" begin
Pkg.add(TEST_PKG.name)
old_v = Pkg.API.__installed()[TEST_PKG.name]
old_v = Pkg.info(;direct=true,version=true)[TEST_PKG.uuid].version
Pkg.rm(TEST_PKG.name)
mktempdir() do devdir
withenv("JULIA_PKG_DEVDIR" => devdir) do
@test_throws PkgError Pkg.develop(Pkg.PackageSpec(url="bleh", rev="blurg"))
Pkg.develop(TEST_PKG.name)
@test isinstalled(TEST_PKG)
@test Pkg.API.__installed()[TEST_PKG.name] > old_v
@test Pkg.info(;direct=true,version=true)[TEST_PKG.uuid].version > old_v
test_pkg_main_file = joinpath(devdir, TEST_PKG.name, "src", TEST_PKG.name * ".jl")
@test isfile(test_pkg_main_file)
# Pkg #152
Expand All @@ -223,7 +223,7 @@ temp_pkg_dir() do project_path
@test isfile(joinpath(devdir, TEST_PKG.name, "deps", "deps.jl"))
Pkg.test(TEST_PKG.name)
Pkg.free(TEST_PKG.name)
@test Pkg.API.__installed()[TEST_PKG.name] == old_v
@test Pkg.info(;direct=true,version=true)[TEST_PKG.uuid].version == old_v
end
end
end
Expand All @@ -235,7 +235,7 @@ temp_pkg_dir() do project_path
@testset "stdlibs as direct dependency" begin
uuid_pkg = (name = "CRC32c", uuid = UUID("8bf52ea8-c179-5cab-976a-9e18b702a9bc"))
Pkg.add("CRC32c")
@test haskey(Pkg.API.__installed(), uuid_pkg.name)
@test haskey(Pkg.info(;direct=true,version=true), TEST_PKG.uuid)
Pkg.update()
# Disable until fixed in Base
# Pkg.test("CRC32c")
Expand Down Expand Up @@ -332,7 +332,7 @@ end
temp_pkg_dir() do project_path
@testset "libgit2 downloads" begin
Pkg.add(TEST_PKG.name; use_libgit2_for_all_downloads=true)
@test haskey(Pkg.installed(), TEST_PKG.name)
@test haskey(Pkg.info(;direct=true,version=true), TEST_PKG.uuid)
@eval import $(Symbol(TEST_PKG.name))
@test_throws SystemError open(pathof(eval(Symbol(TEST_PKG.name))), "w") do io end # check read-only
Pkg.rm(TEST_PKG.name)
Expand All @@ -344,7 +344,7 @@ temp_pkg_dir() do project_path
cd(joinpath(dir, "UnregisteredWithProject")) do
with_current_env() do
Pkg.update()
@test haskey(Pkg.API.__installed(), "Example")
@test haskey(Pkg.info(;direct=true), TEST_PKG.uuid)
end
end
end
Expand All @@ -354,12 +354,12 @@ end
temp_pkg_dir() do project_path
@testset "libgit2 downloads" begin
Pkg.add(TEST_PKG.name; use_libgit2_for_all_downloads=true)
@test haskey(Pkg.API.__installed(), TEST_PKG.name)
@test haskey(Pkg.info(;direct=true), TEST_PKG.uuid)
Pkg.rm(TEST_PKG.name)
end
@testset "tarball downloads" begin
Pkg.add("JSON"; use_only_tarballs_for_downloads=true)
@test haskey(Pkg.API.__installed(), "JSON")
@test "JSON" in [pkg.name for (uuid, pkg) in Pkg.info(;direct=true,name=true)]
Pkg.rm("JSON")
end
end
Expand Down Expand Up @@ -775,6 +775,23 @@ end
end end
end

@testset "query interface basic tests" begin
temp_pkg_dir() do project_path; with_temp_env() do
Pkg.develop("Example")
Pkg.add("Unicode")
Pkg.add("Markdown")
info = Pkg.info(;direct=true, name=true, developed=true)
@test length(info) == 3
xs = Dict(uuid => pkg for (uuid, pkg) in info if pkg.developed)
@test length(xs) == 1
@test xs[TEST_PKG.uuid].name == "Example"
@test xs[TEST_PKG.uuid].pinned == nothing
@test xs[TEST_PKG.uuid].version == nothing
@test xs[TEST_PKG.uuid].developed == true
@test xs[TEST_PKG.uuid].source == nothing
end end
end

include("repl.jl")
include("api.jl")
include("registry.jl")
Expand Down
Loading

0 comments on commit 885594a

Please sign in to comment.