drydock 0.5.1 → 0.5.2

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.
Files changed (5) hide show
  1. data/CHANGES.txt +26 -21
  2. data/bin/example +9 -10
  3. data/drydock.gemspec +2 -2
  4. data/lib/drydock.rb +38 -28
  5. metadata +3 -3
@@ -4,32 +4,37 @@ DRYDOCK, CHANGES
4
4
 
5
5
  * Support putting descriptions into resource file (or __END__)
6
6
  * Define aliases with "command [:name, :alias]"
7
- * Add Drydock::Console, Drydock::Window, Drydock::Cursor
8
- * Generate scripts in the form: script-action
9
- * globals can be configured with env vars.
10
- * Motivation to stick to a single environment (just stage)
11
- * Add convenience methods for system calls: sh, write, read
7
+
8
+
9
+ #### 0.5.2 (2009-04-05) #############################
10
+
11
+ * ADDED: before and after blocks now receive a primed reference to the
12
+ command object (which gives them access to the globals and options)
13
+ * CHANGE: The prep stuff in Drydock::Command#call is now split into a
14
+ separate method: prepare so call no longer takes arguments.
15
+ * FIXED: Drydock#capture_io was using yield. It now accepts a block instead.
16
+
12
17
 
13
18
  #### 0.5.1 (2009-03-15) #############################
14
19
 
15
- * FIX: Prevent calling default command in at_exit when there's a LoadError.
16
- * FIX: Exit gracefully when the application exits.
17
- * FIX: Print command names with dashes rather than underscores
20
+ * FIXED: Prevent calling default command in at_exit when there's a LoadError.
21
+ * FIXED: Exit gracefully when the application exits.
22
+ * FIXED: Print command names with dashes rather than underscores
18
23
 
19
24
 
20
25
  #### 0.5 (2009-03-11) ###############################
21
26
 
22
- * NEW: Checks that the command class is a subclass of Drydock::Command
27
+ * ADDED: Checks that the command class is a subclass of Drydock::Command
23
28
  * CHANGE: Cleaned up show-commands screen
24
29
  * FIXED: Help didn't work when using command alias
25
- * NEW: Named argv values.
30
+ * ADDED: Named argv values.
26
31
  * CHANGE: argv are now part of the Command class (not passed to command blocks)
27
32
  * CHANGE: "project" now automatically requires the lowercase name of the project
28
33
  and gracefully continues if the require failed.
29
34
  * CHANGE: Drydock will look for different validation method, based on the method
30
35
  being executed. If a validation method is found it's executed and
31
36
  must return a true valid (it can also raise its own exceptions).
32
- * NEW: command actions. These are boolean switches with a twist. Drydock looks
37
+ * ADDED: command actions. These are boolean switches with a twist. Drydock looks
33
38
  for command_action or action_command methods. Saves checking the switches
34
39
  and sending to other methods manually.
35
40
 
@@ -37,26 +42,26 @@ and sending to other methods manually.
37
42
  #### 0.4 (2009-02-28) ###############################
38
43
 
39
44
  * FIXED: "interning empty string" error when bare "option" is used
40
- * NEW: Calls valid? method (if present) before calling command block.
41
- * NEW: "capture" method. Auto capture STDOUT to obj.stdout etc...
42
- * NEW: Automatically calls init and print_header methods before the command
45
+ * ADDED: Calls valid? method (if present) before calling command block.
46
+ * ADDED: "capture" method. Auto capture STDOUT to obj.stdout etc...
47
+ * ADDED: Automatically calls init and print_header methods before the command
43
48
  and print_footer after the command (if available)
44
- * NEW: Tries to call obj.command if available when no block is supplied
45
- * NEW: "show_commands" command built-in. Displays commands with descriptions
46
- * NEW: A default usage help msg for every command: "#{$0} command-name"
47
- * NEW: "usage" work multiple times for the same command.
48
- * NEW: "desc" method for per command descriptions
49
+ * ADDED: Tries to call obj.command if available when no block is supplied
50
+ * ADDED: "show_commands" command built-in. Displays commands with descriptions
51
+ * ADDED: A default usage help msg for every command: "#{$0} command-name"
52
+ * ADDED: "usage" work multiple times for the same command.
53
+ * ADDED: "desc" method for per command descriptions
49
54
  * CHANGE: options are now stored as obj.option.name instead of obj.name
50
55
  * CHANGE: global options are now stored as obj.globals.name
51
56
  * CHANGE: removed auto importing methods
52
57
  OLD: require 'drydock'
53
- NEW: require 'drydock'
58
+ ADDED: require 'drydock'
54
59
  extend Drydock
55
60
 
56
61
 
57
62
  #### 0.3.3 (2009-02-14) ###############################
