rubikon 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.
@@ -0,0 +1,31 @@
1
+ # This code is free software; you can redistribute it and/or modify it under
2
+ # the terms of the new BSD License.
3
+ #
4
+ # Copyright (c) 2010, Sebastian Staudt
5
+
6
+ unless Enumerable.method_defined?(:max_by)
7
+
8
+ # Extends Ruby's own Enumrable module with method #max_by? for Ruby < 1.8.7
9
+ #
10
+ # @author Sebastian Staudt
11
+ # @since 0.5.0
12
+ module Enumerable
13
+
14
+ def find_index(obj)
15
+
16
+ end
17
+
18
+ # Returns the object in enum that gives the maximum value from the given
19
+ # block.
20
+ #
21
+ # @yield [obj] The block to call on each element in the enum
22
+ # @yieldparam [Object] obj A single object in the enum
23
+ # @yieldreturn [Comparable] A value that can be compared (+<=>+) with the
24
+ # values of the other objects in the enum
25
+ def max_by(&block)
26
+ max { |a , b| block.call(a) <=> block.call(b) }
27
+ end
28
+
29
+ end
30
+
31
+ end
@@ -32,6 +32,7 @@ module Rubikon
32
32
  # user on the command-line.
33
33
  #
34
34
  # @param [#to_sym] name The name of the parameter to check
35
+ # @see Parameter
35
36
  # @since 0.2.0
36
37
  #
37
38
  # @example
@@ -73,6 +74,8 @@ module Rubikon
73
74
  # is called with the associated parameter
74
75
  #
75
76
  # @return [Command]
77
+ # @see default
78
+ # @see Command
76
79
  # @since 0.2.0
77
80
  def command(name, arg_count = nil, description = nil, &block)
78
81
  command = nil
@@ -127,6 +130,8 @@ module Rubikon
127
130
  # parameter is given to the application
128
131
  #
129
132
  # @return [Command] The default Command object
133
+ # @see Command
134
+ # @see command
130
135
  # @since 0.2.0
131
136
  def default(arg_count = nil, description = nil, &block)
132
137
  if arg_count.is_a? Symbol
@@ -275,6 +280,7 @@ module Rubikon
275
280
  # arbitrary number of arguments
276
281
  # @param [Proc] block An optional code block that should be executed if
277
282
  # this option is used
283
+ # @see Option
278
284
  # @since 0.2.0
279
285
  #
280
286
  # @example
@@ -439,6 +445,7 @@ module Rubikon
439
445
  #
440
446
  # @param [Proc] block The block to execute while the throbber is
441
447
  # displayed
448
+ # @see Throbber
442
449
  # @since 0.2.0
443
450
  # @yield While the block is executed a throbber is displayed
444
451
  #
@@ -51,6 +51,7 @@ module Rubikon
51
51
  @parameters = []
52
52
  @sandbox = Sandbox.new(self)
