rudy 0.3.2 → 0.4.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/CHANGES.txt +53 -3
- data/README.rdoc +9 -5
- data/bin/rudy +115 -292
- data/bin/rudy-ec2 +107 -0
- data/lib/console.rb +322 -278
- data/lib/rudy.rb +78 -55
- data/lib/rudy/aws/ec2.rb +63 -5
- data/lib/rudy/command/addresses.rb +18 -13
- data/lib/rudy/command/backups.rb +175 -0
- data/lib/rudy/command/base.rb +664 -146
- data/lib/rudy/command/config.rb +77 -0
- data/lib/rudy/command/deploy.rb +12 -0
- data/lib/rudy/command/disks.rb +165 -195
- data/lib/rudy/command/environment.rb +42 -64
- data/lib/rudy/command/groups.rb +21 -19
- data/lib/rudy/command/images.rb +34 -19
- data/lib/rudy/command/instances.rb +46 -92
- data/lib/rudy/command/machines.rb +161 -0
- data/lib/rudy/command/metadata.rb +14 -30
- data/lib/rudy/command/release.rb +174 -0
- data/lib/rudy/command/volumes.rb +26 -10
- data/lib/rudy/config.rb +93 -0
- data/lib/rudy/metadata/backup.rb +1 -1
- data/lib/rudy/metadata/disk.rb +15 -50
- data/lib/rudy/scm/svn.rb +32 -21
- data/lib/rudy/utils.rb +2 -3
- data/lib/storable.rb +4 -0
- data/lib/tryouts.rb +40 -0
- data/rudy.gemspec +25 -9
- data/support/mailtest +40 -0
- data/support/rudy-ec2-startup +41 -15
- data/tryouts/console_tryout.rb +91 -0
- metadata +86 -11
- data/lib/drydock.rb +0 -524
- data/lib/rudy/command/stage.rb +0 -45
- data/lib/rudy/metadata/config.rb +0 -8
- data/lib/rudy/metadata/environment.rb +0 -0
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rudy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Delano Mandelbaum
|
@@ -9,11 +9,80 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-03-12 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
|
-
dependencies:
|
15
|
-
|
16
|
-
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: drydock
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: caesars
|
27
|
+
type: :runtime
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0"
|
34
|
+
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: net-ssh
|
37
|
+
type: :runtime
|
38
|
+
version_requirement:
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: "0"
|
44
|
+
version:
|
45
|
+
- !ruby/object:Gem::Dependency
|
46
|
+
name: net-scp
|
47
|
+
type: :runtime
|
48
|
+
version_requirement:
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: "0"
|
54
|
+
version:
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: net-ssh-gateway
|
57
|
+
type: :runtime
|
58
|
+
version_requirement:
|
59
|
+
version_requirements: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - ">="
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: "0"
|
64
|
+
version:
|
65
|
+
- !ruby/object:Gem::Dependency
|
66
|
+
name: net-ssh-multi
|
67
|
+
type: :runtime
|
68
|
+
version_requirement:
|
69
|
+
version_requirements: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: "0"
|
74
|
+
version:
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: highline
|
77
|
+
type: :runtime
|
78
|
+
version_requirement:
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: "0"
|
84
|
+
version:
|
85
|
+
description: Your friend in staging and deploying with EC2.
|
17
86
|
email: delano@solutious.com
|
18
87
|
executables:
|
19
88
|
- rudy
|
@@ -28,36 +97,42 @@ files:
|
|
28
97
|
- README.rdoc
|
29
98
|
- Rakefile
|
30
99
|
- bin/rudy
|
100
|
+
- bin/rudy-ec2
|
31
101
|
- lib/aws_sdb.rb
|
32
102
|
- lib/aws_sdb/error.rb
|
33
103
|
- lib/aws_sdb/service.rb
|
34
104
|
- lib/console.rb
|
35
|
-
- lib/drydock.rb
|
36
105
|
- lib/rudy.rb
|
37
106
|
- lib/rudy/aws.rb
|
38
107
|
- lib/rudy/aws/ec2.rb
|
39
108
|
- lib/rudy/aws/s3.rb
|
40
109
|
- lib/rudy/aws/simpledb.rb
|
41
110
|
- lib/rudy/command/addresses.rb
|
111
|
+
- lib/rudy/command/backups.rb
|
42
112
|
- lib/rudy/command/base.rb
|
113
|
+
- lib/rudy/command/config.rb
|
114
|
+
- lib/rudy/command/deploy.rb
|
43
115
|
- lib/rudy/command/disks.rb
|
44
116
|
- lib/rudy/command/environment.rb
|
45
117
|
- lib/rudy/command/groups.rb
|
46
118
|
- lib/rudy/command/images.rb
|
47
119
|
- lib/rudy/command/instances.rb
|
120
|
+
- lib/rudy/command/machines.rb
|
48
121
|
- lib/rudy/command/metadata.rb
|
49
|
-
- lib/rudy/command/
|
122
|
+
- lib/rudy/command/release.rb
|
50
123
|
- lib/rudy/command/volumes.rb
|
124
|
+
- lib/rudy/config.rb
|
51
125
|
- lib/rudy/metadata.rb
|
52
126
|
- lib/rudy/metadata/backup.rb
|
53
|
-
- lib/rudy/metadata/config.rb
|
54
127
|
- lib/rudy/metadata/disk.rb
|
55
|
-
- lib/rudy/metadata/environment.rb
|
56
128
|
- lib/rudy/scm/svn.rb
|
57
129
|
- lib/rudy/utils.rb
|
58
130
|
- lib/storable.rb
|
131
|
+
- lib/tryouts.rb
|
59
132
|
- rudy.gemspec
|
133
|
+
- support/mailtest
|
60
134
|
- support/rudy-ec2-startup
|
135
|
+
- tryouts/console_tryout.rb
|
61
136
|
has_rdoc: true
|
62
137
|
homepage: http://github.com/solutious/rudy
|
63
138
|
post_install_message:
|
@@ -65,7 +140,7 @@ rdoc_options:
|
|
65
140
|
- --line-numbers
|
66
141
|
- --inline-source
|
67
142
|
- --title
|
68
|
-
- "Rudy: Your friend in staging and deploying with EC2"
|
143
|
+
- "Rudy: Your friend in staging and deploying with EC2."
|
69
144
|
- --main
|
70
145
|
- README.rdoc
|
71
146
|
require_paths:
|
@@ -88,6 +163,6 @@ rubyforge_project: rudy
|
|
88
163
|
rubygems_version: 1.2.0
|
89
164
|
signing_key:
|
90
165
|
specification_version: 2
|
91
|
-
summary:
|
166
|
+
summary: Your friend in staging and deploying with EC2.
|
92
167
|
test_files: []
|
93
168
|
|
data/lib/drydock.rb
DELETED
@@ -1,524 +0,0 @@
|
|
1
|
-
require 'optparse'
|
2
|
-
require 'ostruct'
|
3
|
-
|
4
|
-
|
5
|
-
module Drydock
|
6
|
-
# The base class for all command objects. There is an instance of this class
|
7
|
-
# for every command defined. Global and command-specific options are added
|
8
|
-
# as attributes to this class dynamically.
|
9
|
-
#
|
10
|
-
# i.e. "example -v date -f yaml"
|
11
|
-
#
|
12
|
-
# global_option :v, :verbose, "I want mooooore!"
|
13
|
-
# option :f, :format, String, "Long date format"
|
14
|
-
# command :date do |obj|
|
15
|
-
# puts obj.verbose #=> true
|
16
|
-
# puts obj.format #=> "yaml"
|
17
|
-
# end
|
18
|
-
#
|
19
|
-
# You can inherit from this class to create your own: EatFood < Drydock::Command.
|
20
|
-
# And then specific your class in the command definition:
|
21
|
-
#
|
22
|
-
# command :eat => EatFood do |obj|; ...; end
|
23
|
-
#
|
24
|
-
class Command
|
25
|
-
attr_reader :cmd, :alias
|
26
|
-
attr_accessor :verbose
|
27
|
-
|
28
|
-
# The default constructor sets the short name of the command
|
29
|
-
# and stores a reference to the block (if supplied).
|
30
|
-
# You don't need to override this method to add functionality
|
31
|
-
# to your custom Command classes. Define an +init+ method instead.
|
32
|
-
# It will be called just before the block is executed.
|
33
|
-
# +cmd+ is the short name of this command.
|
34
|
-
# +b+ is the block associated to this command.
|
35
|
-
def initialize(cmd, &b)
|
36
|
-
@cmd = (cmd.kind_of?(Symbol)) ? cmd : cmd.to_sym
|
37
|
-
@b = b
|
38
|
-
@verbose = 0
|
39
|
-
end
|
40
|
-
|
41
|
-
# Execute the block.
|
42
|
-
#
|
43
|
-
# Calls self.init before calling the block. Implement this method when
|
44
|
-
#
|
45
|
-
# +cmd_str+ is the short name used to evoke this command. It will equal @cmd
|
46
|
-
# unless an alias was used used to evoke this command.
|
47
|
-
# +argv+ an array of unnamed arguments. If ignore :options was declared this
|
48
|
-
# will contain the arguments exactly as they were defined on the command-line.
|
49
|
-
# +stdin+ contains the output of stdin do; ...; end otherwise it's a STDIN IO handle.
|
50
|
-
# +global_options+ a hash of the global options specified on the command-line
|
51
|
-
# +options+ a hash of the command-specific options specific on the command-line.
|
52
|
-
def call(cmd_str=nil, argv=[], stdin=[], global_options={}, options={})
|
53
|
-
@alias = cmd_str.nil? ? @cmd : cmd_str
|
54
|
-
global_options.merge(options).each_pair do |n,v|
|
55
|
-
self.send("#{n}=", v)
|
56
|
-
end
|
57
|
-
|
58
|
-
self.init if respond_to? :init
|
59
|
-
|
60
|
-
block_args = [self, argv, stdin] # TODO: review order
|
61
|
-
@b.call(*block_args[0..(@b.arity-1)]) # send only as many args as defined
|
62
|
-
end
|
63
|
-
|
64
|
-
# The name of the command
|
65
|
-
def to_s
|
66
|
-
@cmd.to_s
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
module Drydock
|
72
|
-
class UnknownCommand < RuntimeError
|
73
|
-
attr_reader :name
|
74
|
-
def initialize(name)
|
75
|
-
@name = name || :unknown
|
76
|
-
end
|
77
|
-
def message
|
78
|
-
"Unknown command: #{@name}"
|
79
|
-
end
|
80
|
-
end
|
81
|
-
class NoCommandsDefined < RuntimeError
|
82
|
-
def message
|
83
|
-
"No commands defined"
|
84
|
-
end
|
85
|
-
end
|
86
|
-
class InvalidArgument < RuntimeError
|
87
|
-
attr_accessor :args
|
88
|
-
def initialize(args)
|
89
|
-
@args = args || []
|
90
|
-
end
|
91
|
-
def message
|
92
|
-
"Unknown option: #{@args.join(", ")}"
|
93
|
-
end
|
94
|
-
end
|
95
|
-
class MissingArgument < InvalidArgument
|
96
|
-
def message
|
97
|
-
"Option requires a value: #{@args.join(", ")}"
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
# Drydock is a DSL for command-line apps.
|
103
|
-
# See bin/example for usage examples.
|
104
|
-
module Drydock
|
105
|
-
extend self
|
106
|
-
|
107
|
-
VERSION = 0.3
|
108
|
-
|
109
|
-
private
|
110
|
-
# Stolen from Sinatra!
|
111
|
-
#def delegate(*args)
|
112
|
-
# args.each do |m|
|
113
|
-
# eval(<<-end_eval, binding, "(__Drydock__)", __LINE__)
|
114
|
-
# def #{m}(*args, &b)
|
115
|
-
# Drydock.#{m}(*args, &b)
|
116
|
-
# end
|
117
|
-
# end_eval
|
118
|
-
# end
|
119
|
-
#end
|
120
|
-
#
|
121
|
-
#delegate :before, :after, :alias_command, :desc
|
122
|
-
#delegate :global_option, :global_usage, :usage, :commands, :command
|
123
|
-
#delegate :debug, :option, :stdin, :default, :ignore, :command_alias
|
124
|
-
|
125
|
-
@@debug = false
|
126
|
-
@@has_run = false
|
127
|
-
@@run = true
|
128
|
-
@@default_command = nil
|
129
|
-
|
130
|
-
public
|
131
|
-
# Enable or disable debug output.
|
132
|
-
#
|
133
|
-
# debug :on
|
134
|
-
# debug :off
|
135
|
-
#
|
136
|
-
# Calling without :on or :off will toggle the value.
|
137
|
-
#
|
138
|
-
def debug(toggle=false)
|
139
|
-
if toggle.is_a? Symbol
|
140
|
-
@@debug = true if toggle == :on
|
141
|
-
@@debug = false if toggle == :off
|
142
|
-
else
|
143
|
-
@@debug = (!@@debug)
|
144
|
-
end
|
145
|
-
end
|
146
|
-
# Returns true if debug output is enabled.
|
147
|
-
def debug?
|
148
|
-
@@debug
|
149
|
-
end
|
150
|
-
|
151
|
-
# Define a default command.
|
152
|
-
#
|
153
|
-
# default :task
|
154
|
-
#
|
155
|
-
def default(cmd)
|
156
|
-
@@default_command = canonize(cmd)
|
157
|
-
end
|
158
|
-
|
159
|
-
# Provide a description for a method
|
160
|
-
def desc(txt)
|
161
|
-
@@command_descriptions ||= []
|
162
|
-
@@command_descriptions << txt
|
163
|
-
end
|
164
|
-
|
165
|
-
# Define a block for processing STDIN before the command is called.
|
166
|
-
# The command block receives the return value of this block in a named argument:
|
167
|
-
#
|
168
|
-
# command :task do |obj, argv, stdin|; ...; end
|
169
|
-
#
|
170
|
-
# If a stdin block isn't defined, +stdin+ above will be the STDIN IO handle.
|
171
|
-
def stdin(&b)
|
172
|
-
@@stdin_block = b
|
173
|
-
end
|
174
|
-
|
175
|
-
# Define a block to be called before the command.
|
176
|
-
# This is useful for opening database connections, etc...
|
177
|
-
def before(&b)
|
178
|
-
@@before_block = b
|
179
|
-
end
|
180
|
-
|
181
|
-
# Define a block to be called after the command.
|
182
|
-
# This is useful for stopping, closing, etc... the stuff in the before block.
|
183
|
-
def after(&b)
|
184
|
-
@@after_block = b
|
185
|
-
end
|
186
|
-
|
187
|
-
# Define the default global usage banner. This is displayed
|
188
|
-
# with "script -h".
|
189
|
-
def global_usage(msg)
|
190
|
-
@@global_options ||= OpenStruct.new
|
191
|
-
global_opts_parser.banner = "USAGE: #{msg}"
|
192
|
-
end
|
193
|
-
|
194
|
-
# Define a command-specific usage banner. This is displayed
|
195
|
-
# with "script command -h"
|
196
|
-
def usage(msg)
|
197
|
-
get_current_option_parser.banner = "USAGE: #{msg}"
|
198
|
-
end
|
199
|
-
|
200
|
-
# Grab the options parser for the current command or create it if it doesn't exist.
|
201
|
-
def get_current_option_parser
|
202
|
-
@@command_opts_parser ||= []
|
203
|
-
@@command_index ||= 0
|
204
|
-
(@@command_opts_parser[@@command_index] ||= OptionParser.new)
|
205
|
-
end
|
206
|
-
|
207
|
-
# Tell the Drydock parser to ignore something.
|
208
|
-
# Drydock will currently only listen to you if you tell it to "ignore :options",
|
209
|
-
# otherwise it will ignore you!
|
210
|
-
#
|
211
|
-
# +what+ the thing to ignore. When it equals :options Drydock will not parse
|
212
|
-
# the command-specific arguments. It will pass the arguments directly to the
|
213
|
-
# Command object. This is useful when you want to parse the arguments in some a way
|
214
|
-
# that's too crazy, dangerous for Drydock to handle automatically.
|
215
|
-
def ignore(what=:nothing)
|
216
|
-
@@command_opts_parser[@@command_index] = :ignore if what == :options || what == :all
|
217
|
-
end
|
218
|
-
|
219
|
-
# Define a global option. See +option+ for more info.
|
220
|
-
def global_option(*args, &b)
|
221
|
-
args.unshift(global_opts_parser)
|
222
|
-
global_option_names << option_parser(args, &b)
|
223
|
-
end
|
224
|
-
|
225
|
-
# Define a command-specific option.
|
226
|
-
#
|
227
|
-
# +args+ is passed directly to OptionParser.on so it can contain anything
|
228
|
-
# that's valid to that method. Some examples:
|
229
|
-
# [:h, :help, "Displays this message"]
|
230
|
-
# [:m, :max, Integer, "Maximum threshold"]
|
231
|
-
# ['-l x,y,z', '--lang=x,y,z', Array, "Requested languages"]
|
232
|
-
# If a class is included, it will tell OptionParser to expect a value
|
233
|
-
# otherwise it assumes a boolean value.
|
234
|
-
#
|
235
|
-
# All calls to +option+ must come before the command they're associated
|
236
|
-
# to. Example:
|
237
|
-
#
|
238
|
-
# option :l, :longname, String, "Description" do; ...; end
|
239
|
-
# command :task do |obj|; ...; end
|
240
|
-
#
|
241
|
-
# When calling your script with a specific command-line option, the value
|
242
|
-
# is available via obj.longname inside the command block.
|
243
|
-
#
|
244
|
-
def option(*args, &b)
|
245
|
-
args.unshift(get_current_option_parser)
|
246
|
-
current_command_option_names << option_parser(args, &b)
|
247
|
-
end
|
248
|
-
|
249
|
-
# Define a command.
|
250
|
-
#
|
251
|
-
# command :task do
|
252
|
-
# ...
|
253
|
-
# end
|
254
|
-
#
|
255
|
-
# A custom command class can be specified using Hash syntax. The class
|
256
|
-
# must inherit from Drydock::Command (class CustomeClass < Drydock::Command)
|
257
|
-
#
|
258
|
-
# command :task => CustomCommand do
|
259
|
-
# ...
|
260
|
-
# end
|
261
|
-
#
|
262
|
-
def command(*cmds, &b)
|
263
|
-
@@command_index ||= 0
|
264
|
-
@@command_opts_parser ||= []
|
265
|
-
@@command_option_names ||= []
|
266
|
-
cmds.each do |cmd|
|
267
|
-
if cmd.is_a? Hash
|
268
|
-
c = cmd.values.first.new(cmd.keys.first, &b)
|
269
|
-
else
|
270
|
-
c = Drydock::Command.new(cmd, &b)
|
271
|
-
end
|
272
|
-
commands[c.cmd] = c
|
273
|
-
command_index_map[c.cmd] = @@command_index
|
274
|
-
@@command_index += 1
|
275
|
-
end
|
276
|
-
|
277
|
-
end
|
278
|
-
|
279
|
-
# Used to create an alias to a defined command.
|
280
|
-
# Here's an example:
|
281
|
-
#
|
282
|
-
# command :task do; ...; end
|
283
|
-
# alias_command :pointer, :task
|
284
|
-
#
|
285
|
-
# Either name can be used on the command-line:
|
286
|
-
#
|
287
|
-
# $ script task [options]
|
288
|
-
# $ script pointer [options]
|
289
|
-
#
|
290
|
-
# Inside of the command definition, you have access to the
|
291
|
-
# command name that was used via obj.alias.
|
292
|
-
def alias_command(aliaz, cmd)
|
293
|
-
return unless commands.has_key? cmd
|
294
|
-
commands[canonize(aliaz)] = commands[cmd]
|
295
|
-
end
|
296
|
-
|
297
|
-
# Identical to +alias_command+ with reversed arguments.
|
298
|
-
# For whatever reason I forget the order so Drydock supports both.
|
299
|
-
# Tip: the argument order matches the method name.
|
300
|
-
def command_alias(cmd, aliaz)
|
301
|
-
return unless commands.has_key? cmd
|
302
|
-
puts "#{canonize(aliaz)} to #{commands[cmd]}"
|
303
|
-
commands[canonize(aliaz)] = commands[cmd]
|
304
|
-
end
|
305
|
-
|
306
|
-
# An array of the currently defined Drydock::Command objects
|
307
|
-
def commands
|
308
|
-
@@commands ||= {}
|
309
|
-
@@commands
|
310
|
-
end
|
311
|
-
|
312
|
-
# An array of the currently defined commands names
|
313
|
-
def command_names
|
314
|
-
@@commands ||= {}
|
315
|
-
@@commands.keys.collect { |cmd| decanonize(cmd); }
|
316
|
-
end
|
317
|
-
|
318
|
-
# Returns true if automatic execution is enabled.
|
319
|
-
def run?
|
320
|
-
@@run
|
321
|
-
end
|
322
|
-
|
323
|
-
# Disable automatic execution (enabled by default)
|
324
|
-
#
|
325
|
-
# Drydock.run = false
|
326
|
-
def run=(v)
|
327
|
-
@@run = (v == true) ? true : false
|
328
|
-
end
|
329
|
-
|
330
|
-
# Return true if a command has been executed.
|
331
|
-
def has_run?
|
332
|
-
@@has_run
|
333
|
-
end
|
334
|
-
|
335
|
-
# Execute the given command.
|
336
|
-
# By default, Drydock automatically executes itself and provides handlers for known errors.
|
337
|
-
# You can override this functionality by calling +Drydock.run!+ yourself. Drydock
|
338
|
-
# will only call +run!+ once.
|
339
|
-
def run!(argv=[], stdin=STDIN)
|
340
|
-
return if has_run?
|
341
|
-
@@has_run = true
|
342
|
-
raise NoCommandsDefined.new if commands.empty?
|
343
|
-
@@global_options, cmd_name, @@command_options, argv = process_arguments(argv)
|
344
|
-
|
345
|
-
cmd_name ||= default_command
|
346
|
-
|
347
|
-
raise UnknownCommand.new(cmd_name) unless command?(cmd_name)
|
348
|
-
|
349
|
-
stdin = (defined? @@stdin_block) ? @@stdin_block.call(stdin, []) : stdin
|
350
|
-
@@before_block.call if defined? @@before_block
|
351
|
-
|
352
|
-
call_command(cmd_name, argv, stdin)
|
353
|
-
|
354
|
-
@@after_block.call if defined? @@after_block
|
355
|
-
|
356
|
-
rescue OptionParser::InvalidOption => ex
|
357
|
-
raise Drydock::InvalidArgument.new(ex.args)
|
358
|
-
rescue OptionParser::MissingArgument => ex
|
359
|
-
raise Drydock::MissingArgument.new(ex.args)
|
360
|
-
end
|
361
|
-
|
362
|
-
private
|
363
|
-
|
364
|
-
# Executes the block associated to +cmd+
|
365
|
-
def call_command(cmd, argv=[], stdin=nil)
|
366
|
-
return unless command?(cmd)
|
367
|
-
get_command(cmd).call(cmd, argv, stdin, @@global_options || {}, @@command_options || {})
|
368
|
-
end
|
369
|
-
|
370
|
-
# Returns the Drydock::Command object with the name +cmd+
|
371
|
-
def get_command(cmd)
|
372
|
-
return unless command?(cmd)
|
373
|
-
@@commands[canonize(cmd)]
|
374
|
-
end
|
375
|
-
|
376
|
-
# Returns true if a command with the name +cmd+ has been defined.
|
377
|
-
def command?(cmd)
|
378
|
-
name = canonize(cmd)
|
379
|
-
(@@commands || {}).has_key? name
|
380
|
-
end
|
381
|
-
|
382
|
-
# Canonizes a string (+cmd+) to the symbol for command names
|
383
|
-
# '-' is replaced with '_'
|
384
|
-
def canonize(cmd)
|
385
|
-
return unless cmd
|
386
|
-
return cmd if cmd.kind_of?(Symbol)
|
387
|
-
cmd.to_s.tr('-', '_').to_sym
|
388
|
-
end
|
389
|
-
|
390
|
-
# Returns a string version of +cmd+, decanonized.
|
391
|
-
# Lowercase, '_' is replaced with '-'
|
392
|
-
def decanonize(cmd)
|
393
|
-
return unless cmd
|
394
|
-
cmd.to_s.tr('_', '-')
|
395
|
-
end
|
396
|
-
|
397
|
-
# Processes calls to option and global_option. Symbols are converted into
|
398
|
-
# OptionParser style strings (:h and :help become '-h' and '--help').
|
399
|
-
def option_parser(args=[], &b)
|
400
|
-
return if args.empty?
|
401
|
-
opts_parser = args.shift
|
402
|
-
|
403
|
-
arg_name = ''
|
404
|
-
symbol_switches = []
|
405
|
-
args.each_with_index do |arg, index|
|
406
|
-
if arg.is_a? Symbol
|
407
|
-
arg_name = arg.to_s if arg.to_s.size > arg_name.size
|
408
|
-
args[index] = (arg.to_s.length == 1) ? "-#{arg.to_s}" : "--#{arg.to_s}"
|
409
|
-
symbol_switches << args[index]
|
410
|
-
elsif arg.kind_of?(Class)
|
411
|
-
symbol_switches.each do |arg|
|
412
|
-
arg << "=S"
|
413
|
-
end
|
414
|
-
end
|
415
|
-
end
|
416
|
-
|
417
|
-
if args.size == 1
|
418
|
-
opts_parser.on(args.shift)
|
419
|
-
else
|
420
|
-
opts_parser.on(*args) do |v|
|
421
|
-
block_args = [v, opts_parser]
|
422
|
-
result = (b.nil?) ? v : b.call(*block_args[0..(b.arity-1)])
|
423
|
-
end
|
424
|
-
end
|
425
|
-
|
426
|
-
arg_name
|
427
|
-
end
|
428
|
-
|
429
|
-
|
430
|
-
# Split the +argv+ array into global args and command args and
|
431
|
-
# find the command name.
|
432
|
-
# i.e. ./script -H push -f (-H is a global arg, push is the command, -f is a command arg)
|
433
|
-
# returns [global_options, cmd, command_options, argv]
|
434
|
-
def process_arguments(argv=[])
|
435
|
-
global_options = command_options = {}
|
436
|
-
cmd = nil
|
437
|
-
|
438
|
-
global_options = global_opts_parser.getopts(argv)
|
439
|
-
|
440
|
-
cmd_name = (argv.empty?) ? @@default_command : argv.shift
|
441
|
-
raise UnknownCommand.new(cmd_name) unless command?(cmd_name)
|
442
|
-
|
443
|
-
cmd = get_command(cmd_name)
|
444
|
-
|
445
|
-
command_parser = @@command_opts_parser[get_command_index(cmd.cmd)]
|
446
|
-
command_options = {}
|
447
|
-
|
448
|
-
# We only need to parse the options out of the arguments when
|
449
|
-
# there are args available, there is a valid parser, and
|
450
|
-
# we weren't requested to ignore the options.
|
451
|
-
if !argv.empty? && command_parser && command_parser != :ignore
|
452
|
-
command_options = command_parser.getopts(argv)
|
453
|
-
end
|
454
|
-
|
455
|
-
# Add accessors to the Drydock::Command object
|
456
|
-
# for the global and command specific options
|
457
|
-
[global_option_names, (command_option_names[get_command_index(cmd_name)] || [])].flatten.each do |n|
|
458
|
-
unless cmd.respond_to?(n)
|
459
|
-
cmd.class.send(:define_method, n) do
|
460
|
-
instance_variable_get("@#{n}")
|
461
|
-
end
|
462
|
-
end
|
463
|
-
unless cmd.respond_to?("#{n}=")
|
464
|
-
cmd.class.send(:define_method, "#{n}=") do |val|
|
465
|
-
instance_variable_set("@#{n}", val)
|
466
|
-
end
|
467
|
-
end
|
468
|
-
end
|
469
|
-
|
470
|
-
[global_options, cmd_name, command_options, argv]
|
471
|
-
end
|
472
|
-
|
473
|
-
def global_option_names
|
474
|
-
@@global_option_names ||= []
|
475
|
-
end
|
476
|
-
|
477
|
-
# Grab the current list of command-specific option names. This is a list of the
|
478
|
-
# long names.
|
479
|
-
def current_command_option_names
|
480
|
-
@@command_option_names ||= []
|
481
|
-
@@command_index ||= 0
|
482
|
-
(@@command_option_names[@@command_index] ||= [])
|
483
|
-
end
|
484
|
-
|
485
|
-
def command_index_map
|
486
|
-
@@command_index_map ||= {}
|
487
|
-
end
|
488
|
-
|
489
|
-
def get_command_index(cmd)
|
490
|
-
command_index_map[canonize(cmd)] || -1
|
491
|
-
end
|
492
|
-
|
493
|
-
def command_option_names
|
494
|
-
@@command_option_names ||= []
|
495
|
-
end
|
496
|
-
|
497
|
-
def global_opts_parser
|
498
|
-
@@global_opts_parser ||= OptionParser.new
|
499
|
-
end
|
500
|
-
|
501
|
-
def default_command
|
502
|
-
@@default_command ||= nil
|
503
|
-
end
|
504
|
-
|
505
|
-
end
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
trap ("SIGINT") do
|
510
|
-
puts "#{$/}Exiting..."
|
511
|
-
exit 1
|
512
|
-
end
|
513
|
-
|
514
|
-
|
515
|
-
at_exit {
|
516
|
-
begin
|
517
|
-
Drydock.run!(ARGV, STDIN) if Drydock.run? && !Drydock.has_run?
|
518
|
-
rescue => ex
|
519
|
-
STDERR.puts "ERROR: #{ex.message}"
|
520
|
-
STDERR.puts ex.backtrace if Drydock.debug?
|
521
|
-
end
|
522
|
-
}
|
523
|
-
|
524
|
-
|