58
63
 
59
- * NEW: init method hook for subclasses of Drydock::Command
64
+ * ADDED: init method hook for subclasses of Drydock::Command
60
65
  * UPDATED: Rdocs
61
66
  * CHANGE: added method command_aliaz to mirror aliaz_command
62
67
 
@@ -26,16 +26,6 @@ default :welcome # The welcome command will be run if no command is given
26
26
  capture :stderr # Drydock will capture STDERR and keep it in the hold.
27
27
  # You can use this to suppress errors.
28
28
 
29
- project "Drydock Example" # An optional name
30
-
31
- before do
32
- # You can execute a block before the requests command is executed. Instance
33
- # variables defined here will be available to all commands.
34
- end
35
-
36
- after do
37
- # And this will be called after the command.
38
- end
39
29
 
40
30
  desc "A friendly welcome to the Drydock"
41
31
  command :welcome do
@@ -65,6 +55,15 @@ global :v, :verbose, "Verbosity level (i.e. -vvv is greater than -v)" do |v|
65
55
  @val += 1
66
56
  end
67
57
 
58
+ before do |obj|
59
+ # You can execute a block before the requests command is executed. Instance
60
+ # variables defined here will be available to all commands.
61
+ # +obj+ is a reference to the command object, just like in command blocks.
62
+ end
63
+
64
+ after do |obj|
65
+ # And this will be called after the command.
66
+ end
68
67
 
69
68
  usage "#{$0} [-s] [-vv] date"
70
69
  desc "Display the current date"
@@ -1,7 +1,7 @@
1
1
  @spec = Gem::Specification.new do |s|
2
2
  s.name = %q{drydock}
3
- s.version = "0.5.1"
4
- s.date = %q{2009-03-15}
3
+ s.version = "0.5.2"
4
+ s.date = %q{2009-04-05}
5
5
  s.specification_version = 1 if s.respond_to? :specification_version=
6
6
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
7
7
 
@@ -110,9 +110,11 @@ module Drydock
110
110
  @cmd
111
111
  end
112
112
 
113
- # Execute the block.
113
+ # Prepare this command object to be called.
114
114
  #
115
- # Calls self.init before calling the block. Implement this method when
115
+ # Calls self.init after setting attributes (if the method exists). You can
116
+ # implement an init method in your subclasses of Drydock::Command to handle
117
+ # your own initialization stuff.
116
118
  #
117
119
  # <li>+cmd_str+ is the short name used to evoke this command. It will equal @cmd
118
120
  # unless an alias was used used to evoke this command.</li>
@@ -121,7 +123,7 @@ module Drydock
121
123
  # <li>+stdin+ contains the output of stdin do; ...; end otherwise it's a STDIN IO handle.</li>
122
124
  # <li>+global_options+ a hash of the global options specified on the command-line</li>
123
125
  # <li>+options+ a hash of the command-specific options specific on the command-line.</li>
124
- def call(cmd_str=nil, argv=[], stdin=[], global_options={}, options={})
126
+ def prepare(cmd_str=nil, argv=[], stdin=[], global_options={}, options={})
125
127
  @alias = cmd_str.nil? ? @cmd : cmd_str
126
128
 
127
129
  global_options.each_pair do |n,v|
@@ -132,19 +134,28 @@ module Drydock
132
134
  self.option.send("#{n}=", v) # ... and also the command options
133
135
  end
134
136
 
135
-
136
137
  @argv << argv # TODO: Using += returns an Array instead of FancyArray
137
138
  @argv.flatten! # NOTE: << creates @argv[[]]
138
139
  @stdin = stdin
139
140
 
140
141
  self.init if self.respond_to? :init # Must be called first!
141
- self.print_header if self.respond_to? :print_header
142
142
 
143
+ end
144
+
145
+ # Calls the command in the following order:
146
+ #
147
+ # * print_header
148
+ # * validation (if methodname_valid? exists)
149
+ # * command block (@b)
150
+ # * print_footer
151
+ #
152
+ def call
153
+ self.print_header if self.respond_to? :print_header
143
154
  if @b
144
155
  run_validation
145
156
  @b.call(self)
146
157
 
147
- elsif !(chosen = find_action(options)).empty?
158
+ elsif !(chosen = find_action(self.option)).empty?
148
159
  raise "Only one action at a time please! I can't #{chosen.join(' AND ')}." if chosen.size > 1
149
160
  criteria = [[@cmd, chosen.first], [chosen.first, @cmd]]
150
161
  meth = name = nil
@@ -167,7 +178,6 @@ module Drydock
167
178
  end
168
179
 
169
180
  self.print_footer if respond_to? :print_footer
170
-
171
181
  end
172
182
 
173
183
  # <li>+meth+ The method name used to determine the name of the validation method.