53
53
  @settings = {
54
+ :autohelp => true,
54
55
  :autorun => true,
55
56
  :colors => true,
56
57
  :config_file => "#{self.class.to_s.downcase}.yml",
@@ -109,9 +110,14 @@ module Rubikon
109
110
  rescue
110
111
  raise $! if @settings[:raise_errors]
111
112
 
112
- puts "r{Error:}\n #{$!.message}"
113
- puts " at #{$!.backtrace.join("\n at ")}" if $DEBUG
114
- exit 1
113
+ if @settings[:autohelp] && @commands.key?(:help) &&
114
+ $!.is_a?(UnknownCommandError)
115
+ call :help, $!.command
116
+ else
117
+ puts "r{Error:}\n #{$!.message}"
118
+ debug " at #{$!.backtrace.join("\n at ")}"
119
+ exit 1
120
+ end
115
121
  ensure
116
122
  InstanceMethods.instance_method(:reset).bind(self).call
117
123
  end
@@ -149,6 +155,38 @@ module Rubikon
149
155
  global_flag :d => :debug
150
156
  end
151
157
 
158
+ # Prints a help screen for this application
159
+ #
160
+ # @param [String] info A additional information string to be displayed
161
+ # right after usage information
162
+ # @since 0.6.0
163
+ def help(info = nil)
164
+ help = {}
165
+ @commands.each_value do |command|
166
+ help[command.name.to_s] = command.description
167
+ end
168
+ help.delete('__default')
169
+
170
+ if @commands.key? :__default
171
+ puts " [command] [args]\n\n"
172
+ else
173
+ puts " command [args]\n\n"
174
+ end
175
+
176
+ puts "#{info}\n\n" unless info.nil?
177
+
178
+ puts 'Commands:'
179
+ max_command_length = help.keys.max_by { |a| a.size }.size
180
+ help.sort_by { |name, description| name }.each do |name, description|
181
+ puts " #{name.ljust(max_command_length)} #{description}"
182
+ end
183
+
184
+ if @commands.key?(:__default) && @commands[:__default].description != :hidden
185
+ put "\nYou can also call this application without a command:"
186
+ puts @commands[:__default].help(false) + "\n"
187
+ end
188
+ end
189
+
152
190
  # Defines a command for displaying a help screen
153
191
  #
154
192
  # This takes any defined commands and it's corresponding options and
@@ -158,16 +196,11 @@ module Rubikon
158
196
  global_parameters = @global_parameters
159
197
  settings = @settings
160
198
 
161
- command :help, nil, 'Display this help screen' do
199
+ command :help, 0..1, 'Show help for the application or a single command' do
162
200
  put settings[:help_banner]
163
201
 
164
- help = {}
165
- commands.each_value do |command|
166
- help[command.name.to_s] = command.description
167
- end
168
-
169
202
  global_params = ''
170
- global_parameters.values.uniq.sort {|a,b| a.name.to_s <=> b.name.to_s }.each do |param|
203
+ global_parameters.values.uniq.sort_by { |a| a.name.to_s }.each do |param|
171
204
  global_params << ' ['
172
205
  ([param.name] + param.aliases).each_with_index do |name, index|
173
206
  name = name.to_s
@@ -178,19 +211,19 @@ module Rubikon
178
211
  global_params << ' ...' if param.is_a?(Option)
179
212
  global_params << ']'
180
213
  end
214
+ put global_params
181
215
 
182
- default_description = help.delete('__default')
183
- if default_description.nil?
184
- puts "#{global_params} command [args]\n\n"
185
- else
186
- puts "#{global_params} [command] [args]\n\n"
187
- puts "Without command: #{default_description}\n\n"
188
- end
216
+ app_help = lambda { |info| @__app__.instance_eval { help(info) } }
189
217
 
190
- puts 'Commands:'
191
- max_command_length = help.keys.max { |a, b| a.size <=> b.size }.size
192
- help.sort_by { |name, description| name }.each do |name, description|
193
- puts " #{name.ljust(max_command_length)} #{description}"
218
+ unless args.first.nil?
219
+ command = args.first.to_sym
220
+ if commands.keys.include?(command)
221
+ puts commands[command].help
222
+ else
223
+ app_help.call("The command \"#{command}\" is undefined. The following commands are available:")
224
+ end
225
+ else
226
+ app_help.call(nil)
194
227
  end
195
228
  end
196
229
  end
@@ -240,7 +273,8 @@ module Rubikon
240
273
  InstanceMethods.instance_method(:help_command).bind(self).call
241
274
  InstanceMethods.instance_method(:verbose_flag).bind(self).call
242
275
 
243
- if @settings[:help_as_default] && !@commands.keys.include?(:__default)
276
+ if @settings[:help_as_default] && @commands.key?(:help) &&
277
+ !@commands.key?(:__default)
244
278
  default :help
245
279
  end
246
280
 
@@ -299,19 +333,22 @@ module Rubikon
299
333
  # parameters of this command that have been supplied and any
300
334
  # additional command-line arguments supplied
301
335
  def parse_arguments(args)
302
- command_arg = args.shift
303
- if command_arg.nil? || command_arg.start_with?('-')
336
+ command_arg = args.find { |arg| arg == '--' || !arg.start_with?('-') }
337
+ command_arg = nil if command_arg == '--'
338
+
339
+ if command_arg.nil?
304
340
  command = @commands[:__default]
305
- args.unshift(command_arg) unless command_arg.nil?
306
341
  raise NoDefaultCommandError if command.nil?
307
342
  else
308
343
  command = @commands[command_arg.to_sym]
344
+ args.delete_at args.index(command_arg)
309
345
  raise UnknownCommandError.new(command_arg) if command.nil?
310
346
  end
311
347
 
348
+ args.delete '--'
312
349
  args = args.map do |arg|
313
350
  if !arg.start_with?('--') && arg.start_with?('-') && arg.size > 2
314
- arg[1..-1].split('').map { |a| "-#{a}"}
351
+ arg[1..-1].split('').map { |a| "-#{a}" }
315
352
  else
316
353
  arg
317
354
  end
@@ -354,7 +391,7 @@ module Rubikon
354
391
  # @see Parameter#reset
355
392
  # @since 0.4.0
356
393
  def reset
357
- ostream.rewind
394
+ ostream.rewind if ostream.is_a? StringIO || !ostream.stat.chardev?
358
395
  ColoredIO.remove_color_filter(ostream)
359
396
  (@commands.values + @global_parameters.values).uniq.each do |param|
360
397
  param.send :reset
@@ -14,6 +14,8 @@ module Rubikon
14
14
  # be executed when running the Application.
15
15
  #
16
16
  # @author Sebastian Staudt
17
+ # @see Application::DSLMethods#command
18
+ # @see Application::DSLMethods#default
17
19
  # @since 0.3.0
18
20
  class Command
19
21
 
@@ -56,6 +58,66 @@ module Rubikon
56
58
  end
57
59
  end
58
60
 
61
+ # Generate help for this command
62
+ #
63
+ # @param [Boolean] show_usage If +true+, the returned String will also
64
+ # include usage information
65
+ # @return [String] The contents of the help screen for this command
66
+ # @since 0.6.0
67
+ def help(show_usage = true)
68
+ help = ''
69
+
70
+ if show_usage
71
+ help << " #{name}" if name != :__default
72
+
73
+ @params.values.uniq.sort_by {|a| a.name.to_s }.each do |param|
74
+ help << ' ['
75
+ ([param.name] + param.aliases).each_with_index do |name, index|
76
+ name = name.to_s
77
+ help << '|' if index > 0
78
+ help << '-' if name.size > 1
79
+ help << "-#{name}"
80
+ end
81
+ help << ' ...' if param.is_a?(Option)
82
+ help << ']'
83
+ end
84
+ end
85
+
86
+ help << "\n\n#{description}" unless description.nil?
87
+
88
+ help_flags = {}
89
+ help_options = {}
90
+ params.each_value do |param|
91
+ if param.is_a? Flag
92
+ help_flags[param.name.to_s] = param
93
+ else
94
+ help_options[param.name.to_s] = param
95
+ end
96
+ end
97
+
98
+ param_name = lambda { |name| "#{name.size > 1 ? '-' : ' '}-#{name}" }
99
+ unless help_flags.empty? && help_options.empty?
100
+ max_param_length = (help_flags.keys + help_options.keys).
101
+ max_by { |a| a.size }.size + 2
102
+ end
103
+
104
+ unless help_flags.empty?
105
+ help << "\n\nFlags:"
106
+ help_flags.sort_by { |name, param| name }.each do |name, param|
107
+ help << "\n #{param_name.call(name).ljust(max_param_length)}"
108
+ end
109
+ end
110
+
111
+ unless help_options.empty?
112
+ help << "\n\nOptions:\n"
113
+ help_options.sort_by { |name, param| name }.each do |name, param|
114
+ help << " #{param_name.call(name).ljust(max_param_length)} ...\n"
115
+ end
116
+ end
117
+
118
+ help
119
+ end
120
+
59
121
  private
60
122
 
61
123
  # Add a new parameter for this command
@@ -45,6 +45,7 @@ module Rubikon
45
45
  # Raised if the user did not specify a command and no default command exists
46
46
  #
47
47
  # @author Sebastian Staudt
48
+ # @see Application::DSLMethods#default
48
49
  # @since 0.3.0
49
50
  class NoDefaultCommandError < ArgumentError
50
51
 
@@ -57,11 +58,20 @@ module Rubikon
57
58
  # Raised if a command has been supplied that does not exist
58
59
  #
59
60
  # @author Sebastian Staudt
61
+ # @see Application::DSLMethods#command
60
62
  # @since 0.3.0
61
63
  class UnknownCommandError < ArgumentError
62
64
 
65
+ # @return [Symbol] The name of the command that has been tried to access
66
+ attr_reader :command
67
+
68
+ # Creates a new error and stores the name of the command that could not be
69
+ # found
70
+ #
71
+ # @param [Symbol] name The name of the unknown command
63
72
  def initialize(name)
64
73
  super "Unknown command: #{name}"
74
+ @command = name
65
75
  end
66
76
 
67
77
  end
@@ -69,6 +79,10 @@ module Rubikon
69
79
  # Raised if a parameter has been supplied that does not exist
70
80
  #
71
81
  # @author Sebastian Staudt
82
+ # @see Application::DSLMethods#flag
83
+ # @see Application::DSLMethods#option
84
+ # @see Application::DSLMethods#global_flag
85
+ # @see Application::DSLMethods#global_option
72
86
  # @since 0.3.0
73
87
  class UnknownParameterError < ArgumentError
74
88
 
data/lib/rubikon/flag.rb CHANGED
@@ -10,8 +10,8 @@ module Rubikon
10
10
  # A flag is an application parameter without arguments
11
11
  #
12
12
  # @author Sebastian Staudt
13
- # @see Application::InstanceMethods#flag
14
- # @see Application::InstanceMethods#global_flag
13
+ # @see Application::DSLMethods#flag
14
+ # @see Application::DSLMethods#global_flag
15
15
  # @see Parameter
16
16
  # @since 0.3.0
17
17
  class Flag
@@ -72,6 +72,7 @@ module Rubikon
72
72
  # indices can be used always while symbolic arguments are only
73
73
  # available for named arguments.
74
74
  # @return The argument with the specified index
75
+ # @see #args
75
76
  # @since 0.4.0
76
77
  def [](arg)
77
78
  arg = @arg_names.index(arg) if arg.is_a? Symbol
@@ -11,7 +11,8 @@ module Rubikon
11
11
  # arguments.
12
12
  #
13
13
  # @author Sebastian Staudt
14
- # @see Application::InstanceMethods#option
14
+ # @see Application::DSLMethods#option
15
+ # @see Application::DSLMethods#global_option
15
16
  # @see Parameter
16
17
  # @since 0.3.0
17
18
  class Option
@@ -11,6 +11,8 @@ module Rubikon
11
11
  #
12
12
  # @author Sebastian Staudt
13
13
  # @see Command
14
+ # @see Flag
15
+ # @see Option
14
16
  # @since 0.3.0
15
17
  module Parameter
16
18
 
@@ -9,7 +9,7 @@ module Rubikon
9
9
  # A class for displaying and managing progress bars
10
10
  #
11
11
  # @author Sebastian Staudt
12
- # @see Application::InstanceMethods#throbber
12
+ # @see Application::DSLMethods#progress_bar
13
13
  # @since 0.2.0
14
14
  class ProgressBar
15
15
 
@@ -8,7 +8,7 @@ module Rubikon
8
8
  # A class for displaying and managing throbbers
9
9
  #
10
10
  # @author Sebastian Staudt
11
- # @see Application::InstanceMethods#throbber
11
+ # @see Application::DSLMethods#throbber
12
12
  # @since 0.2.0
13
13
  class Throbber < Thread
14
14
 
data/lib/rubikon.rb CHANGED
@@ -24,6 +24,6 @@ require 'rubikon/application/base'
24
24
  module Rubikon
25
25
 
26
26
  # This is the current version of the Rubikon gem
27
- VERSION = '0.5.1'
27
+ VERSION = '0.5.2'
28
28
 
29
29
  end
@@ -120,7 +120,7 @@ class TestApplication < Test::Unit::TestCase
120
120
 
121
121
  should 'have a working help command' do
122
122
  @app.run(%w{help})
123
- assert_match /Usage: [^ ]* \[--debug\|-d\] \[--gflag\|--gf1\|--gf2\] \[--gopt\|--go1\|--go2 \.\.\.\] \[--verbose\|-v\] command \[args\]\n\nCommands:\n arguments \n globalopt \n help Display this help screen\n input \n object_id \n parameters \n progressbar \n sandbox \n throbber \n/, @ostream.string
123
+ assert_match /Usage: [^ ]* \[--debug\|-d\] \[--gflag\|--gf1\|--gf2\] \[--gopt\|--go1\|--go2 \.\.\.\] \[--verbose\|-v\] \[command\] \[args\]\n\nCommands:\n arguments \n globalopt \n help Show help for the application or a single command\n input \n object_id \n parameters \n progressbar \n sandbox \n throbber \n/, @ostream.string
124
124
  end
125
125
 
126
126
  should 'have a working DSL for command parameters' do
data/test/testapps.rb CHANGED
@@ -13,6 +13,7 @@ end
13
13
 
14
14
  class TestApp < Application::Base
15
15
 
16
+ set :autohelp, false
16
17
  set :autorun, false
17
18
  set :name, 'Rubikon test application'
18
19
  set :raise_errors, true
@@ -29,7 +30,7 @@ class TestApp < Application::Base
29
30
  end
30
31
  global_option :go2 => :gopt
31
32
 
32
- default do
33
+ default nil, :hidden do
33
34
  'default command'
34
35
  end
35
36
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubikon
3
3
  version: !ruby/object:Gem::Version
4
- hash: 9
4
+ hash: 15
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 5
9
- - 1
10
- version: 0.5.1
9
+ - 2
10
+ version: 0.5.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Sebastian Staudt
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-12-01 00:00:00 +01:00
18
+ date: 2010-12-04 00:00:00 +01:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -74,6 +74,7 @@ files:
74
74
  - LICENSE
75
75
  - README.md
76
76
  - Rakefile
77
+ - lib/core_ext/enumerable.rb
77
78
  - lib/core_ext/object.rb
78
79
  - lib/core_ext/string.rb
79
80
  - lib/rubikon.rb