cloulu 0.0.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (152) hide show
  1. data/bin/{cloulu → cl} +0 -0
  2. data/lib/cc_api_stub/applications.rb +53 -0
  3. data/lib/cc_api_stub/domains.rb +16 -0
  4. data/lib/cc_api_stub/frameworks.rb +22 -0
  5. data/lib/cc_api_stub/helper.rb +131 -0
  6. data/lib/cc_api_stub/login.rb +21 -0
  7. data/lib/cc_api_stub/organization_users.rb +21 -0
  8. data/lib/cc_api_stub/organizations.rb +70 -0
  9. data/lib/cc_api_stub/routes.rb +26 -0
  10. data/lib/cc_api_stub/runtimes.rb +22 -0
  11. data/lib/cc_api_stub/service_bindings.rb +22 -0
  12. data/lib/cc_api_stub/service_instances.rb +22 -0
  13. data/lib/cc_api_stub/services.rb +25 -0
  14. data/lib/cc_api_stub/spaces.rb +49 -0
  15. data/lib/cc_api_stub/users.rb +84 -0
  16. data/lib/cc_api_stub.rb +17 -0
  17. data/lib/cfoundry/auth_token.rb +63 -0
  18. data/lib/cfoundry/baseclient.rb +201 -0
  19. data/lib/cfoundry/chatty_hash.rb +46 -0
  20. data/lib/cfoundry/client.rb +46 -0
  21. data/lib/cfoundry/concerns/login_helpers.rb +13 -0
  22. data/lib/cfoundry/errors.rb +160 -0
  23. data/lib/cfoundry/rest_client.rb +299 -0
  24. data/lib/cfoundry/test_support.rb +3 -0
  25. data/lib/cfoundry/trace_helpers.rb +40 -0
  26. data/lib/cfoundry/uaaclient.rb +112 -0
  27. data/lib/cfoundry/upload_helpers.rb +187 -0
  28. data/lib/cfoundry/v1/app.rb +363 -0
  29. data/lib/cfoundry/v1/base.rb +72 -0
  30. data/lib/cfoundry/v1/client.rb +193 -0
  31. data/lib/cfoundry/v1/framework.rb +21 -0
  32. data/lib/cfoundry/v1/model.rb +178 -0
  33. data/lib/cfoundry/v1/model_magic.rb +129 -0
  34. data/lib/cfoundry/v1/runtime.rb +24 -0
  35. data/lib/cfoundry/v1/service.rb +39 -0
  36. data/lib/cfoundry/v1/service_instance.rb +32 -0
  37. data/lib/cfoundry/v1/service_plan.rb +19 -0
  38. data/lib/cfoundry/v1/user.rb +22 -0
  39. data/lib/cfoundry/v2/app.rb +392 -0
  40. data/lib/cfoundry/v2/base.rb +83 -0
  41. data/lib/cfoundry/v2/client.rb +138 -0
  42. data/lib/cfoundry/v2/domain.rb +11 -0
  43. data/lib/cfoundry/v2/framework.rb +14 -0
  44. data/lib/cfoundry/v2/model.rb +148 -0
  45. data/lib/cfoundry/v2/model_magic.rb +449 -0
  46. data/lib/cfoundry/v2/organization.rb +16 -0
  47. data/lib/cfoundry/v2/route.rb +15 -0
  48. data/lib/cfoundry/v2/runtime.rb +12 -0
  49. data/lib/cfoundry/v2/service.rb +19 -0
  50. data/lib/cfoundry/v2/service_auth_token.rb +9 -0
  51. data/lib/cfoundry/v2/service_binding.rb +10 -0
  52. data/lib/cfoundry/v2/service_instance.rb +14 -0
  53. data/lib/cfoundry/v2/service_plan.rb +12 -0
  54. data/lib/cfoundry/v2/space.rb +18 -0
  55. data/lib/cfoundry/v2/user.rb +64 -0
  56. data/lib/cfoundry/validator.rb +39 -0
  57. data/lib/cfoundry/version.rb +4 -0
  58. data/lib/cfoundry/zip.rb +56 -0
  59. data/lib/cfoundry.rb +2 -0
  60. data/lib/manifests-vmc-plugin/errors.rb +21 -0
  61. data/lib/manifests-vmc-plugin/loader/builder.rb +34 -0
  62. data/lib/manifests-vmc-plugin/loader/normalizer.rb +149 -0
  63. data/lib/manifests-vmc-plugin/loader/resolver.rb +79 -0
  64. data/lib/manifests-vmc-plugin/loader.rb +31 -0
  65. data/lib/manifests-vmc-plugin/plugin.rb +145 -0
  66. data/lib/manifests-vmc-plugin/version.rb +3 -0
  67. data/lib/manifests-vmc-plugin.rb +313 -0
  68. data/lib/mothership/base.rb +99 -0
  69. data/lib/mothership/callbacks.rb +85 -0
  70. data/lib/mothership/command.rb +146 -0
  71. data/lib/mothership/errors.rb +38 -0
  72. data/lib/mothership/help/commands.rb +53 -0
  73. data/lib/mothership/help/printer.rb +170 -0
  74. data/lib/mothership/help.rb +64 -0
  75. data/lib/mothership/inputs.rb +189 -0
  76. data/lib/mothership/parser.rb +182 -0
  77. data/lib/mothership/version.rb +3 -0
  78. data/lib/mothership.rb +64 -0
  79. data/lib/tunnel-vmc-plugin/plugin.rb +178 -0
  80. data/lib/tunnel-vmc-plugin/tunnel.rb +308 -0
  81. data/lib/tunnel-vmc-plugin/version.rb +3 -0
  82. data/lib/uaa/http.rb +168 -0
  83. data/lib/uaa/misc.rb +121 -0
  84. data/lib/uaa/scim.rb +292 -0
  85. data/lib/uaa/token_coder.rb +196 -0
  86. data/lib/uaa/token_issuer.rb +255 -0
  87. data/lib/uaa/util.rb +235 -0
  88. data/lib/uaa/version.rb +19 -0
  89. data/lib/uaa.rb +18 -0
  90. data/lib/vmc/cli/app/app.rb +45 -0
  91. data/lib/vmc/cli/app/apps.rb +99 -0
  92. data/lib/vmc/cli/app/base.rb +90 -0
  93. data/lib/vmc/cli/app/crashes.rb +42 -0
  94. data/lib/vmc/cli/app/delete.rb +95 -0
  95. data/lib/vmc/cli/app/deprecated.rb +11 -0
  96. data/lib/vmc/cli/app/env.rb +78 -0
  97. data/lib/vmc/cli/app/files.rb +137 -0
  98. data/lib/vmc/cli/app/health.rb +26 -0
  99. data/lib/vmc/cli/app/instances.rb +53 -0
  100. data/lib/vmc/cli/app/logs.rb +76 -0
  101. data/lib/vmc/cli/app/push/create.rb +165 -0
  102. data/lib/vmc/cli/app/push/interactions.rb +94 -0
  103. data/lib/vmc/cli/app/push/sync.rb +64 -0
  104. data/lib/vmc/cli/app/push.rb +109 -0
  105. data/lib/vmc/cli/app/rename.rb +35 -0
  106. data/lib/vmc/cli/app/restart.rb +20 -0
  107. data/lib/vmc/cli/app/scale.rb +71 -0
  108. data/lib/vmc/cli/app/start.rb +143 -0
  109. data/lib/vmc/cli/app/stats.rb +67 -0
  110. data/lib/vmc/cli/app/stop.rb +27 -0
  111. data/lib/vmc/cli/help.rb +11 -0
  112. data/lib/vmc/cli/interactive.rb +105 -0
  113. data/lib/vmc/cli/route/base.rb +12 -0
  114. data/lib/vmc/cli/route/map.rb +82 -0
  115. data/lib/vmc/cli/route/routes.rb +25 -0
  116. data/lib/vmc/cli/route/unmap.rb +94 -0
  117. data/lib/vmc/cli/service/base.rb +8 -0
  118. data/lib/vmc/cli/service/bind.rb +44 -0
  119. data/lib/vmc/cli/service/create.rb +126 -0
  120. data/lib/vmc/cli/service/delete.rb +86 -0
  121. data/lib/vmc/cli/service/rename.rb +35 -0
  122. data/lib/vmc/cli/service/service.rb +42 -0
  123. data/lib/vmc/cli/service/services.rb +114 -0
  124. data/lib/vmc/cli/service/unbind.rb +38 -0
  125. data/lib/vmc/cli/start/base.rb +94 -0
  126. data/lib/vmc/cli/start/colors.rb +13 -0
  127. data/lib/vmc/cli/start/info.rb +126 -0
  128. data/lib/vmc/cli/start/login.rb +97 -0
  129. data/lib/vmc/cli/start/logout.rb +17 -0
  130. data/lib/vmc/cli/start/target.rb +60 -0
  131. data/lib/vmc/cli/start/target_interactions.rb +37 -0
  132. data/lib/vmc/cli/start/targets.rb +16 -0
  133. data/lib/vmc/cli/user/base.rb +29 -0
  134. data/lib/vmc/cli/user/create.rb +39 -0
  135. data/lib/vmc/cli/user/delete.rb +27 -0
  136. data/lib/vmc/cli/user/passwd.rb +50 -0
  137. data/lib/vmc/cli/user/register.rb +42 -0
  138. data/lib/vmc/cli/user/users.rb +32 -0
  139. data/lib/vmc/cli/v2_check_cli.rb +16 -0
  140. data/lib/vmc/cli.rb +474 -0
  141. data/lib/vmc/constants.rb +13 -0
  142. data/lib/vmc/detect.rb +129 -0
  143. data/lib/vmc/errors.rb +19 -0
  144. data/lib/vmc/plugin.rb +56 -0
  145. data/lib/vmc/spacing.rb +89 -0
  146. data/lib/vmc/spec_helper.rb +1 -0
  147. data/lib/vmc/test_support.rb +6 -0
  148. data/lib/vmc/version.rb +3 -0
  149. data/lib/vmc.rb +8 -0
  150. data/vendor/errors/v1.yml +189 -0
  151. data/vendor/errors/v2.yml +360 -0
  152. metadata +303 -190
