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.
@@ -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