choosy 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.markdown +229 -221
- data/Rakefile +21 -3
- data/examples/bar.rb +44 -0
- data/examples/foo.rb +198 -0
- data/examples/superfoo.rb +125 -0
- data/lib/VERSION +1 -1
- data/lib/choosy/argument.rb +51 -0
- data/lib/choosy/base_command.rb +22 -7
- data/lib/choosy/command.rb +12 -4
- data/lib/choosy/dsl/argument_builder.rb +88 -0
- data/lib/choosy/dsl/base_command_builder.rb +71 -56
- data/lib/choosy/dsl/command_builder.rb +14 -2
- data/lib/choosy/dsl/option_builder.rb +43 -83
- data/lib/choosy/dsl/super_command_builder.rb +37 -9
- data/lib/choosy/option.rb +13 -11
- data/lib/choosy/parse_result.rb +8 -27
- data/lib/choosy/parser.rb +20 -16
- data/lib/choosy/printing/color.rb +39 -21
- data/lib/choosy/printing/erb_printer.rb +12 -3
- data/lib/choosy/printing/formatting_element.rb +17 -0
- data/lib/choosy/printing/help_printer.rb +204 -117
- data/lib/choosy/printing/terminal.rb +53 -0
- data/lib/choosy/super_command.rb +6 -6
- data/lib/choosy/super_parser.rb +26 -15
- data/lib/choosy/verifier.rb +61 -6
- data/spec/choosy/base_command_spec.rb +27 -2
- data/spec/choosy/command_spec.rb +31 -9
- data/spec/choosy/dsl/argument_builder_spec.rb +180 -0
- data/spec/choosy/dsl/base_command_builder_spec.rb +87 -44
- data/spec/choosy/dsl/commmand_builder_spec.rb +15 -4
- data/spec/choosy/dsl/option_builder_spec.rb +101 -191
- data/spec/choosy/dsl/super_command_builder_spec.rb +34 -9
- data/spec/choosy/parser_spec.rb +30 -8
- data/spec/choosy/printing/color_spec.rb +19 -5
- data/spec/choosy/printing/help_printer_spec.rb +152 -73
- data/spec/choosy/printing/terminal_spec.rb +27 -0
- data/spec/choosy/super_command_spec.rb +17 -17
- data/spec/choosy/super_parser_spec.rb +20 -10
- data/spec/choosy/verifier_spec.rb +137 -47
- data/spec/integration/command-A_spec.rb +6 -6
- data/spec/integration/command-B_spec.rb +45 -0
- data/spec/integration/supercommand-A_spec.rb +33 -27
- data/spec/integration/supercommand-B_spec.rb +32 -0
- data/spec/spec_helpers.rb +8 -5
- metadata +95 -54
data/lib/choosy/base_command.rb
CHANGED
@@ -1,27 +1,42 @@
|
|
1
1
|
require 'choosy/errors'
|
2
|
+
require 'tsort'
|
2
3
|
|
3
4
|
module Choosy
|
5
|
+
class OptionBuilderHash < Hash
|
6
|
+
include TSort
|
7
|
+
alias tsort_each_node each_key
|
8
|
+
|
9
|
+
def tsort_each_child(node, &block)
|
10
|
+
deps = fetch(node).option.dependent_options
|
11
|
+
deps.each(&block) unless deps.nil?
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
4
15
|
class BaseCommand
|
5
|
-
attr_accessor :name, :summary, :
|
16
|
+
attr_accessor :name, :summary, :printer
|
6
17
|
attr_reader :builder, :listing, :option_builders
|
7
18
|
|
8
|
-
def initialize(name)
|
19
|
+
def initialize(name, &block)
|
9
20
|
@name = name
|
10
21
|
@listing = []
|
11
|
-
@option_builders =
|
22
|
+
@option_builders = OptionBuilderHash.new
|
12
23
|
|
13
24
|
@builder = create_builder
|
14
|
-
|
25
|
+
if block_given?
|
26
|
+
@builder.instance_eval(&block)
|
27
|
+
end
|
15
28
|
@builder.finalize!
|
16
29
|
end
|
17
30
|
|
18
31
|
def alter(&block)
|
19
|
-
|
32
|
+
if block_given?
|
33
|
+
@builder.instance_eval(&block)
|
34
|
+
end
|
20
35
|
@builder.finalize!
|
21
36
|
end
|
22
37
|
|
23
38
|
def options
|
24
|
-
@option_builders.
|
39
|
+
@option_builders.tsort.map {|key| @option_builders[key].option }
|
25
40
|
end
|
26
41
|
|
27
42
|
def parse!(args, propagate=false)
|
@@ -30,7 +45,7 @@ module Choosy
|
|
30
45
|
else
|
31
46
|
begin
|
32
47
|
return parse(args)
|
33
|
-
rescue Choosy::ValidationError, Choosy::ConversionError, Choosy::ParseError => e
|
48
|
+
rescue Choosy::ValidationError, Choosy::ConversionError, Choosy::ParseError, Choosy::SuperParseError => e
|
34
49
|
$stderr << "#{@name}: #{e.message}\n"
|
35
50
|
exit 1
|
36
51
|
rescue Choosy::HelpCalled => e
|
data/lib/choosy/command.rb
CHANGED
@@ -6,12 +6,16 @@ require 'choosy/verifier'
|
|
6
6
|
|
7
7
|
module Choosy
|
8
8
|
class Command < BaseCommand
|
9
|
-
attr_accessor :executor, :
|
9
|
+
attr_accessor :executor, :arguments
|
10
10
|
|
11
11
|
def execute!(args)
|
12
12
|
raise Choosy::ConfigurationError.new("No executor given for: #{name}") unless executor
|
13
13
|
result = parse!(args)
|
14
|
-
executor.
|
14
|
+
if executor.is_a?(Proc)
|
15
|
+
executor.call(result.args, result.options)
|
16
|
+
else
|
17
|
+
executor.execute!(result.args, result.options)
|
18
|
+
end
|
15
19
|
end
|
16
20
|
|
17
21
|
protected
|
@@ -20,13 +24,17 @@ module Choosy
|
|
20
24
|
end
|
21
25
|
|
22
26
|
def handle_help(hc)
|
23
|
-
printer.print!(self)
|
27
|
+
puts printer.print!(self)
|
24
28
|
end
|
25
29
|
|
26
30
|
def parse(args)
|
27
31
|
parser = Parser.new(self)
|
28
32
|
result = parser.parse!(args)
|
29
|
-
|
33
|
+
|
34
|
+
verifier = Verifier.new
|
35
|
+
verifier.verify!(result)
|
36
|
+
|
37
|
+
result
|
30
38
|
end
|
31
39
|
end
|
32
40
|
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'choosy/errors'
|
2
|
+
require 'choosy/argument'
|
3
|
+
require 'choosy/converter'
|
4
|
+
|
5
|
+
module Choosy::DSL
|
6
|
+
class ArgumentBuilder
|
7
|
+
def initialize
|
8
|
+
@count_called = false
|
9
|
+
end
|
10
|
+
|
11
|
+
def argument
|
12
|
+
@argument ||= Choosy::Argument.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def required(value=nil)
|
16
|
+
argument.required = if value.nil? || value == true
|
17
|
+
true
|
18
|
+
else
|
19
|
+
false
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def metaname(meta)
|
24
|
+
return if meta.nil?
|
25
|
+
argument.metaname = meta
|
26
|
+
return if @count_called
|
27
|
+
|
28
|
+
if meta =~ /\+$/
|
29
|
+
argument.multiple!
|
30
|
+
else
|
31
|
+
argument.single!
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def count(restriction)
|
36
|
+
@count_called = true
|
37
|
+
if restriction.is_a?(Hash)
|
38
|
+
lower_bound = restriction[:at_least] || restriction[:exactly] || 1
|
39
|
+
upper_bound = restriction[:at_most] || restriction[:exactly] || 1000
|
40
|
+
|
41
|
+
check_count(lower_bound)
|
42
|
+
check_count(upper_bound)
|
43
|
+
if lower_bound > upper_bound
|
44
|
+
raise Choosy::ConfigurationError.new("The upper bound (#{upper_bound}) is less than the lower bound (#{lower_bound}).")
|
45
|
+
end
|
46
|
+
|
47
|
+
argument.arity = (lower_bound .. upper_bound)
|
48
|
+
elsif restriction.is_a?(Range)
|
49
|
+
argument.arity = restriction
|
50
|
+
elsif restriction == :zero || restriction == :none
|
51
|
+
argument.boolean!
|
52
|
+
elsif restriction == :once
|
53
|
+
argument.single!
|
54
|
+
else
|
55
|
+
check_count(restriction)
|
56
|
+
argument.arity = (restriction .. restriction)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def cast(ty)
|
61
|
+
argument.cast_to = Choosy::Converter.for(ty)
|
62
|
+
if argument.cast_to.nil?
|
63
|
+
raise Choosy::ConfigurationError.new("Unknown conversion cast: #{ty}")
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def validate(&block)
|
68
|
+
argument.validation_step = block
|
69
|
+
end
|
70
|
+
|
71
|
+
def die(msg)
|
72
|
+
raise Choosy::ValidationError.new("argument error: #{msg}")
|
73
|
+
end
|
74
|
+
|
75
|
+
def finalize!
|
76
|
+
if argument.arity.nil?
|
77
|
+
argument.boolean!
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
protected
|
82
|
+
def check_count(count)
|
83
|
+
if !count.is_a?(Integer)
|
84
|
+
raise Choosy::ConfigurationError.new("Expected a number to count, got '#{count}'")
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'choosy/errors'
|
2
2
|
require 'choosy/dsl/option_builder'
|
3
3
|
require 'choosy/printing/erb_printer'
|
4
|
+
require 'choosy/printing/formatting_element'
|
4
5
|
|
5
6
|
module Choosy::DSL
|
6
7
|
class BaseCommandBuilder
|
@@ -10,46 +11,37 @@ module Choosy::DSL
|
|
10
11
|
@command = command
|
11
12
|
end
|
12
13
|
|
14
|
+
# Generic setup
|
15
|
+
|
13
16
|
def summary(msg)
|
14
17
|
@command.summary = msg
|
15
18
|
end
|
16
19
|
|
17
|
-
def printer(kind, options=
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
raise Choosy::ConfigurationError.new("the template file doesn't exist: #{options[:template]}")
|
29
|
-
end
|
30
|
-
p.template = options[:template]
|
31
|
-
elsif kind.respond_to?(:print!)
|
32
|
-
p = kind
|
33
|
-
else
|
34
|
-
raise Choosy::ConfigurationError.new("Unknown printing method for help: #{kind}")
|
35
|
-
end
|
20
|
+
def printer(kind, options={})
|
21
|
+
@command.printer = if kind == :standard
|
22
|
+
Choosy::Printing::HelpPrinter.new(options)
|
23
|
+
elsif kind == :erb
|
24
|
+
Choosy::Printing::ERBPrinter.new(options)
|
25
|
+
elsif kind.respond_to?(:print!)
|
26
|
+
kind
|
27
|
+
else
|
28
|
+
raise Choosy::ConfigurationError.new("Unknown printing method for help: #{kind}")
|
29
|
+
end
|
30
|
+
end
|
36
31
|
|
37
|
-
|
38
|
-
p.color.disable! if !options[:color]
|
39
|
-
end
|
32
|
+
# Formatting
|
40
33
|
|
41
|
-
|
34
|
+
def header(msg, *styles)
|
35
|
+
@command.listing << Choosy::Printing::FormattingElement.new(:header, msg, styles)
|
42
36
|
end
|
43
37
|
|
44
|
-
def
|
45
|
-
@command.
|
38
|
+
def para(msg=nil, *styles)
|
39
|
+
@command.listing << Choosy::Printing::FormattingElement.new(:para, msg, styles)
|
46
40
|
end
|
47
41
|
|
48
|
-
|
49
|
-
@command.listing << (msg.nil? ? "" : msg)
|
50
|
-
end
|
42
|
+
# Options
|
51
43
|
|
52
|
-
def option(arg)
|
44
|
+
def option(arg, &block)
|
53
45
|
raise Choosy::ConfigurationError.new("The option name was nil") if arg.nil?
|
54
46
|
|
55
47
|
builder = nil
|
@@ -61,7 +53,7 @@ module Choosy::DSL
|
|
61
53
|
|
62
54
|
to_process = arg[name]
|
63
55
|
if to_process.is_a?(Array)
|
64
|
-
builder.
|
56
|
+
builder.depends_on to_process
|
65
57
|
elsif to_process.is_a?(Hash)
|
66
58
|
builder.from_hash to_process
|
67
59
|
else
|
@@ -72,33 +64,33 @@ module Choosy::DSL
|
|
72
64
|
raise Choosy::ConfigurationError.new("No configuration block was given") if !block_given?
|
73
65
|
end
|
74
66
|
|
75
|
-
|
67
|
+
if block_given?
|
68
|
+
builder.instance_eval(&block)
|
69
|
+
end
|
76
70
|
finalize_option_builder builder
|
77
71
|
end
|
78
72
|
|
79
|
-
# Option types
|
80
73
|
def self.create_conversions
|
81
74
|
Choosy::Converter::CONVERSIONS.keys.each do |method|
|
82
75
|
next if method == :boolean || method == :bool
|
83
76
|
|
84
|
-
|
85
|
-
|
86
|
-
|
77
|
+
self.class_eval <<-EOF
|
78
|
+
def #{method}(sym, desc, config=nil, &block)
|
79
|
+
simple_option(sym, desc, true, :one, :#{method}, nil, config, &block)
|
80
|
+
end
|
87
81
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
end
|
82
|
+
def #{method}s(sym, desc, config=nil, &block)
|
83
|
+
simple_option(sym, desc, true, :many, :#{method}, nil, config, &block)
|
84
|
+
end
|
92
85
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
end
|
86
|
+
def #{method}_(sym, desc, config=nil, &block)
|
87
|
+
simple_option(sym, desc, false, :one, :#{method}, nil, config, &block)
|
88
|
+
end
|
97
89
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
90
|
+
def #{method}s_(sym, desc, config=nil, &block)
|
91
|
+
simple_option(sym, desc, false, :many, :#{method}, nil, config, &block)
|
92
|
+
end
|
93
|
+
EOF
|
102
94
|
end
|
103
95
|
end
|
104
96
|
|
@@ -110,15 +102,24 @@ module Choosy::DSL
|
|
110
102
|
alias :multiple_ :strings_
|
111
103
|
|
112
104
|
def boolean(sym, desc, config=nil, &block)
|
113
|
-
simple_option(sym, desc, true, :zero, :boolean, config, &block)
|
105
|
+
simple_option(sym, desc, true, :zero, :boolean, nil, config, &block)
|
114
106
|
end
|
115
107
|
def boolean_(sym, desc, config=nil, &block)
|
116
|
-
simple_option(sym, desc, false, :zero, :boolean, config, &block)
|
108
|
+
simple_option(sym, desc, false, :zero, :boolean, nil, config, &block)
|
117
109
|
end
|
118
110
|
alias :bool :boolean
|
119
111
|
alias :bool_ :boolean_
|
120
112
|
|
121
|
-
def
|
113
|
+
def enum(sym, allowed, desc, config=nil, &block)
|
114
|
+
simple_option(sym, desc, true, :one, :symbol, allowed, config, &block)
|
115
|
+
end
|
116
|
+
|
117
|
+
def enum_(sym, allowed, desc, config=nil, &block)
|
118
|
+
simple_option(sym, desc, false, :one, :symbol, allowed, config, &block)
|
119
|
+
end
|
120
|
+
# Additional helpers
|
121
|
+
|
122
|
+
def version(msg, &block)
|
122
123
|
v = OptionBuilder.new(OptionBuilder::VERSION)
|
123
124
|
v.long '--version'
|
124
125
|
v.desc "The version number"
|
@@ -127,7 +128,9 @@ module Choosy::DSL
|
|
127
128
|
raise Choosy::VersionCalled.new(msg)
|
128
129
|
end
|
129
130
|
|
130
|
-
|
131
|
+
if block_given?
|
132
|
+
v.instance_eval(&block)
|
133
|
+
end
|
131
134
|
finalize_option_builder v
|
132
135
|
end
|
133
136
|
|
@@ -147,21 +150,33 @@ module Choosy::DSL
|
|
147
150
|
end
|
148
151
|
|
149
152
|
private
|
150
|
-
def simple_option(sym, desc, allow_short,
|
153
|
+
def simple_option(sym, desc, allow_short, meta, cast, allowed, config, &block)
|
151
154
|
name = sym.to_s
|
152
155
|
builder = OptionBuilder.new sym
|
153
156
|
builder.desc desc
|
154
|
-
|
157
|
+
short = case name[0]
|
158
|
+
when Fixnum
|
159
|
+
name[0].chr
|
160
|
+
else
|
161
|
+
name[0]
|
162
|
+
end
|
163
|
+
|
164
|
+
builder.short "-#{short}" if allow_short
|
155
165
|
builder.long "--#{name.downcase.gsub(/_/, '-')}"
|
156
|
-
builder.
|
166
|
+
builder.metaname format_meta(name, meta)
|
157
167
|
builder.cast cast
|
168
|
+
if allowed
|
169
|
+
builder.only(*allowed)
|
170
|
+
end
|
158
171
|
builder.from_hash config if config
|
159
172
|
|
160
|
-
|
173
|
+
if block_given?
|
174
|
+
builder.instance_eval(&block)
|
175
|
+
end
|
161
176
|
finalize_option_builder builder
|
162
177
|
end
|
163
178
|
|
164
|
-
def
|
179
|
+
def format_meta(name, count)
|
165
180
|
case count
|
166
181
|
when :zero then nil
|
167
182
|
when :one then name.upcase
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'choosy/errors'
|
2
2
|
require 'choosy/dsl/base_command_builder'
|
3
3
|
require 'choosy/dsl/option_builder'
|
4
|
+
require 'choosy/dsl/argument_builder'
|
4
5
|
require 'choosy/printing/help_printer'
|
5
6
|
|
6
7
|
module Choosy::DSL
|
@@ -35,9 +36,20 @@ module Choosy::DSL
|
|
35
36
|
end
|
36
37
|
|
37
38
|
def arguments(&block)
|
38
|
-
|
39
|
+
builder = ArgumentBuilder.new
|
40
|
+
# Set multiple by default
|
41
|
+
builder.argument.multiple!
|
39
42
|
|
40
|
-
|
43
|
+
if block_given?
|
44
|
+
builder.instance_eval(&block)
|
45
|
+
end
|
46
|
+
|
47
|
+
builder.finalize!
|
48
|
+
if builder.argument.metaname.nil?
|
49
|
+
builder.metaname 'ARGS+'
|
50
|
+
end
|
51
|
+
|
52
|
+
command.arguments = builder.argument
|
41
53
|
end
|
42
54
|
end
|
43
55
|
end
|
@@ -1,37 +1,38 @@
|
|
1
1
|
require 'choosy/option'
|
2
2
|
require 'choosy/errors'
|
3
3
|
require 'choosy/converter'
|
4
|
+
require 'choosy/dsl/argument_builder'
|
4
5
|
|
5
6
|
module Choosy::DSL
|
6
|
-
class OptionBuilder
|
7
|
+
class OptionBuilder < ArgumentBuilder
|
7
8
|
HELP = :__help__
|
8
9
|
VERSION = :__version__
|
9
10
|
|
10
|
-
ZERO_ARITY = (0 .. 0)
|
11
|
-
ONE_ARITY = (1 .. 1)
|
12
|
-
MANY_ARITY = (1 .. 1000)
|
13
|
-
|
14
|
-
attr_reader :option
|
15
|
-
|
16
11
|
def initialize(name)
|
17
|
-
|
18
|
-
@
|
12
|
+
super()
|
13
|
+
@name = name
|
14
|
+
end
|
15
|
+
|
16
|
+
def option
|
17
|
+
@argument ||= Choosy::Option.new(@name)
|
19
18
|
end
|
20
19
|
|
21
|
-
|
20
|
+
alias :argument :option
|
21
|
+
|
22
|
+
def short(flag, meta=nil)
|
22
23
|
option.short_flag = flag
|
23
|
-
|
24
|
+
metaname(meta)
|
24
25
|
end
|
25
26
|
|
26
|
-
def long(flag,
|
27
|
+
def long(flag, meta=nil)
|
27
28
|
option.long_flag = flag
|
28
|
-
|
29
|
+
metaname(meta)
|
29
30
|
end
|
30
31
|
|
31
|
-
def flags(shorter, longer=nil,
|
32
|
+
def flags(shorter, longer=nil, meta=nil)
|
32
33
|
short(shorter)
|
33
34
|
long(longer) if longer
|
34
|
-
|
35
|
+
metaname(meta) if meta
|
35
36
|
end
|
36
37
|
|
37
38
|
def desc(description)
|
@@ -42,77 +43,32 @@ module Choosy::DSL
|
|
42
43
|
option.default_value = value
|
43
44
|
end
|
44
45
|
|
45
|
-
def
|
46
|
-
|
47
|
-
|
48
|
-
else
|
49
|
-
false
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def param(param)
|
54
|
-
return if param.nil?
|
55
|
-
option.flag_parameter = param
|
56
|
-
return if @count_called
|
57
|
-
|
58
|
-
if param =~ /\+$/
|
59
|
-
option.arity = MANY_ARITY
|
46
|
+
def depends_on(*args)
|
47
|
+
if args.count == 1 && args[0].is_a?(Array)
|
48
|
+
option.dependent_options = args[0]
|
60
49
|
else
|
61
|
-
option.
|
50
|
+
option.dependent_options = args
|
62
51
|
end
|
63
52
|
end
|
64
53
|
|
65
|
-
def
|
66
|
-
|
67
|
-
if restriction.is_a?(Hash)
|
68
|
-
lower_bound = restriction[:at_least] || restriction[:exactly] || 1
|
69
|
-
upper_bound = restriction[:at_most] || restriction[:exactly] || 1000
|
70
|
-
|
71
|
-
check_count(lower_bound)
|
72
|
-
check_count(upper_bound)
|
73
|
-
if lower_bound > upper_bound
|
74
|
-
raise Choosy::ConfigurationError.new("The upper bound (#{upper_bound}) is less than the lower bound (#{lower_bound}).")
|
75
|
-
end
|
76
|
-
|
77
|
-
option.arity = (lower_bound .. upper_bound)
|
78
|
-
elsif restriction == :zero || restriction == :none
|
79
|
-
option.arity = ZERO_ARITY
|
80
|
-
elsif restriction == :once
|
81
|
-
option.arity = ONE_ARITY
|
82
|
-
else
|
83
|
-
check_count(restriction)
|
84
|
-
option.arity = (restriction .. restriction)
|
85
|
-
end
|
54
|
+
def only(*args)
|
55
|
+
option.allowable_values = args
|
86
56
|
end
|
87
57
|
|
88
|
-
def
|
89
|
-
|
90
|
-
|
91
|
-
raise Choosy::ConfigurationError.new("Unknown conversion cast: #{ty}")
|
92
|
-
end
|
58
|
+
def negate(prefix=nil)
|
59
|
+
prefix ||= 'no'
|
60
|
+
option.negation = prefix
|
93
61
|
end
|
94
|
-
|
95
|
-
def
|
96
|
-
option.validation_step = block
|
97
|
-
end
|
98
|
-
|
99
|
-
def fail(msg)
|
62
|
+
|
63
|
+
def die(msg)
|
100
64
|
flag_fmt = if option.short_flag && option.long_flag
|
101
65
|
"#{option.short_flag}/#{option.long_flag}"
|
102
66
|
end
|
103
67
|
flag_fmt ||= option.short_flag || option.long_flag
|
104
|
-
|
105
|
-
" #{option.
|
68
|
+
flag_meta = if option.metaname
|
69
|
+
" #{option.metaname}"
|
106
70
|
end
|
107
|
-
raise Choosy::ValidationError.new("#{flag_fmt}#{
|
108
|
-
end
|
109
|
-
|
110
|
-
def dependencies(*args)
|
111
|
-
if args.count == 1 && args[0].is_a?(Array)
|
112
|
-
option.dependent_options = args[0]
|
113
|
-
else
|
114
|
-
option.dependent_options = args
|
115
|
-
end
|
71
|
+
raise Choosy::ValidationError.new("#{flag_fmt}#{flag_meta}: #{msg}")
|
116
72
|
end
|
117
73
|
|
118
74
|
def from_hash(hash)
|
@@ -132,23 +88,27 @@ module Choosy::DSL
|
|
132
88
|
end
|
133
89
|
|
134
90
|
def finalize!
|
135
|
-
|
136
|
-
option.arity = ZERO_ARITY
|
137
|
-
end
|
91
|
+
super
|
138
92
|
|
139
93
|
if option.cast_to.nil?
|
140
|
-
if option.
|
94
|
+
if option.boolean?
|
141
95
|
option.cast_to = :boolean
|
142
96
|
else
|
143
97
|
option.cast_to = :string
|
144
98
|
end
|
145
99
|
end
|
146
|
-
end
|
147
100
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
101
|
+
if option.boolean?
|
102
|
+
if option.restricted?
|
103
|
+
raise Choosy::ConfigurationError.new("Options cannot be both boolean and restricted to certain arguments: #{option.name}")
|
104
|
+
elsif option.negated? && option.long_flag.nil?
|
105
|
+
raise Choosy::ConfigurationError.new("The long flag is required for negation: #{option.name}")
|
106
|
+
end
|
107
|
+
option.default_value ||= false
|
108
|
+
else
|
109
|
+
if option.negated?
|
110
|
+
raise Choosy::ConfigurationError.new("Unable to negate a non-boolean option: #{option.name}")
|
111
|
+
end
|
152
112
|
end
|
153
113
|
end
|
154
114
|
end
|