drydock 0.5.1 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
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