mothership 0.1.5 → 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/lib/mothership.rb +2 -2
- data/lib/mothership/base.rb +23 -2
- data/lib/mothership/callbacks.rb +2 -2
- data/lib/mothership/command.rb +15 -11
- data/lib/mothership/errors.rb +3 -3
- data/lib/mothership/help.rb +1 -1
- data/lib/mothership/inputs.rb +27 -1
- data/lib/mothership/parser.rb +30 -15
- data/lib/mothership/pretty.rb +1 -1
- data/lib/mothership/version.rb +1 -1
- metadata +5 -5
data/lib/mothership.rb
CHANGED
@@ -14,8 +14,8 @@ class Mothership
|
|
14
14
|
|
15
15
|
class << self
|
16
16
|
# define a global option
|
17
|
-
def option(name, options = {}, &
|
18
|
-
@@global.add_input(name, options, &
|
17
|
+
def option(name, options = {}, &interact)
|
18
|
+
@@global.add_input(name, options, &interact)
|
19
19
|
end
|
20
20
|
|
21
21
|
# parse argv, by taking the first arg as the command, and the rest as
|
data/lib/mothership/base.rb
CHANGED
@@ -20,10 +20,10 @@ class Mothership
|
|
20
20
|
end
|
21
21
|
|
22
22
|
# define an input for the current command or the global command
|
23
|
-
def input(name, options = {}, &
|
23
|
+
def input(name, options = {}, &interact)
|
24
24
|
raise "no current command" unless @command
|
25
25
|
|
26
|
-
@command.add_input(name, options, &
|
26
|
+
@command.add_input(name, options, &interact)
|
27
27
|
end
|
28
28
|
|
29
29
|
# register a command
|
@@ -65,4 +65,25 @@ class Mothership
|
|
65
65
|
unknown_command(name)
|
66
66
|
end
|
67
67
|
end
|
68
|
+
|
69
|
+
# explicitly perform the interaction of an input
|
70
|
+
#
|
71
|
+
# if no input specified, assume current input and reuse the arguments
|
72
|
+
#
|
73
|
+
# example:
|
74
|
+
# input(:foo, :default => proc { |foos|
|
75
|
+
# foos.find { |f| f.name == "XYZ" } ||
|
76
|
+
# interact
|
77
|
+
# }) { |foos|
|
78
|
+
# ask("Foo?", :choices => foos, :display => proc(&:name))
|
79
|
+
# }
|
80
|
+
def interact(input = nil, *args)
|
81
|
+
unless input
|
82
|
+
input, args = @input.current_input
|
83
|
+
end
|
84
|
+
|
85
|
+
raise "no active input" unless input
|
86
|
+
|
87
|
+
@input.interact(input, *args)
|
88
|
+
end
|
68
89
|
end
|
data/lib/mothership/callbacks.rb
CHANGED
@@ -42,8 +42,8 @@ class Mothership
|
|
42
42
|
end
|
43
43
|
|
44
44
|
# add an input/flag to a command
|
45
|
-
def add_input(cmd, name, options = {}, &
|
46
|
-
@@commands[cmd].add_input(name, options, &
|
45
|
+
def add_input(cmd, name, options = {}, &interact)
|
46
|
+
@@commands[cmd].add_input(name, options, &interact)
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
data/lib/mothership/command.rb
CHANGED
@@ -33,23 +33,27 @@ class Mothership
|
|
33
33
|
"\#<Command '#{@name}'>"
|
34
34
|
end
|
35
35
|
|
36
|
-
def
|
37
|
-
|
36
|
+
def display_name
|
37
|
+
@name.to_s.gsub("_", "-")
|
38
|
+
end
|
38
39
|
|
40
|
+
def usage
|
41
|
+
args = [display_name]
|
39
42
|
@arguments.each do |a|
|
40
43
|
name = (a[:value] || a[:name]).to_s.upcase
|
44
|
+
input = @inputs[a[:name]]
|
41
45
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
46
|
+
if a[:type] == :splat
|
47
|
+
args << "#{name}..."
|
48
|
+
elsif a[:type] == :optional || input.key?(:default) || \
|
49
|
+
input.key?(:interact)
|
50
|
+
args << "[#{name}]"
|
47
51
|
else
|
48
|
-
|
52
|
+
args << name
|
49
53
|
end
|
50
54
|
end
|
51
55
|
|
52
|
-
|
56
|
+
args.join(" ")
|
53
57
|
end
|
54
58
|
|
55
59
|
def invoke(inputs = {}, given = {}, global = {})
|
@@ -82,8 +86,8 @@ class Mothership
|
|
82
86
|
res
|
83
87
|
end
|
84
88
|
|
85
|
-
def add_input(name, options = {}, &
|
86
|
-
options[:
|
89
|
+
def add_input(name, options = {}, &interact)
|
90
|
+
options[:interact] = interact if interact
|
87
91
|
options[:description] = options.delete(:desc) if options.key?(:desc)
|
88
92
|
|
89
93
|
@flags["--#{name.to_s.gsub("_", "-")}"] = name
|
data/lib/mothership/errors.rb
CHANGED
@@ -9,7 +9,7 @@ class Mothership
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def to_s
|
12
|
-
"#{@command}: missing input '#{@argument}'"
|
12
|
+
"#{@command.display_name}: missing input '#{@argument}'"
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
@@ -20,7 +20,7 @@ class Mothership
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def to_s
|
23
|
-
"#{@command}: too many arguments; extra: #{@extra.join(" ")}"
|
23
|
+
"#{@command.display_name}: too many arguments; extra: #{@extra.join(" ")}"
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
@@ -32,7 +32,7 @@ class Mothership
|
|
32
32
|
end
|
33
33
|
|
34
34
|
def to_s
|
35
|
-
"#{@command}: expected #{@type} value for #{@input}"
|
35
|
+
"#{@command.display_name}: expected #{@type} value for #{@input}"
|
36
36
|
end
|
37
37
|
end
|
38
38
|
end
|
data/lib/mothership/help.rb
CHANGED
data/lib/mothership/inputs.rb
CHANGED
@@ -2,6 +2,9 @@ class Mothership
|
|
2
2
|
class Inputs
|
3
3
|
attr_reader :inputs, :given, :global
|
4
4
|
|
5
|
+
# the input being processed; set during #get
|
6
|
+
attr_reader :current_input
|
7
|
+
|
5
8
|
def initialize(
|
6
9
|
command, context = nil,
|
7
10
|
inputs = {}, given = {}, global = {})
|
@@ -47,6 +50,19 @@ class Mothership
|
|
47
50
|
get(name, @context, *args)
|
48
51
|
end
|
49
52
|
|
53
|
+
def interact(name, *args)
|
54
|
+
meta =
|
55
|
+
if @command
|
56
|
+
@command.inputs[name]
|
57
|
+
else
|
58
|
+
Mothership.global_option(name)
|
59
|
+
end
|
60
|
+
|
61
|
+
if interact = meta[:interact]
|
62
|
+
@context.instance_exec(*args, &interact)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
50
66
|
# search:
|
51
67
|
# 1. cache
|
52
68
|
# 2. cache, singular
|
@@ -57,6 +73,8 @@ class Mothership
|
|
57
73
|
def get(name, context, *args)
|
58
74
|
return @inputs[name] if @inputs.key?(name)
|
59
75
|
|
76
|
+
@current_input = [name, args]
|
77
|
+
|
60
78
|
if @command && meta = @command.inputs[name]
|
61
79
|
# special case so #invoke can be called with singular-named inputs
|
62
80
|
singular = meta[:singular]
|
@@ -69,7 +87,13 @@ class Mothership
|
|
69
87
|
|
70
88
|
return val if not found
|
71
89
|
|
72
|
-
|
90
|
+
if val == :interact && interact = meta[:interact]
|
91
|
+
@inputs[name] = context.instance_exec(*args, &interact)
|
92
|
+
else
|
93
|
+
@inputs[name] = convert_given(meta, context, val, *args)
|
94
|
+
end
|
95
|
+
ensure
|
96
|
+
@current_input = nil
|
73
97
|
end
|
74
98
|
|
75
99
|
def forget(name)
|
@@ -120,6 +144,8 @@ class Mothership
|
|
120
144
|
else
|
121
145
|
default
|
122
146
|
end
|
147
|
+
elsif interact = meta[:interact]
|
148
|
+
context.instance_exec(*args, &interact)
|
123
149
|
elsif meta[:type] == :boolean
|
124
150
|
false
|
125
151
|
elsif meta[:argument] == :splat
|
data/lib/mothership/parser.rb
CHANGED
@@ -41,6 +41,12 @@ class Mothership
|
|
41
41
|
|
42
42
|
input = @command.inputs[name]
|
43
43
|
|
44
|
+
if input[:interact] && argv.first == "_"
|
45
|
+
@given[name] = :interact
|
46
|
+
argv.shift
|
47
|
+
next
|
48
|
+
end
|
49
|
+
|
44
50
|
case input[:type]
|
45
51
|
when :bool, :boolean
|
46
52
|
if argv.first == "false" || argv.first == "true"
|
@@ -52,25 +58,28 @@ class Mothership
|
|
52
58
|
if !argv.empty? && argv.first =~ /^[0-9]+(\.[0-9]*)?$/
|
53
59
|
@given[name] = argv.shift.to_f
|
54
60
|
else
|
55
|
-
raise TypeMismatch.new(@command
|
61
|
+
raise TypeMismatch.new(@command, name, "floating")
|
56
62
|
end
|
57
63
|
when :integer, :number, :numeric
|
58
64
|
if !argv.empty? && argv.first =~ /^[0-9]+$/
|
59
65
|
@given[name] = argv.shift.to_i
|
60
66
|
else
|
61
|
-
raise TypeMismatch.new(@command
|
67
|
+
raise TypeMismatch.new(@command, name, "numeric")
|
62
68
|
end
|
63
69
|
else
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
70
|
+
arg =
|
71
|
+
if argv.empty? || argv.first.start_with?("-")
|
72
|
+
""
|
73
|
+
else
|
74
|
+
argv.shift
|
75
|
+
end
|
76
|
+
|
77
|
+
@given[name] =
|
78
|
+
if input[:argument] == :splat
|
79
|
+
arg.split(",")
|
80
|
+
else
|
81
|
+
arg
|
82
|
+
end
|
74
83
|
end
|
75
84
|
end
|
76
85
|
|
@@ -102,6 +111,8 @@ class Mothership
|
|
102
111
|
name = arg[:name]
|
103
112
|
next if @given.key? name
|
104
113
|
|
114
|
+
input = @command.inputs[name]
|
115
|
+
|
105
116
|
case arg[:type]
|
106
117
|
when :splat
|
107
118
|
@given[name] = []
|
@@ -119,13 +130,13 @@ class Mothership
|
|
119
130
|
else
|
120
131
|
if val = args.shift
|
121
132
|
@given[name] = val
|
122
|
-
elsif
|
123
|
-
raise MissingArgument.new(@command
|
133
|
+
elsif !input[:default] && !input[:interact]
|
134
|
+
raise MissingArgument.new(@command, name)
|
124
135
|
end
|
125
136
|
end
|
126
137
|
end
|
127
138
|
|
128
|
-
raise ExtraArguments.new(@command
|
139
|
+
raise ExtraArguments.new(@command, args) unless args.empty?
|
129
140
|
end
|
130
141
|
|
131
142
|
private
|
@@ -150,6 +161,10 @@ class Mothership
|
|
150
161
|
|
151
162
|
"--#$1"
|
152
163
|
|
164
|
+
when /^--ask-(.+)/
|
165
|
+
argv.unshift "_"
|
166
|
+
"--#$1"
|
167
|
+
|
153
168
|
# --foo=bar form
|
154
169
|
when /^--([^=]+)=(.+)/
|
155
170
|
argv.unshift $2
|
data/lib/mothership/pretty.rb
CHANGED
data/lib/mothership/version.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mothership
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 23
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 2
|
9
|
+
- 0
|
10
|
+
version: 0.2.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Alex Suraci
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-09
|
18
|
+
date: 2012-10-09 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: rake
|