Skip to content

Commit

Permalink
Add ability to split arguments and provide remaining unparsed arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
piotrmurach committed Apr 14, 2020
1 parent d248f64 commit 526256e
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 2 deletions.
21 changes: 20 additions & 1 deletion lib/tty/option.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,33 @@ def self.included(base)
end

module Interface
# The parsed parameters
#
# @api public
def parameters
@parameters ||= {}
end
alias :params :parameters

# The remaining unparsed arguments
#
# @api public
def remaining
@remaining ||= []
end
alias :remaining_args :remaining

# Parse command line arguments
#
# @param [Array<String>] argv
# the command line arguments
# @param [Hash] env
# the hash of environment variables
#
# @api public
def parse(argv = ARGV, env = ENV)
parser = Parser.new(self.class.parameters)
@parameters = parser.parse(argv, env)
@parameters, @remaining = parser.parse(argv, env)
end
end
end # Option
Expand Down
15 changes: 14 additions & 1 deletion lib/tty/option/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,24 @@ class Parser
environments: TTY::Option::Parser::Environments
}

ARGUMENT_SEPARATOR = /^-{2,}$/.freeze

def initialize(parameters)
@parameters = parameters
end

def parse(argv, env)
argv = argv.dup
params = {}
ignored = []

# split argv into processable args and leftovers
stop_index = argv.index { |arg| arg.match(ARGUMENT_SEPARATOR) }

if stop_index
ignored = argv.slice!(stop_index..-1)
ignored.shift
end

PARAMETER_PARSERS.each do |name, parser_type|
parser = parser_type.new(parameters.send(name))
Expand All @@ -47,7 +58,9 @@ def parse(argv, env)
params.merge!(parsed)
end

params
argv += ignored unless ignored.empty?

[params, argv]
end
end # Parser
end # Option
Expand Down
42 changes: 42 additions & 0 deletions spec/unit/parse_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -624,4 +624,46 @@ def new_command(&block)
expect(cmd.params[:cmd_env]).to eq("production")
end
end

context "stops parsing on --" do
it "doesn't include arguments -- split" do
cmd = new_command { }

cmd.parse(%w[--])

expect(cmd.params).to be_empty
expect(cmd.remaining).to eq([])
end

it "doesn't include arguments after --- split" do
cmd = new_command { }

cmd.parse(%w[--- a b])

expect(cmd.params).to be_empty
expect(cmd.remaining).to eq(%w[a b])
end

it "parses anything after -- as remaining arguments" do
cmd = new_command do
option :foo do
arity one_or_more
short "-f"
long "--foo list"
convert :list
end

option :bar do
optional
short "-b"
long "--bar string"
end
end

cmd.parse(%w[--foo a b -- --bar c d])

expect(cmd.params[:foo]).to eq(%w[a b])
expect(cmd.remaining).to eq(%w[--bar c d])
end
end
end

0 comments on commit 526256e

Please sign in to comment.