@@ -0,0 +1,53 @@
1
+ require "mothership/help/printer"
2
+
3
+ class Mothership
4
+ class << self
5
+ # add command to help group
6
+ def group(*names)
7
+ options =
8
+ if names.last.is_a? Hash
9
+ names.pop
10
+ else
11
+ {}
12
+ end
13
+
14
+ Mothership::Help.add_to_group(@command, names, options)
15
+ end
16
+ end
17
+
18
+ def default_action
19
+ invoke :help
20
+ end
21
+
22
+ def unknown_command(name)
23
+ $stderr.print "Unknown command '#{name.to_s.gsub("_", "-")}'. "
24
+ $stderr.puts "See 'help' for available commands."
25
+ exit_status 1
26
+ end
27
+
28
+ desc "Help!"
29
+ input :command, :argument => :optional
30
+ input :all, :type => :boolean
31
+ def help
32
+ # custom header
33
+ puts "\x1B[1m\x1B[33m===========================================================\x1B[00m"
34
+ puts "\x1B[1m\x1B[33m* Welcome Cloulu Platform\x1B[00m"
35
+ puts "\x1B[1m\x1B[33m*\x1B[00m"
36
+ puts "\x1B[1m\x1B[33m* @author clouluteam <cloulu@sk.com>\x1B[00m"
37
+ puts "\x1B[1m\x1B[33m* @homepage https://cloulu.com, http://blog.cloulu.com\x1B[00m"
38
+ puts "\x1B[1m\x1B[33m============================================================\x1B[00m"
39
+ puts
40
+
41
+ if name = input[:command]
42
+ if cmd = @@commands[name.gsub("-", "_").to_sym]
43
+ Mothership::Help.command_help(cmd)
44
+ else
45
+ unknown_command(name)
46
+ end
47
+ elsif Help.has_groups?
48
+ Mothership::Help.print_help_groups(@@global, input[:all])
49
+ else
50
+ Mothership::Help.basic_help(@@commands, @@global)
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,170 @@
1
+ module Mothership::Help
2
+ class << self
3
+ def print_help_groups(global = nil, all = false)
4
+ @@groups.each do |commands|
5
+ print_help_group(commands, all)
6
+ end
7
+
8
+ command_options(global)
9
+ end
10
+
11
+ def print_help_group(group, all = false, indent = 0)
12
+ return if nothing_printable?(group, all)
13
+
14
+ members = group[:members]
15
+
16
+ unless all
17
+ members = members.reject do |_, opts|
18
+ opts[:hidden]
19
+ end
20
+ end
21
+
22
+ commands = members.collect(&:first)
23
+
24
+ i = " " * indent
25
+
26
+ # set prefix
27
+ prefix = "*"
28
+ prefix = ">>" if indent == 1
29
+
30
+ # set color
31
+ color = "31"
32
+ color = "32" if indent == 1
33
+
34
+ print i
35
+ puts "\x1B[1m\x1B[#{color}m" + prefix + " " + group[:description] + "\x1B[00m"
36
+
37
+ commands = unique_commands(commands)
38
+
39
+ width = 0
40
+ commands.each do |cmd|
41
+ len = cmd.usage.size
42
+ if len > width
43
+ width = len
44
+ end
45
+ end
46
+
47
+ commands.each do |cmd|
48
+ puts "#{i} #{cmd.usage.ljust(width)}\t#{cmd.description}"
49
+ end
50
+
51
+ puts "" unless commands.empty?
52
+
53
+ group[:children].each do |group|
54
+ print_help_group(group, all, indent + 1)
55
+ end
56
+ end
57
+
58
+ def basic_help(commands, global)
59
+ puts "Commands:"
60
+
61
+ width = 0
62
+ commands.each do |_, c|
63
+ len = c.usage.size
64
+ width = len if len > width
65
+ end
66
+
67
+ commands.each do |_, c|
68
+ puts " #{c.usage.ljust(width)}\t#{c.description}"
69
+ end
70
+
71
+ unless global.flags.empty?
72
+ puts ""
73
+ command_options(global)
74
+ end
75
+ end
76
+
77
+ def command_help(cmd)
78
+ puts cmd.description
79
+ puts ""
80
+ command_usage(cmd)
81
+ end
82
+
83
+ def command_usage(cmd, io = $stdout)
84
+ io.puts "Usage: #{cmd.usage}"
85
+
86
+ unless cmd.flags.empty?
87
+ io.puts ""
88
+ command_options(cmd, io)
89
+ end
90
+ end
91
+
92
+ def command_options(cmd, io = $stdout)
93
+ io.puts "Options:"
94
+
95
+ rev_flags = Hash.new { |h, k| h[k] = [] }
96
+
97
+ cmd.flags.each do |f, n|
98
+ rev_flags[n] << f
99
+ end
100
+
101
+ usages = []
102
+
103
+ max_width = 0
104
+ rev_flags.collect do |name, fs|
105
+ info = cmd.inputs[name]
106
+ next if info[:hidden]
107
+
108
+ flag = name.to_s.gsub("_", "-")
109
+
110
+ # move full form to the front
111
+ fs.unshift fs.delete("--#{flag}")
112
+
113
+ if short = fs.find { |x| x =~ /^-.$/ }
114
+ fs.delete short
115
+ end
116
+
117
+ if info[:type] == :boolean && info[:default]
118
+ fs[0] = "--[no-]#{flag}"
119
+ end
120
+
121
+ if info.key?(:default) && info.key?(:interact)
122
+ fs.unshift "--ask-#{flag}"
123
+ end
124
+
125
+ usage = "#{short ? short + "," : " "} #{fs.join ", "}"
126
+
127
+ unless info[:type] == :boolean
128
+ usage << " #{(info[:value] || name).to_s.upcase}"
129
+ end
130
+
131
+ max_width = usage.size if usage.size > max_width
132
+
133
+ usages << [usage, info[:description]]
134
+ end
135
+
136
+ usages.sort! { |a, b| a.first <=> b.first }
137
+
138
+ usages.each do |u, d|
139
+ if d
140
+ io.puts " #{u.ljust(max_width)} #{d}"
141
+ else
142
+ io.puts " #{u}"
143
+ end
144
+ end
145
+ end
146
+
147
+ private
148
+
149
+ def nothing_printable?(group, all = false)
150
+ group[:members].reject { |_, opts| !all && opts[:hidden] }.empty? &&
151
+ group[:children].all? { |g| nothing_printable?(g) }
152
+ end
153
+
154
+ def unique_commands(commands)
155
+ uniq_commands = []
156
+ cmd_index = {}
157
+
158
+ commands.each do |cmd|
159
+ if idx = cmd_index[cmd.name]
160
+ uniq_commands[idx] = cmd
161
+ else
162
+ cmd_index[cmd.name] = uniq_commands.size
163
+ uniq_commands << cmd
164
+ end
165
+ end
166
+
167
+ uniq_commands
168
+ end
169
+ end
170
+ end
@@ -0,0 +1,64 @@
1
+ require "mothership/base"
2
+ require "mothership/help/commands"
3
+
4
+ module Mothership::Help
5
+ @@groups = []
6
+ @@tree = {}
7
+
8
+ class << self
9
+ def has_groups?
10
+ !@@groups.empty?
11
+ end
12
+
13
+ # define help groups
14
+ def groups(*tree)
15
+ tree.each do |*args|
16
+ add_group(@@groups, @@tree, *args.first)
17
+ end
18
+ end
19
+
20
+ def group(*names)
21
+ if where = find_group(names, @@tree)
22
+ where[:members].collect(&:first)
23
+ else
24
+ []
25
+ end
26
+ end
27
+
28
+ def add_to_group(command, names, options)
29
+ where = find_group(names, @@tree)
30
+ raise "unknown help group: #{names.join("/")}" unless where
31
+
32
+ where[:members] << [command, options]
33
+ end
34
+
35
+ private
36
+
37
+ def find_group(names, where)
38
+ names.each_with_index do |n, index|
39
+ where = where[:children] unless index == 0
40
+ break unless where
41
+
42
+ where = where[n]
43
+ break unless where
44
+ end
45
+
46
+ where
47
+ end
48
+
49
+ def add_group(groups, tree, name, desc, *subs)
50
+ members = []
51
+
52
+ meta = { :members => members, :children => [] }
53
+ groups << meta
54
+
55
+ tree[name] = { :members => members, :children => {} }
56
+
57
+ meta[:description] = desc
58
+
59
+ subs.each do |*args|
60
+ add_group(meta[:children], tree[name][:children], *args.first)
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,189 @@
1
+ class Mothership
2
+ class Inputs
3
+ attr_reader :inputs, :given, :global
4
+
5
+ # the input being processed; set during #get
6
+ attr_reader :current_input
7
+
8
+ def initialize(
9
+ command, context = nil,
10
+ inputs = {}, given = {}, global = {})
11
+ @command = command
12
+ @context = context
13
+ @inputs = inputs
14
+ @given = given
15
+ @global = global
16
+ end
17
+
18
+ def has?(name)
19
+ @inputs.key?(name) || @given.key?(name)
20
+ end
21
+
22
+ def direct(name)
23
+ if @inputs.key?(name)
24
+ @inputs[name]
25
+ elsif (given = @given[name]) != :interact
26
+ given
27
+ end
28
+ end
29
+
30
+ def merge(inputs)
31
+ self.class.new(@command, @context, @inputs.merge(inputs), @given, @global)
32
+ end
33
+
34
+ def merge_given(given)
35
+ self.class.new(@command, @context, @inputs.dup, @given.merge(given), @global)
36
+ end
37
+
38
+ def rebase(inputs)
39
+ self.class.new(@command, @context, inputs.merge(@inputs), @given, @global)
40
+ end
41
+
42
+ def rebase_given(given)
43
+ self.class.new(@command, @context, @inputs.dup, given.merge(@given), @global)
44
+ end
45
+
46
+ def without(*names)
47
+ given = @given.dup
48
+ inputs = @inputs.dup
49
+ names.each do |n|
50
+ given.delete(n)
51
+ inputs.delete(n)
52
+ end
53
+
54
+ self.class.new(@command, @context, inputs, given, @global)
55
+ end
56
+
57
+ def [](name, *args)
58
+ return @inputs[name] if @inputs.key?(name)
59
+
60
+ if @command && meta = @command.inputs[name]
61
+ # special case so #invoke can be called with singular-named inputs
62
+ singular = meta[:singular]
63
+
64
+ if @inputs.key?(singular)
65
+ return @inputs[name] = [@inputs[singular]]
66
+ end
67
+ end
68
+
69
+ found, val = get(name, @context, *args)
70
+
71
+ @inputs[name] = val unless meta && meta[:forget]
72
+
73
+ val
74
+ end
75
+
76
+ def interact(name, context, *args)
77
+ meta =
78
+ if @command
79
+ @command.inputs[name]
80
+ else
81
+ Mothership.global_option(name)
82
+ end
83
+
84
+ interact = meta[:interact] || :"ask_#{name}"
85
+
86
+ case interact
87
+ when Symbol, String
88
+ context.send(interact, *args)
89
+ else
90
+ context.instance_exec(*args, &interact)
91
+ end
92
+ end
93
+
94
+ # search:
95
+ # 1. cache
96
+ # 2. cache, singular
97
+ # 3. given
98
+ # 4. given, singular
99
+ # 5. global
100
+ # 6. global, singular
101
+ def get(name, context, *args)
102
+ before_input = @current_input
103
+ @current_input = [name, args]
104
+
105
+ if @command && meta = @command.inputs[name]
106
+ found, val = find_in(@given, name, meta, context, *args)
107
+ elsif @global.is_a?(self.class)
108
+ return @global.get(name, context, *args)
109
+ elsif @global.key?(name)
110
+ return [true, @global[name]]
111
+ end
112
+
113
+ return [false, val] if not found
114
+
115
+ if val == :interact
116
+ [true, interact(name, context, *args)]
117
+ else
118
+ [true, convert_given(meta, context, val, *args)]
119
+ end
120
+ ensure
121
+ @current_input = before_input
122
+ end
123
+
124
+ def forget(name)
125
+ @inputs.delete(name)
126
+ @given.delete(name)
127
+ end
128
+
129
+ def interactive?(name)
130
+ @given[name] == :interact
131
+ end
132
+
133
+ private
134
+
135
+ def find_in(where, name, meta, context, *args)
136
+ singular = meta[:singular]
137
+
138
+ if where.key?(name)
139
+ [true, where[name]]
140
+ elsif where.key?(singular)
141
+ [true, [where[singular]]]
142
+ else
143
+ # no value given; set as default
144
+ [false, default_for(name, meta, context, *args)]
145
+ end
146
+ end
147
+
148
+ def convert_given(meta, context, given, *args)
149
+ if convert = meta[:from_given]
150
+ if given.is_a?(Array)
151
+ given.collect do |i|
152
+ context.instance_exec(i, *args, &convert)
153
+ end
154
+ else
155
+ context.instance_exec(given, *args, &convert)
156
+ end
157
+ else
158
+ case meta[:type]
159
+ when :integer, :number, :numeric
160
+ given.to_i
161
+ when :float, :floating
162
+ given.to_f
163
+ when :bool, :boolean
164
+ given == "true"
165
+ else
166
+ given
167
+ end
168
+ end
169
+ end
170
+
171
+ def default_for(name, meta, context, *args)
172
+ if meta.key?(:default)
173
+ default = meta[:default]
174
+
175
+ if default.respond_to? :to_proc
176
+ context.instance_exec(*args, &default)
177
+ else
178
+ default
179
+ end
180
+ elsif meta[:interact] || context.respond_to?(:"ask_#{name}", true)
181
+ interact(name, context, *args)
182
+ elsif meta[:type] == :boolean
183
+ false
184
+ elsif meta[:argument] == :splat
185
+ []
186
+ end
187
+ end
188
+ end
189
+ end
@@ -0,0 +1,182 @@
1
+ class Mothership
2
+ class Parser
3
+ attr_reader :given
4
+
5
+ def initialize(command, given = {})
6
+ @command = command
7
+ @given = given
8
+ end
9
+
10
+ def parse_argv(argv)
11
+ args = parse_flags(argv.dup)
12
+
13
+ parse_arguments(args)
14
+
15
+ @given
16
+ end
17
+
18
+ def parse_flags(argv, find_in = nil)
19
+ local = nil
20
+ args = []
21
+
22
+ until argv.empty?
23
+ flag = normalize_flag(argv.shift, argv)
24
+
25
+ name = local && local.flags[flag] || @command.flags[flag]
26
+ unless name
27
+ # assume first argument is subcommand
28
+ if args.empty? && find_in && !local
29
+ local = find_in[flag.gsub("-", "_").to_sym]
30
+ end
31
+
32
+ args << flag
33
+ next
34
+ end
35
+
36
+ # skip flags defined by the local cmd
37
+ if local && local.inputs[name]
38
+ args << flag
39
+ next
40
+ end
41
+
42
+ input = @command.inputs[name]
43
+
44
+ if argv.first == "--ask"
45
+ @given[name] = :interact
46
+ argv.shift
47
+ next
48
+ end
49
+
50
+ case input[:type]
51
+ when :bool, :boolean
52
+ if argv.first == "false" || argv.first == "true"
53
+ @given[name] = argv.shift
54
+ else
55
+ @given[name] = "true"
56
+ end
57
+ when :float, :floating
58
+ if !argv.empty? && argv.first =~ /^[0-9]+(\.[0-9]*)?$/
59
+ @given[name] = argv.shift
60
+ else
61
+ raise TypeMismatch.new(@command, name, "floating")
62
+ end
63
+ when :integer, :number, :numeric
64
+ if !argv.empty? && argv.first =~ /^[0-9]+$/
65
+ @given[name] = argv.shift
66
+ else
67
+ raise TypeMismatch.new(@command, name, "numeric")
68
+ end
69
+ else
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
83
+ end
84
+ end
85
+
86
+ args
87
+ end
88
+
89
+ # [FOO] [BAR] FIZZ BUZZ:
90
+ # 1 2 => :fizz => 1, :buzz => 2
91
+ # 1 2 3 => :foo => 1, :fizz => 2, :buzz => 3
92
+ # 1 2 3 4 => :foo => 1, :bar => 2, :fizz => 3, :buzz => 4
93
+ def parse_arguments(args)
94
+ total = @command.arguments.size
95
+ required = 0
96
+ optional = 0
97
+ @command.arguments.each do |arg|
98
+ case arg[:type]
99
+ when :optional
100
+ optional += 1
101
+ when :splat
102
+ break
103
+ else
104
+ required += 1
105
+ end
106
+ end
107
+
108
+ parse_optionals = args.size - required
109
+
110
+ @command.arguments.each do |arg|
111
+ name = arg[:name]
112
+ next if @given.key? name
113
+
114
+ input = @command.inputs[name]
115
+
116
+ case arg[:type]
117
+ when :splat
118
+ @given[name] = []
119
+
120
+ until args.empty?
121
+ @given[name] << args.shift
122
+ end
123
+
124
+ when :optional
125
+ if parse_optionals > 0 && val = args.shift
126
+ @given[name] = val
127
+ parse_optionals -= 1
128
+ end
129
+
130
+ else
131
+ if val = args.shift
132
+ @given[name] = val
133
+ elsif !input[:default] && !input[:interact]
134
+ raise MissingArgument.new(@command, name)
135
+ end
136
+ end
137
+ end
138
+
139
+ raise ExtraArguments.new(@command, args) unless args.empty?
140
+ end
141
+
142
+ private
143
+
144
+ # --no-foo => --foo false
145
+ # --no-foo true => --foo false
146
+ # --no-foo false => --foo true
147
+ #
148
+ # --foo=bar => --foo bar
149
+ def normalize_flag(flag, argv)
150
+ case flag
151
+ # boolean negation
152
+ when /^--no-(.+)/
153
+ case argv.first
154
+ when "true"
155
+ argv[0] = "false"
156
+ when "false"
157
+ argv[0] = "true"
158
+ else
159
+ argv.unshift "false"
160
+ end
161
+
162
+ "--#$1"
163
+
164
+ when /^--ask-(.+)/
165
+ argv.unshift "--ask"
166
+ "--#$1"
167
+
168
+ # --foo=bar form
169
+ when /^--([^=]+)=(.+)/
170
+ argv.unshift $2
171
+ "--#$1"
172
+
173
+ # normal flag name
174
+ when /^--([^ ]+)$/
175
+ "--#$1"
176
+
177
+ else
178
+ flag
179
+ end
180
+ end
181
+ end
182
+ end
@@ -0,0 +1,3 @@
1
+ class Mothership
2
+ VERSION = "0.5.1"
3
+ end