choosy 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|