mothership 0.0.15 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/mothership/base.rb +13 -7
- data/lib/mothership/command.rb +8 -6
- data/lib/mothership/help.rb +1 -1
- data/lib/mothership/inputs.rb +49 -23
- data/lib/mothership/parser.rb +20 -19
- data/lib/mothership/version.rb +1 -1
- data/lib/mothership.rb +7 -19
- data/spec/helpers.rb +1 -1
- metadata +4 -4
data/lib/mothership/base.rb
CHANGED
@@ -5,12 +5,12 @@ class Mothership
|
|
5
5
|
# all commands
|
6
6
|
@@commands = {}
|
7
7
|
|
8
|
-
|
9
|
-
@@inputs = nil
|
8
|
+
attr_accessor :input
|
10
9
|
|
11
10
|
# Initialize with the command being executed.
|
12
|
-
def initialize(command = nil)
|
11
|
+
def initialize(command = nil, input = nil)
|
13
12
|
@command = command
|
13
|
+
@input = input
|
14
14
|
end
|
15
15
|
|
16
16
|
class << self
|
@@ -41,8 +41,8 @@ class Mothership
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
-
def execute(cmd, argv)
|
45
|
-
cmd.invoke(Parser.new(cmd).
|
44
|
+
def execute(cmd, argv, global = {})
|
45
|
+
cmd.invoke({}, Parser.new(cmd).parse_argv(argv), global)
|
46
46
|
rescue Mothership::Error => e
|
47
47
|
$stderr.puts e
|
48
48
|
$stderr.puts ""
|
@@ -51,10 +51,16 @@ class Mothership
|
|
51
51
|
exit_status 1
|
52
52
|
end
|
53
53
|
|
54
|
+
# wrap this with your error handling/etc.
|
55
|
+
def run(name)
|
56
|
+
send(name)
|
57
|
+
end
|
58
|
+
|
54
59
|
# invoke a command with inputs
|
55
|
-
def invoke(
|
60
|
+
def invoke(
|
61
|
+
name, inputs = {}, given = {}, global = @input ? @input.global : {})
|
56
62
|
if cmd = @@commands[name]
|
57
|
-
cmd.invoke(given,
|
63
|
+
cmd.invoke(inputs, given, global)
|
58
64
|
else
|
59
65
|
unknown_command(name)
|
60
66
|
end
|
data/lib/mothership/command.rb
CHANGED
@@ -52,28 +52,30 @@ class Mothership
|
|
52
52
|
str
|
53
53
|
end
|
54
54
|
|
55
|
-
def invoke(given,
|
55
|
+
def invoke(inputs = {}, given = {}, global = {})
|
56
56
|
@before.each { |f, c| c.new.instance_exec(&f) }
|
57
57
|
|
58
58
|
name = @name
|
59
59
|
ctx = @context.new(self)
|
60
|
-
input = Inputs.new(self, ctx, given,
|
60
|
+
ctx.input = Inputs.new(self, ctx, inputs, given, global)
|
61
61
|
|
62
62
|
action = proc do |*given_inputs|
|
63
|
-
ctx.
|
63
|
+
ctx.input = given_inputs.first || ctx.input
|
64
|
+
ctx.run(name)
|
64
65
|
end
|
65
66
|
|
66
67
|
cmd = self
|
67
68
|
@around.each do |a, c|
|
68
69
|
before = action
|
69
70
|
|
70
|
-
sub = c.new(cmd)
|
71
|
+
sub = c.new(cmd, ctx.input)
|
71
72
|
action = proc do |*given_inputs|
|
72
|
-
|
73
|
+
ctx.input = given_inputs.first || ctx.input
|
74
|
+
sub.instance_exec(before, ctx.input, &a)
|
73
75
|
end
|
74
76
|
end
|
75
77
|
|
76
|
-
res = ctx.instance_exec(input, &action)
|
78
|
+
res = ctx.instance_exec(ctx.input, &action)
|
77
79
|
|
78
80
|
@after.each { |f, c| c.new.instance_exec(&f) }
|
79
81
|
|
data/lib/mothership/help.rb
CHANGED
@@ -215,7 +215,7 @@ class Mothership
|
|
215
215
|
desc "Help!"
|
216
216
|
input :command, :argument => :optional
|
217
217
|
input :all, :type => :boolean
|
218
|
-
def help
|
218
|
+
def help
|
219
219
|
if name = input[:command]
|
220
220
|
Mothership::Help.command_help(@@commands[name.gsub("-", "_").to_sym])
|
221
221
|
elsif Help.has_groups?
|
data/lib/mothership/inputs.rb
CHANGED
@@ -1,12 +1,15 @@
|
|
1
1
|
class Mothership
|
2
2
|
class Inputs
|
3
|
-
attr_reader :inputs
|
3
|
+
attr_reader :inputs, :given, :global
|
4
4
|
|
5
|
-
def initialize(
|
5
|
+
def initialize(
|
6
|
+
command, context = nil,
|
7
|
+
inputs = {}, given = {}, global = {})
|
6
8
|
@command = command
|
7
9
|
@context = context
|
8
|
-
@given = given
|
9
10
|
@inputs = inputs
|
11
|
+
@given = given
|
12
|
+
@global = global
|
10
13
|
end
|
11
14
|
|
12
15
|
def given?(name)
|
@@ -14,15 +17,19 @@ class Mothership
|
|
14
17
|
end
|
15
18
|
|
16
19
|
def given(name)
|
17
|
-
@inputs
|
20
|
+
if @inputs.key?(name)
|
21
|
+
@inputs[name]
|
22
|
+
else
|
23
|
+
@given[name]
|
24
|
+
end
|
18
25
|
end
|
19
26
|
|
20
27
|
def merge(inputs)
|
21
|
-
self.class.new(@command, @context, @
|
28
|
+
self.class.new(@command, @context, @inputs.merge(inputs), @given)
|
22
29
|
end
|
23
30
|
|
24
31
|
def merge_given(inputs)
|
25
|
-
self.class.new(@command, @context, @given.merge(inputs)
|
32
|
+
self.class.new(@command, @context, @inputs, @given.merge(inputs))
|
26
33
|
end
|
27
34
|
|
28
35
|
def without(*names)
|
@@ -40,31 +47,32 @@ class Mothership
|
|
40
47
|
get(name, @context, *args)
|
41
48
|
end
|
42
49
|
|
50
|
+
# search:
|
51
|
+
# 1. cache
|
52
|
+
# 2. cache, singular
|
53
|
+
# 3. given
|
54
|
+
# 4. given, singular
|
55
|
+
# 5. global
|
56
|
+
# 6. global, singular
|
43
57
|
def get(name, context, *args)
|
44
58
|
return @inputs[name] if @inputs.key?(name)
|
45
59
|
|
46
|
-
meta = @command.inputs[name]
|
47
|
-
|
60
|
+
if meta = @command.inputs[name]
|
61
|
+
# special case so #invoke can be called with singular-named inputs
|
62
|
+
singular = meta[:singular]
|
63
|
+
return @inputs[name] = [@inputs[singular]] if @inputs.key?(singular)
|
48
64
|
|
49
|
-
|
50
|
-
return @inputs[name] = [@inputs[singular]] if @inputs.key?(singular)
|
51
|
-
|
52
|
-
given = @given[name] if @given.key?(name)
|
53
|
-
given ||= [@given[singular]] if @given.key?(singular)
|
54
|
-
|
55
|
-
# value given; convert if needed
|
56
|
-
if given && given != []
|
57
|
-
return @inputs[name] = convert_given(meta, context, given, *args)
|
65
|
+
found, val = find_in(@given, name, meta, context, *args)
|
58
66
|
end
|
59
67
|
|
60
|
-
#
|
61
|
-
val
|
62
|
-
|
63
|
-
unless meta[:forget]
|
64
|
-
@inputs[name] = val
|
68
|
+
# if not found locally and the default is nil, search globally
|
69
|
+
if !found && val.nil? && meta = Mothership.global_option(name)
|
70
|
+
found, val = find_in(@global, name, meta, context, *args)
|
65
71
|
end
|
66
72
|
|
67
|
-
val
|
73
|
+
return val if not found
|
74
|
+
|
75
|
+
@inputs[name] = convert_given(meta, context, val, *args)
|
68
76
|
end
|
69
77
|
|
70
78
|
def forget(name)
|
@@ -74,6 +82,24 @@ class Mothership
|
|
74
82
|
|
75
83
|
private
|
76
84
|
|
85
|
+
def find_in(where, name, meta, context, *args)
|
86
|
+
singular = meta[:singular]
|
87
|
+
|
88
|
+
if where.key?(name)
|
89
|
+
[true, where[name]]
|
90
|
+
elsif where.key?(singular)
|
91
|
+
[true, [where[singular]]]
|
92
|
+
else
|
93
|
+
# no value given; set as default
|
94
|
+
val = default_for(meta, context, *args)
|
95
|
+
|
96
|
+
# cache default value
|
97
|
+
@inputs[name] = val unless meta[:forget]
|
98
|
+
|
99
|
+
[false, val]
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
77
103
|
def convert_given(meta, context, given, *args)
|
78
104
|
if convert = meta[:from_given]
|
79
105
|
if given.is_a?(Array)
|
data/lib/mothership/parser.rb
CHANGED
@@ -1,20 +1,21 @@
|
|
1
1
|
class Mothership
|
2
2
|
class Parser
|
3
|
-
|
3
|
+
attr_reader :given
|
4
|
+
|
5
|
+
def initialize(command, given = {})
|
4
6
|
@command = command
|
7
|
+
@given = given
|
5
8
|
end
|
6
9
|
|
7
|
-
def
|
8
|
-
|
9
|
-
|
10
|
-
args = parse_flags(inputs, argv.dup)
|
10
|
+
def parse_argv(argv)
|
11
|
+
args = parse_flags(argv.dup)
|
11
12
|
|
12
|
-
parse_arguments(
|
13
|
+
parse_arguments(args)
|
13
14
|
|
14
|
-
|
15
|
+
@given
|
15
16
|
end
|
16
17
|
|
17
|
-
def parse_flags(
|
18
|
+
def parse_flags(argv, find_in = nil)
|
18
19
|
local = nil
|
19
20
|
args = []
|
20
21
|
|
@@ -43,19 +44,19 @@ class Mothership
|
|
43
44
|
case input[:type]
|
44
45
|
when :bool, :boolean
|
45
46
|
if argv.first == "false" || argv.first == "true"
|
46
|
-
|
47
|
+
@given[name] = argv.shift == "true"
|
47
48
|
else
|
48
|
-
|
49
|
+
@given[name] = true
|
49
50
|
end
|
50
51
|
when :float, :floating
|
51
52
|
if !argv.empty? && argv.first =~ /^[0-9]+(\.[0-9]*)?$/
|
52
|
-
|
53
|
+
@given[name] = argv.shift.to_f
|
53
54
|
else
|
54
55
|
raise TypeMismatch.new(@command.name, name, "floating")
|
55
56
|
end
|
56
57
|
when :integer, :number, :numeric
|
57
58
|
if !argv.empty? && argv.first =~ /^[0-9]+$/
|
58
|
-
|
59
|
+
@given[name] = argv.shift.to_i
|
59
60
|
else
|
60
61
|
raise TypeMismatch.new(@command.name, name, "numeric")
|
61
62
|
end
|
@@ -63,7 +64,7 @@ class Mothership
|
|
63
64
|
if argv.empty? || !argv.first.start_with?("-")
|
64
65
|
arg = argv.shift || ""
|
65
66
|
|
66
|
-
|
67
|
+
@given[name] =
|
67
68
|
if input[:argument] == :splat
|
68
69
|
arg.split(",")
|
69
70
|
else
|
@@ -80,7 +81,7 @@ class Mothership
|
|
80
81
|
# 1 2 => :fizz => 1, :buzz => 2
|
81
82
|
# 1 2 3 => :foo => 1, :fizz => 2, :buzz => 3
|
82
83
|
# 1 2 3 4 => :foo => 1, :bar => 2, :fizz => 3, :buzz => 4
|
83
|
-
def parse_arguments(
|
84
|
+
def parse_arguments(args)
|
84
85
|
total = @command.arguments.size
|
85
86
|
required = 0
|
86
87
|
optional = 0
|
@@ -99,25 +100,25 @@ class Mothership
|
|
99
100
|
|
100
101
|
@command.arguments.each do |arg|
|
101
102
|
name = arg[:name]
|
102
|
-
next if
|
103
|
+
next if @given.key? name
|
103
104
|
|
104
105
|
case arg[:type]
|
105
106
|
when :splat
|
106
|
-
|
107
|
+
@given[name] = []
|
107
108
|
|
108
109
|
until args.empty?
|
109
|
-
|
110
|
+
@given[name] << args.shift
|
110
111
|
end
|
111
112
|
|
112
113
|
when :optional
|
113
114
|
if parse_optionals > 0 && val = args.shift
|
114
|
-
|
115
|
+
@given[name] = val
|
115
116
|
parse_optionals -= 1
|
116
117
|
end
|
117
118
|
|
118
119
|
else
|
119
120
|
if val = args.shift
|
120
|
-
|
121
|
+
@given[name] = val
|
121
122
|
elsif !@command.inputs[name][:default]
|
122
123
|
raise MissingArgument.new(@command.name, name)
|
123
124
|
end
|
data/lib/mothership/version.rb
CHANGED
data/lib/mothership.rb
CHANGED
@@ -9,9 +9,6 @@ class Mothership
|
|
9
9
|
# [Mothership::Command] global options
|
10
10
|
@@global = Command.new(self, "(global options)")
|
11
11
|
|
12
|
-
# [Mothershp::Inputs] inputs from global options
|
13
|
-
@@inputs = Inputs.new(@@global)
|
14
|
-
|
15
12
|
# [Fixnum] exit status; reassign as appropriate error code (e.g. 1)
|
16
13
|
@@exit_status = 0
|
17
14
|
|
@@ -27,11 +24,8 @@ class Mothership
|
|
27
24
|
# arguments and flags can be in any order; all flags will be parsed out
|
28
25
|
# first, and the bits left over will be treated as arguments
|
29
26
|
def start(argv)
|
30
|
-
|
31
|
-
|
32
|
-
@@inputs.inputs,
|
33
|
-
argv,
|
34
|
-
@@commands)
|
27
|
+
global_parser = Parser.new(@@global)
|
28
|
+
name, *argv = global_parser.parse_flags(argv, @@commands)
|
35
29
|
|
36
30
|
app = new
|
37
31
|
|
@@ -42,7 +36,7 @@ class Mothership
|
|
42
36
|
cmd = @@commands[cmdname]
|
43
37
|
return app.unknown_command(cmdname) unless cmd
|
44
38
|
|
45
|
-
app.execute(cmd, argv)
|
39
|
+
app.execute(cmd, argv, global_parser.given)
|
46
40
|
|
47
41
|
code = @@exit_status
|
48
42
|
|
@@ -51,20 +45,14 @@ class Mothership
|
|
51
45
|
|
52
46
|
exit code
|
53
47
|
end
|
48
|
+
|
49
|
+
def global_option(name)
|
50
|
+
@@global.inputs[name]
|
51
|
+
end
|
54
52
|
end
|
55
53
|
|
56
54
|
# set the exit status
|
57
55
|
def exit_status(num)
|
58
56
|
@@exit_status = num
|
59
57
|
end
|
60
|
-
|
61
|
-
# get value of global option
|
62
|
-
def option(name, *args)
|
63
|
-
@@inputs.get(name, self, *args)
|
64
|
-
end
|
65
|
-
|
66
|
-
# test if an option was explicitly provided
|
67
|
-
def option_given?(name)
|
68
|
-
@@inputs.given? name
|
69
|
-
end
|
70
58
|
end
|
data/spec/helpers.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: 27
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
+
- 1
|
8
9
|
- 0
|
9
|
-
|
10
|
-
version: 0.0.15
|
10
|
+
version: 0.1.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-08-
|
18
|
+
date: 2012-08-22 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: rake
|