Skip to content

Commit

Permalink
Introduce special REPL syntax for shared environments
Browse files Browse the repository at this point in the history
  • Loading branch information
00vareladavid committed Nov 6, 2019
1 parent 6077023 commit 87f0008
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 22 deletions.
13 changes: 7 additions & 6 deletions src/REPLMode/REPLMode.jl
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ struct CommandSpec
help::Union{Nothing,Markdown.MD}
end

default_parser(xs, options) = unwrap(xs)
function CommandSpec(;name::Union{Nothing,String} = nothing,
short_name::Union{Nothing,String} = nothing,
api::Union{Nothing,Function} = nothing,
Expand All @@ -87,7 +88,7 @@ function CommandSpec(;name::Union{Nothing,String} = nothing,
description::Union{Nothing,String} = nothing,
completions::Union{Nothing,Function} = nothing,
arg_count::Pair = (0=>0),
arg_parser::Function = unwrap,
arg_parser::Function = default_parser,
)::CommandSpec
@assert name !== nothing "Supply a canonical name"
@assert description !== nothing "Supply a description"
Expand Down Expand Up @@ -357,16 +358,16 @@ Final parsing (and checking) step.
This step is distinct from `parse` in that it relies on the command specifications.
"""
function Command(statement::Statement)::Command
# options
opt_spec = statement.spec.option_specs
enforce_option(statement.options, opt_spec)
options = APIOptions(statement.options, opt_spec)
# arguments
arg_spec = statement.spec.argument_spec
arguments = arg_spec.parser(statement.arguments)
arguments = arg_spec.parser(statement.arguments, options)
if !(arg_spec.count.first <= length(arguments) <= arg_spec.count.second)
pkgerror("Wrong number of arguments")
end
# options
opt_spec = statement.spec.option_specs
enforce_option(statement.options, opt_spec)
options = APIOptions(statement.options, opt_spec)
return Command(statement.spec, options, arguments)
end

Expand Down
22 changes: 18 additions & 4 deletions src/REPLMode/argument_parsers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import ..isdir_windows_workaround
"""
Parser for PackageSpec objects.
"""
function parse_package(args::Vector{QString}; add_or_dev=false)::Vector{PackageSpec}
function parse_package(args::Vector{QString}, options; add_or_dev=false)::Vector{PackageSpec}
args::Vector{PackageToken} = map(PackageToken, package_lex(args))
return parse_package_args(args; add_or_dev=add_or_dev)
end
Expand Down Expand Up @@ -95,7 +95,7 @@ end
################
# RegistrySpec #
################
function parse_registry(raw_args::Vector{QString}; add=false)
function parse_registry(raw_args::Vector{QString}, options; add=false)
regs = RegistrySpec[]
foreach(x -> push!(regs, parse_registry(x; add=add)), unwrap(raw_args))
return regs
Expand Down Expand Up @@ -132,8 +132,22 @@ end
#
# # Other
#
function parse_activate(args::Vector{QString})::Vector{String}
return [(x.isquoted ? x.raw : expanduser(x.raw)) for x in args]
function parse_activate(args::Vector{QString}, options)
isempty(args) && return [] # nothing to do
if length(args) == 1
x = first(args)
if x.isquoted
return [x.raw]
end
x = x.raw
if first(x) == '@'
options[:shared] = true
return [x[2:end]]
else
return [expanduser(x)]
end
end
return args # this is currently invalid input for "activate"
end

#
Expand Down
10 changes: 5 additions & 5 deletions src/REPLMode/command_declarations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ julia is started with `--startup-file=yes`.
:short_name => "?",
:api => identity, # dummy API function
:arg_count => 0 => Inf,
:arg_parser => identity,
:arg_parser => ((x,y) -> x),
:completions => complete_help,
:description => "show this message",
:help => md"""
Expand Down Expand Up @@ -86,7 +86,7 @@ as any no-longer-necessary manifest packages due to project package removals.
:api => API.add,
:should_splat => false,
:arg_count => 1 => Inf,
:arg_parser => (x -> parse_package(x; add_or_dev=true)),
:arg_parser => ((x,y) -> parse_package(x,y; add_or_dev=true)),
:option_spec => OptionDeclaration[
[:name => "preserve", :takes_arg => true, :api => :preserve => do_preserve],
],
Expand Down Expand Up @@ -135,7 +135,7 @@ pkg> add Example=7876af07-990d-54b4-ab0e-23690620f79a
:api => API.develop,
:should_splat => false,
:arg_count => 1 => Inf,
:arg_parser => (x -> parse_package(x; add_or_dev=true)),
:arg_parser => ((x,y) -> parse_package(x,y; add_or_dev=true)),
:option_spec => OptionDeclaration[
[:name => "strict", :api => :strict => true],
[:name => "local", :api => :shared => false],
Expand Down Expand Up @@ -274,7 +274,7 @@ packages will not be upgraded at all.
],[ :name => "generate",
:api => API.generate,
:arg_count => 1 => 1,
:arg_parser => x -> map(expanduser, unwrap(x)),
:arg_parser => ((x,y) -> map(expanduser, unwrap(x))),
:description => "generate files for a new project",
:help => md"""
generate pkgname
Expand Down Expand Up @@ -356,7 +356,7 @@ Redoes the changes from the latest [`undo`](@ref).
:api => Registry.add,
:should_splat => false,
:arg_count => 1 => Inf,
:arg_parser => (x -> parse_registry(x; add = true)),
:arg_parser => ((x,y) -> parse_registry(x,y; add = true)),
:description => "add package registries",
:help => md"""
registry add reg...
Expand Down
20 changes: 13 additions & 7 deletions src/REPLMode/completions.jl
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
########################
# Completion Functions #
########################
function complete_activate(options, partial, i1, i2)
function _shared_envs()
possible = String[]
for depot in Base.DEPOT_PATH
envdir = joinpath(depot, "environments")
isdir(envdir) || continue
append!(possible, readdir(envdir))
end
return possible
end

function complete_activate(options, partial, i1, i2)
shared = get(options, :shared, false)
if shared
for depot in Base.DEPOT_PATH
envdir = joinpath(depot, "environments")
isdir(envdir) || continue
append!(possible, readdir(envdir))
end
return possible
return _shared_envs()
elseif !isempty(partial) && first(partial) == '@'
return "@" .* _shared_envs()
else
return complete_local_dir(partial, i1, i2)
end
Expand Down
28 changes: 28 additions & 0 deletions test/new.jl
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,34 @@ simple_package_uuid = UUID("fc6b7c0f-8a2f-4256-bbf4-8c72c30df5be")
end
end

#
# # Activate
#
@testset "activate: repl" begin
isolate(loaded_depot=true) do
Pkg.REPLMode.TEST_MODE[] = true
# - activate shared env
api, args, opts = first(Pkg.pkg"activate --shared Foo")
@test api == Pkg.activate
@test args == "Foo"
@test opts == Dict(:shared => true)
# - activate shared env using special syntax
api, args, opts = first(Pkg.pkg"activate @Foo")
@test api == Pkg.activate
@test args == "Foo"
@test opts == Dict(:shared => true)
# - no arg activate
api, opts = first(Pkg.pkg"activate")
@test api == Pkg.activate
@test isempty(opts)
# - regular activate
api, args, opts = first(Pkg.pkg"activate FooBar")
@test api == Pkg.activate
@test args == "FooBar"
@test isempty(opts)
end
end

#
# # Add
#
Expand Down

0 comments on commit 87f0008

Please sign in to comment.