cri 2.1.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/NEWS.md CHANGED
@@ -1,6 +1,11 @@
1
1
  Cri News
2
2
  ========
3
3
 
4
+ 2.2.0
5
+ -----
6
+
7
+ * Allowed commands with subcommands to have a run block
8
+
4
9
  2.1.0
5
10
  -----
6
11
 
data/lib/cri.rb CHANGED
@@ -17,7 +17,7 @@ module Cri
17
17
  end
18
18
 
19
19
  # The current Cri version.
20
- VERSION = '2.1.0'
20
+ VERSION = '2.2.0'
21
21
 
22
22
  autoload 'Command', 'cri/command'
23
23
  autoload 'CommandDSL', 'cri/command_dsl'
@@ -226,7 +226,8 @@ module Cri
226
226
  end
227
227
  end
228
228
 
229
- # Runs the command with the given commandline arguments.
229
+ # Runs the command with the given commandline arguments, possibly invoking
230
+ # subcommands and passing on the options and arguments.
230
231
  #
231
232
  # @param [Array<String>] opts_and_args A list of unparsed arguments
232
233
  #
@@ -235,42 +236,59 @@ module Cri
235
236
  #
236
237
  # @return [void]
237
238
  def run(opts_and_args, parent_opts={})
238
- if subcommands.empty?
239
- # Parse
240
- parser = Cri::OptionParser.new(
241
- opts_and_args, global_option_definitions)
242
- self.handle_parser_errors_while { parser.run }
243
- local_opts = parser.options
244
- global_opts = parent_opts.merge(parser.options)
245
- args = parser.arguments
239
+ # Parse up to command name
240
+ stuff = partition(opts_and_args)
241
+ opts_before_subcmd, subcmd_name, opts_and_args_after_subcmd = *stuff
246
242
 
247
- # Handle options
248
- handle_options(local_opts)
249
-
250
- # Execute
251
- if @block.nil?
252
- raise NotImplementedError,
253
- "No implementation available for '#{self.name}'"
254
- end
255
- block.call(global_opts, args, self)
243
+ if subcommands.empty? || (subcmd_name.nil? && !self.block.nil?)
244
+ run_this(opts_and_args, parent_opts)
256
245
  else
257
- # Parse up to command name
258
- stuff = partition(opts_and_args)
259
- opts_before_cmd, cmd_name, opts_and_args_after_cmd = *stuff
260
-
261
246
  # Handle options
262
- handle_options(opts_before_cmd)
247
+ self.handle_options(opts_before_subcmd)
263
248
 
264
249
  # Get command
265
- if cmd_name.nil?
250
+ if subcmd_name.nil?
266
251
  $stderr.puts "#{name}: no command given"
267
252
  exit 1
268
253
  end
269
- command = command_named(cmd_name)
254
+ subcommand = self.command_named(subcmd_name)
270
255
 
271
256
  # Run
272
- command.run(opts_and_args_after_cmd, opts_before_cmd)
257
+ subcommand.run(opts_and_args_after_subcmd, opts_before_subcmd)
258
+ end
259
+ end
260
+
261
+ # Runs the actual command with the given commandline arguments, not
262
+ # invoking any subcommands. If the command does not have an execution
263
+ # block, an error ir raised.
264
+ #
265
+ # @param [Array<String>] opts_and_args A list of unparsed arguments
266
+ #
267
+ # @param [Hash] parent_opts A hash of options already handled by the
268
+ # supercommand
269
+ #
270
+ # @raise [NotImplementedError] if the command does not have an execution
271
+ # block
272
+ #
273
+ # @return [void]
274
+ def run_this(opts_and_args, parent_opts={})
275
+ # Parse
276
+ parser = Cri::OptionParser.new(
277
+ opts_and_args, self.global_option_definitions)
278
+ self.handle_parser_errors_while { parser.run }
279
+ local_opts = parser.options
280
+ global_opts = parent_opts.merge(parser.options)
281
+ args = parser.arguments
282
+
283
+ # Handle options
284
+ self.handle_options(local_opts)
285
+
286
+ # Execute
287
+ if self.block.nil?
288
+ raise NotImplementedError,
289
+ "No implementation available for '#{self.name}'"
273
290
  end
291
+ self.block.call(global_opts, args, self)
274
292
  end
275
293
 
276
294
  # @return [String] The help text for this command
@@ -92,6 +92,33 @@ class Cri::CommandTestCase < Cri::TestCase
92
92
  super_cmd
93
93
  end
94
94
 
95
+ def nested_cmd_with_run_block
96
+ super_cmd = Cri::Command.define do
97
+ name 'super'
98
+ usage 'super [command] [options] [arguments]'
99
+ summary 'does super stuff'
100
+ description 'This command does super stuff.'
101
+
102
+ run do |opts, args|
103
+ $stdout.puts "super"
104
+ end
105
+ end
106
+
107
+ super_cmd.define_command do
108
+ name 'sub'
109
+ aliases 'sup'
110
+ usage 'sub [options]'
111
+ summary 'does subby stuff'
112
+ description 'This command does subby stuff.'
113
+
114
+ run do |opts, args|
115
+ $stdout.puts "sub"
116
+ end
117
+ end
118
+
119
+ super_cmd
120
+ end
121
+
95
122
  def test_invoke_simple_without_opts_or_args
96
123
  out, err = capture_io_while do
97
124
  simple_cmd.run(%w())
@@ -210,6 +237,22 @@ class Cri::CommandTestCase < Cri::TestCase
210
237
  assert_equal [ ], lines(err)
211
238
  end
212
239
 
240
+ def test_invoke_nested_with_run_block
241
+ out, err = capture_io_while do
242
+ nested_cmd_with_run_block.run(%w())
243
+ end
244
+
245
+ assert_equal [ 'super' ], lines(out)
246
+ assert_equal [ ], lines(err)
247
+
248
+ out, err = capture_io_while do
249
+ nested_cmd_with_run_block.run(%w( sub ))
250
+ end
251
+
252
+ assert_equal [ 'sub' ], lines(out)
253
+ assert_equal [ ], lines(err)
254
+ end
255
+
213
256
  def test_help_nested
214
257
  help = nested_cmd.subcommands.find { |cmd| cmd.name == 'sub' }.help
215
258
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cri
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-16 00:00:00.000000000 Z
12
+ date: 2012-02-19 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: Cri allows building easy-to-use commandline interfaces with support for
15
15
  subcommands.
@@ -67,7 +67,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
67
67
  version: '0'
68
68
  requirements: []
69
69
  rubyforge_project:
70
- rubygems_version: 1.8.10
70
+ rubygems_version: 1.8.17
71
71
  signing_key:
72
72
  specification_version: 3
73
73
  summary: a library for building easy-to-use commandline tools