mothership 0.1.5 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -14,8 +14,8 @@ class Mothership
14
14
 
15
15
  class << self
16
16
  # define a global option
17
- def option(name, options = {}, &default)
18
- @@global.add_input(name, options, &default)
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
@@ -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 = {}, &default)
23
+ def input(name, options = {}, &interact)
24
24
  raise "no current command" unless @command
25
25
 
26
- @command.add_input(name, options, &default)
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
@@ -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 = {}, &default)
46
- @@commands[cmd].add_input(name, options, &default)
45
+ def add_input(cmd, name, options = {}, &interact)
46
+ @@commands[cmd].add_input(name, options, &interact)
47
47
  end
48
48
  end
49
49
 
@@ -33,23 +33,27 @@ class Mothership
33
33
  "\#<Command '#{@name}'>"
34
34
  end
35
35
 
36
- def usage
37
- str = @name.to_s.gsub("_", "-")
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
- case a[:type]
43
- when :splat
44
- str << " #{name}..."
45
- when :optional
46
- str << " [#{name}]"
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
- str << " #{name}"
52
+ args << name
49
53
  end
50
54
  end
51
55
 
52
- str
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 = {}, &default)
86
- options[:default] = default if default
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
@@ -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
@@ -155,7 +155,7 @@ module Mothership::Help
155
155
  short = fs.find { |x| x =~ /^-.$/ }
156
156
  fs.delete short if short
157
157
 
158
- if info[:type] == :boolean && info[:default]
158
+ if info[:type] == :boolean && info[:default] == true
159
159
  full = "--[no-]#{flag}"
160
160
  end
161
161
 
@@ -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
- @inputs[name] = convert_given(meta, context, val, *args)
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
@@ -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.name, name, "floating")
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.name, name, "numeric")
67
+ raise TypeMismatch.new(@command, name, "numeric")
62
68
  end
63
69
  else
64
- if argv.empty? || !argv.first.start_with?("-")
65
- arg = argv.shift || ""
66
-
67
- @given[name] =
68
- if input[:argument] == :splat
69
- arg.split(",")
70
- else
71
- arg
72
- end
73
- end
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 !@command.inputs[name][:default]
123
- raise MissingArgument.new(@command.name, name)
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.name, args) unless args.empty?
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
@@ -62,7 +62,7 @@ module Mothership::Pretty
62
62
 
63
63
  bright = false
64
64
  color = user_colors[type]
65
- if color =~ /bright-(.+)/
65
+ if color.to_s =~ /bright-(.+)/
66
66
  bright = true
67
67
  color = $1.to_sym
68
68
  end
@@ -1,3 +1,3 @@
1
1
  class Mothership
2
- VERSION = "0.1.5"
2
+ VERSION = "0.2.0"
3
3
  end
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: 17
4
+ hash: 23
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 1
9
- - 5
10
- version: 0.1.5
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-12 00:00:00 Z
18
+ date: 2012-10-09 00:00:00 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: rake