Skip to content

Commit

Permalink
add --all option to rm, pin, free (#2432)
Browse files Browse the repository at this point in the history
* add --all operator to rm, pin, free

* add note to changelog
  • Loading branch information
IanButterworth authored Mar 18, 2021
1 parent c4d18ce commit af7e41c
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 17 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ Pkg v1.7 Release Notes
======================

- Adding packages by folder name in the REPL mode now requires a prepending a `./` to the folder name package folder is in the current folder, e.g. `add ./Package` is required instead of `add Pacakge`. This is to avoid confusion between the package name `Package` and the local directory `Package`.
- `rm`, `pin`, and `free` now support the `--all` option, and the api variants gain the `all_pkgs::Bool` kwarg, to perform the operation on all packages within the project or manifest, depending on the mode of the operation.
42 changes: 30 additions & 12 deletions src/API.jl
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,11 @@ function add(ctx::Context, pkgs::Vector{PackageSpec}; preserve::PreserveLevel=PR
return
end

function rm(ctx::Context, pkgs::Vector{PackageSpec}; mode=PKGMODE_PROJECT, kwargs...)
function rm(ctx::Context, pkgs::Vector{PackageSpec}; mode=PKGMODE_PROJECT, all_pkgs::Bool=false, kwargs...)
if all_pkgs
!isempty(pkgs) && pkgerror("cannot specify packages when operating on all packages")
append_all_pkgs!(pkgs, ctx, mode)
end
require_not_empty(pkgs, :rm)
pkgs = deepcopy(pkgs) # deepcopy for avoid mutating PackageSpec members
foreach(pkg -> pkg.mode = mode, pkgs)
Expand All @@ -297,6 +301,20 @@ function rm(ctx::Context, pkgs::Vector{PackageSpec}; mode=PKGMODE_PROJECT, kwarg
return
end

function append_all_pkgs!(pkgs, ctx, mode)
if mode == PKGMODE_PROJECT || mode == PKGMODE_COMBINED
for (name::String, uuid::UUID) in ctx.env.project.deps
push!(pkgs, PackageSpec(name=name, uuid=uuid))
end
end
if mode == PKGMODE_MANIFEST || mode == PKGMODE_COMBINED
for (uuid, entry) in ctx.env.manifest
push!(pkgs, PackageSpec(name=entry.name, uuid=uuid))
end
end
return
end

function up(ctx::Context, pkgs::Vector{PackageSpec};
level::UpgradeLevel=UPLEVEL_MAJOR, mode::PackageMode=PKGMODE_PROJECT,
update_registry::Bool=true, kwargs...)
Expand All @@ -311,15 +329,7 @@ function up(ctx::Context, pkgs::Vector{PackageSpec};
end
Operations.prune_manifest(ctx.env)
if isempty(pkgs)
if mode == PKGMODE_PROJECT
for (name::String, uuid::UUID) in ctx.env.project.deps
push!(pkgs, PackageSpec(name=name, uuid=uuid))
end
elseif mode == PKGMODE_MANIFEST
for (uuid, entry) in ctx.env.manifest
push!(pkgs, PackageSpec(name=entry.name, uuid=uuid))
end
end
append_all_pkgs!(pkgs, ctx, mode)
else
project_deps_resolve!(ctx.env, pkgs)
manifest_resolve!(ctx.env.manifest, pkgs)
Expand All @@ -335,7 +345,11 @@ function resolve(ctx::Context; kwargs...)
return nothing
end

function pin(ctx::Context, pkgs::Vector{PackageSpec}; kwargs...)
function pin(ctx::Context, pkgs::Vector{PackageSpec}; all_pkgs::Bool=false, kwargs...)
if all_pkgs
!isempty(pkgs) && pkgerror("cannot specify packages when operating on all packages")
append_all_pkgs!(pkgs, ctx, PKGMODE_PROJECT)
end
require_not_empty(pkgs, :pin)
pkgs = deepcopy(pkgs) # deepcopy for avoid mutating PackageSpec members
Context!(ctx; kwargs...)
Expand Down Expand Up @@ -364,7 +378,11 @@ function pin(ctx::Context, pkgs::Vector{PackageSpec}; kwargs...)
return
end

function free(ctx::Context, pkgs::Vector{PackageSpec}; kwargs...)
function free(ctx::Context, pkgs::Vector{PackageSpec}; all_pkgs::Bool=false, kwargs...)
if all_pkgs
!isempty(pkgs) && pkgerror("cannot specify packages when operating on all packages")
append_all_pkgs!(pkgs, ctx, PKGMODE_PROJECT)
end
require_not_empty(pkgs, :free)
pkgs = deepcopy(pkgs) # deepcopy for avoid mutating PackageSpec members
Context!(ctx; kwargs...)
Expand Down
23 changes: 18 additions & 5 deletions src/REPLMode/command_declarations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,18 @@ PSA[:name => "remove",
:short_name => "rm",
:api => API.rm,
:should_splat => false,
:arg_count => 1 => Inf,
:arg_count => 0 => Inf,
:arg_parser => parse_package,
:option_spec => [
PSA[:name => "project", :short_name => "p", :api => :mode => PKGMODE_PROJECT],
PSA[:name => "manifest", :short_name => "m", :api => :mode => PKGMODE_MANIFEST],
PSA[:name => "all", :api => :all_pkgs => true],
],
:completions => complete_installed_packages,
:description => "remove packages from project or manifest",
:help => md"""
[rm|remove] [-p|--project] pkg[=uuid] ...
[rm|remove] [-p|--project] [--all]
Remove package `pkg` from the project file. Since the name `pkg` can only
refer to one package in a project this is unambiguous, but you can specify
Expand All @@ -78,14 +80,16 @@ and UUID do not match. When a package is removed from the project file, it
may still remain in the manifest if it is required by some other package in
the project. Project mode operation is the default, so passing `-p` or
`--project` is optional unless it is preceded by the `-m` or `--manifest`
options at some earlier point.
options at some earlier point. All packages can be removed by passing `--all`.
[rm|remove] [-m|--manifest] pkg[=uuid] ...
[rm|remove] [-m|--manifest] [--all]
Remove package `pkg` from the manifest file. If the name `pkg` refers to
multiple packages in the manifest, `uuid` disambiguates it. Removing a package
from the manifest forces the removal of all packages that depend on it, as well
as any no-longer-necessary manifest packages due to project package removals.
All packages can be removed by passing `--all`.
""",
],
PSA[:name => "add",
Expand Down Expand Up @@ -176,26 +180,34 @@ pkg> develop --local Example
PSA[:name => "free",
:api => API.free,
:should_splat => false,
:arg_count => 1 => Inf,
:arg_count => 0 => Inf,
:option_spec => [
PSA[:name => "all", :api => :all_pkgs => true],
],
:arg_parser => parse_package,
:completions => complete_installed_packages,
:description => "undoes a `pin`, `develop`, or stops tracking a repo",
:help => md"""
free pkg[=uuid] ...
free [--all]
Free a pinned package `pkg`, which allows it to be upgraded or downgraded again. If the package is checked out (see `help develop`) then this command
Free pinned packages, which allows it to be upgraded or downgraded again. If the package is checked out (see `help develop`) then this command
makes the package no longer being checked out.
""",
],
PSA[:name => "pin",
:api => API.pin,
:should_splat => false,
:arg_count => 1 => Inf,
:arg_count => 0 => Inf,
:option_spec => [
PSA[:name => "all", :api => :all_pkgs => true],
],
:arg_parser => parse_package,
:completions => complete_installed_packages,
:description => "pins the version of packages",
:help => md"""
pin pkg[=uuid] ...
pin [--all]
Pin packages to given versions, or the current version if no version is specified. A pinned package has its version fixed and will not be upgraded or downgraded.
A pinned package has the symbol `⚲` next to its version in the status list.
Expand All @@ -205,6 +217,7 @@ A pinned package has the symbol `⚲` next to its version in the status list.
pkg> pin Example
pkg> pin Example@0.5.0
pkg> pin Example=7876af07-990d-54b4-ab0e-23690620f79a@0.5.0
pkg> pin --all
```
""",
],
Expand Down
35 changes: 35 additions & 0 deletions test/new.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1760,6 +1760,41 @@ end
end
end

#
# # `all` operations
#
@testset "all" begin
# pin all, free all, rm all packages
isolate(loaded_depot=true) do
Pkg.add("Example")
Pkg.pin(all_pkgs = true)
Pkg.free(all_pkgs = true)
Pkg.dependencies(exuuid) do pkg
@test pkg.name == "Example"
@test !pkg.is_pinned
end
Pkg.rm(all_pkgs = true)
@test !haskey(Pkg.dependencies(), exuuid)
end
isolate() do
Pkg.REPLMode.TEST_MODE[] = true
api, args, opts = first(Pkg.pkg"pin --all")
@test api == Pkg.pin
@test isempty(args)
@test opts == Dict(:all_pkgs => true)

api, args, opts = first(Pkg.pkg"free --all")
@test api == Pkg.free
@test isempty(args)
@test opts == Dict(:all_pkgs => true)

api, args, opts = first(Pkg.pkg"rm --all")
@test api == Pkg.rm
@test isempty(args)
@test opts == Dict(:all_pkgs => true)
end
end

#
# # build
#
Expand Down

0 comments on commit af7e41c

Please sign in to comment.