Improve CLI usage:

* Rewrite arguments parsing with OptionParser;
* Allow processing of multiple recipes.
This commit is contained in:
Thibault Jouan
2014-09-26 14:16:26 +00:00
parent 85ee79ab88
commit 7a7c8379ff
4 changed files with 124 additions and 90 deletions

View File

@@ -1,5 +1,6 @@
require 'etc'
require 'forwardable'
require 'optparse'
require 'pathname'
require 'net/ssh'

View File

@@ -3,8 +3,7 @@ module Producer
class CLI
ArgumentError = Class.new(::ArgumentError)
OPTIONS_USAGE = '[-v] [-n] [-t host.example]'.freeze
USAGE = "Usage: #{File.basename $0} #{OPTIONS_USAGE} recipe_file".freeze
USAGE = "Usage: #{File.basename $0} [options] [recipes]".freeze
EX_USAGE = 64
EX_SOFTWARE = 70
@@ -15,8 +14,8 @@ module Producer
begin
cli.parse_arguments!
cli.run
rescue ArgumentError
stderr.puts USAGE
rescue ArgumentError => e
stderr.puts e.message
exit EX_USAGE
rescue RuntimeError => e
stderr.puts "#{e.class.name.split('::').last}: #{e.message}"
@@ -25,40 +24,55 @@ module Producer
end
end
attr_reader :arguments, :env
attr_reader :arguments, :stdin, :stdout, :stderr, :env
def initialize(args, stdin: $stdin, stdout: $stdout, stderr: $stderr)
@arguments = args
@stdin = stdin
@stdout = stdout
@env = Env.new(input: stdin, output: stdout, error_output: stderr)
@stderr = stderr
@env = build_env
end
def parse_arguments!
@arguments = arguments.each_with_index.inject([]) do |m, (e, i)|
case e
when '-v'
env.verbose = true
when '-n'
env.dry_run = true
when '-t'
env.target = arguments.delete_at i + 1
else
m << e
end
m
end
fail ArgumentError unless @arguments.any?
option_parser.parse!(@arguments)
fail ArgumentError, option_parser if @arguments.empty?
end
def run(worker: Worker.new(@env))
worker.process recipe.tasks
evaluate_recipes.each { |recipe| worker.process recipe.tasks }
@env.cleanup
end
def recipe
@recipe ||= Recipe::FileEvaluator.evaluate(@arguments.first, env)
def evaluate_recipes
@arguments.map { |e| Recipe::FileEvaluator.evaluate(e, @env) }
end
private
def build_env
Env.new(input: @stdin, output: @stdout, error_output: @stderr)
end
def option_parser
OptionParser.new do |opts|
opts.banner = USAGE
opts.separator ''
opts.separator 'options:'
opts.on '-v', '--verbose', 'enable verbose mode' do |e|
env.verbose = true
end
opts.on '-n', '--dry-run', 'enable dry run mode' do |e|
env.dry_run = true
end
opts.on '-t', '--target HOST', 'target host' do |e|
env.target = e
end
end
end
end
end