@@ -199,6 +209,7 @@ module Drydock
199
209
  # OptionParser#getopts)</li>
200
210
  # Returns an array of action names (empty if no action was supplied)
201
211
  def find_action(options)
212
+ options = options.marshal_dump if options.is_a?(OpenStruct)
202
213
  boolkeys = options.keys.select { |n| options[n] == true } || []
203
214
  (@actions || []) & boolkeys # an array of requested actions (or empty)
204
215
  end
@@ -341,19 +352,19 @@ module Drydock
341
352
  @@command_argv_names[@@command_index] += args.flatten
342
353
  end
343
354
 
344
- # The project of the script. This is currently only used when printing
355
+ # The project name. This is currently only used when printing
345
356
  # list of commands (see: Drydock::Command#show_commands). It may be
346
357
  # used elsewhere in the future.
347
358
  def project(txt=nil)
348
359
 
349
360
  return @@project unless txt
350
361
 
351
- begin
352
- require txt.downcase
353
- rescue LoadError => ex
354
- Drydock.run = false # Prevent execution at_exit
355
- abort "Problem during require: #{ex.message}"
356
- end
362
+ #begin
363
+ # require txt.downcase
364
+ #rescue LoadError => ex
365
+ # Drydock.run = false # Prevent execution at_exit
366
+ # abort "Problem during require: #{ex.message}"
367
+ #end
357
368
  @@project = txt
358
369
  end
359
370
 
@@ -509,7 +520,7 @@ module Drydock
509
520
  # end
510
521
  #
511
522
  def command(*cmds, &b)
512
- cmd = cmds.first
523
+ cmd = cmds.first # Should we accept aliases here?
513
524
 
514
525
  if cmd.is_a? Hash
515
526
  raise "#{cmd.values.first} is not a subclass of Drydock::Command" unless cmd.values.first.ancestors.member?(Drydock::Command)
@@ -616,13 +627,18 @@ module Drydock
616
627
  raise UnknownCommand.new(cmd_name) unless command?(cmd_name)
617
628
 
618
629
  stdin = (defined? @@stdin_block) ? @@stdin_block.call(stdin, []) : stdin
619
- @@before_block.call if defined? @@before_block
620
630
 
621
- command_portion = lambda { call_command(cmd_name, argv, stdin, global_options, command_options) }
622
-
623
- capture? ? (@@captured = capture_io(@@capture, &command_portion)) : command_portion.call
631
+ command_obj = get_command(cmd_name)
632
+ command_obj.prepare(cmd_name, argv, stdin, global_options, command_options)
633
+
634
+ # Execute before block
635
+ @@before_block.call(command_obj) if defined? @@before_block
624
636
 
625
- @@after_block.call if defined? @@after_block
637
+ # Execute the requested command. We'll capture STDERR or STDOUT if desired.
638
+ @@captured = capture? ? capture_io(@@capture) { command_obj.call } : command_obj.call
639
+
640
+ # Execute after block
641
+ @@after_block.call(command_obj) if defined? @@after_block
626
642
 
627
643
  rescue OptionParser::InvalidOption => ex
628
644
  raise Drydock::InvalidArgument.new(ex.args)
@@ -669,11 +685,11 @@ module Drydock
669
685
  # ...
670
686
  # end
671
687
  #
672
- def capture_io(stream)
688
+ def capture_io(stream, &block)
673
689
  raise "We can only capture STDOUT or STDERR" unless stream == :stdout || stream == :stderr
674
690
  begin
675
691
  eval "$#{stream} = StringIO.new"
676
- yield
692
+ block.call
677
693
  eval("$#{stream}").rewind # Otherwise we'll get nil
678
694
  result = eval("$#{stream}").read
679
695
  ensure
@@ -683,12 +699,6 @@ module Drydock
683
699
 
684
700
  private
685
701
 
686
- # Executes the block associated to +cmd+
687
- def call_command(cmd, argv=[], stdin=nil, global_options={}, command_options={})
688
- return unless command?(cmd)
689
- get_command(cmd).call(cmd, argv, stdin, global_options || {}, command_options || {})
690
- end
691
-
692
702
  # Returns the Drydock::Command object with the name +cmd+
693
703
  def get_command(cmd)
694
704
  return unless command?(cmd)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: drydock
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Delano Mandelbaum
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-03-15 00:00:00 -04:00
12
+ date: 2009-04-05 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -57,7 +57,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
57
57
  requirements: []
58
58
 
59
59
  rubyforge_project: drydock
60
- rubygems_version: 1.2.0
60
+ rubygems_version: 1.3.1
61
61
  signing_key:
62
62
  specification_version: 1
63
63
  summary: A seaworthy DSL for writing command line apps