cri 2.6.1 → 2.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,10 +1,11 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Cri
4
-
5
4
  # The command DSL is a class that is used for building and modifying
6
5
  # commands.
7
6
  class CommandDSL
7
+ # @return [Cri::Command] The built command
8
+ attr_reader :command
8
9
 
9
10
  # Creates a new DSL, intended to be used for building a single command. A
10
11
  # {CommandDSL} instance is not reusable; create a new instance if you want
@@ -12,15 +13,10 @@ module Cri
12
13
  #
13
14
  # @param [Cri::Command, nil] command The command to modify, or nil if a
14
15
  # new command should be created
15
- def initialize(command=nil)
16
+ def initialize(command = nil)
16
17
  @command = command || Cri::Command.new
17
18
  end
18
19
 
19
- # @return [Cri::Command] The built command
20
- def command
21
- @command
22
- end
23
-
24
20
  # Adds a subcommand to the current command. The command can either be
25
21
  # given explicitly, or a block can be given that defines the command.
26
22
  #
@@ -29,7 +25,7 @@ module Cri
29
25
  # added as a subcommand
30
26
  #
31
27
  # @return [void]
32
- def subcommand(command=nil, &block)
28
+ def subcommand(command = nil, &block)
33
29
  if command.nil?
34
30
  command = Cri::Command.define(&block)
35
31
  end
@@ -108,13 +104,17 @@ module Cri
108
104
  # @option params [Boolean] :multiple Whether or not the option should
109
105
  # be multi-valued
110
106
  #
107
+ # @option params [Boolean] :hidden Whether or not the option should
108
+ # be printed in the help output
109
+ #
111
110
  # @return [void]
112
- def option(short, long, desc, params={}, &block)
111
+ def option(short, long, desc, params = {}, &block)
113
112
  requiredness = params.fetch(:argument, :forbidden)
114
113
  multiple = params.fetch(:multiple, false)
114
+ hidden = params.fetch(:hidden, false)
115
115
 
116
116
  if short.nil? && long.nil?
117
- raise ArgumentError, "short and long options cannot both be nil"
117
+ fail ArgumentError, 'short and long options cannot both be nil'
118
118
  end
119
119
 
120
120
  @command.option_definitions << {
@@ -124,6 +124,7 @@ module Cri
124
124
  :argument => requiredness,
125
125
  :multiple => multiple,
126
126
  :block => block,
127
+ :hidden => hidden,
127
128
  }
128
129
  end
129
130
  alias_method :opt, :option
@@ -140,12 +141,15 @@ module Cri
140
141
  # @option params [Boolean] :multiple Whether or not the option should
141
142
  # be multi-valued
142
143
  #
144
+ # @option params [Boolean] :hidden Whether or not the option should
145
+ # be printed in the help output
146
+ #
143
147
  # @return [void]
144
148
  #
145
149
  # @see {#option}
146
- def required(short, long, desc, params={}, &block)
150
+ def required(short, long, desc, params = {}, &block)
147
151
  params = params.merge(:argument => :required)
148
- self.option(short, long, desc, params, &block)
152
+ option(short, long, desc, params, &block)
149
153
  end
150
154
 
151
155
  # Adds a new option with a forbidden argument to the command. If a block
@@ -160,12 +164,15 @@ module Cri
160
164
  # @option params [Boolean] :multiple Whether or not the option should
161
165
  # be multi-valued
162
166
  #
167
+ # @option params [Boolean] :hidden Whether or not the option should
168
+ # be printed in the help output
169
+ #
163
170
  # @return [void]
164
171
  #
165
172
  # @see {#option}
166
- def flag(short, long, desc, params={}, &block)
173
+ def flag(short, long, desc, params = {}, &block)
167
174
  params = params.merge(:argument => :forbidden)
168
- self.option(short, long, desc, params, &block)
175
+ option(short, long, desc, params, &block)
169
176
  end
170
177
  alias_method :forbidden, :flag
171
178
 
@@ -181,12 +188,15 @@ module Cri
181
188
  # @option params [Boolean] :multiple Whether or not the option should
182
189
  # be multi-valued
183
190
  #
191
+ # @option params [Boolean] :hidden Whether or not the option should
192
+ # be printed in the help output
193
+ #
184
194
  # @return [void]
185
195
  #
186
196
  # @see {#option}
187
- def optional(short, long, desc, params={}, &block)
197
+ def optional(short, long, desc, params = {}, &block)
188
198
  params = params.merge(:argument => :optional)
189
- self.option(short, long, desc, params, &block)
199
+ option(short, long, desc, params, &block)
190
200
  end
191
201
 
192
202
  # Sets the run block to the given block. The given block should have two
@@ -203,8 +213,8 @@ module Cri
203
213
  # @return [void]
204
214
  def run(&block)
205
215
  unless [2, 3].include?(block.arity)
206
- raise ArgumentError,
207
- "The block given to Cri::Command#run expects two or three args"
216
+ fail ArgumentError,
217
+ 'The block given to Cri::Command#run expects two or three args'
208
218
  end
209
219
 
210
220
  @command.block = block
@@ -1,11 +1,9 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Cri
4
-
5
4
  # A command runner is responsible for the execution of a command. Using it
6
5
  # is optional, but it is useful for commands whose execution block is large.
7
6
  class CommandRunner
8
-
9
7
  # @return [Hash] A hash contain the options and their values
10
8
  attr_reader :options
11
9
 
@@ -33,7 +31,7 @@ module Cri
33
31
  #
34
32
  # @return [void]
35
33
  def call
36
- self.run
34
+ run
37
35
  end
38
36
 
39
37
  # Performs the actual execution of the command.
@@ -42,9 +40,7 @@ module Cri
42
40
  #
43
41
  # @abstract
44
42
  def run
45
- raise NotImplementedError, 'Cri::CommandRunner subclasses must implement #run'
43
+ fail NotImplementedError, 'Cri::CommandRunner subclasses must implement #run'
46
44
  end
47
-
48
45
  end
49
-
50
46
  end
@@ -14,8 +14,8 @@ flag :v, :verbose, 'show more detailed help'
14
14
 
15
15
  run do |opts, args, cmd|
16
16
  if cmd.supercommand.nil?
17
- raise NoHelpAvailableError,
18
- "No help available because the help command has no supercommand"
17
+ fail NoHelpAvailableError,
18
+ 'No help available because the help command has no supercommand'
19
19
  end
20
20
 
21
21
  is_verbose = opts.fetch(:verbose, false)
@@ -1,6 +1,6 @@
1
1
  # encoding: utf-8
2
2
 
3
- flag :h, :help, 'show help for this command' do |value, cmd|
3
+ flag :h, :help, 'show help for this command' do |_value, cmd|
4
4
  puts cmd.help
5
5
  exit 0
6
6
  end
@@ -1,6 +1,8 @@
1
1
  # encoding: utf-8
2
2
 
3
- module Cri::CoreExtensions
3
+ module Cri
4
+ module CoreExtensions
5
+ end
4
6
  end
5
7
 
6
8
  require 'cri/core_ext/string'
@@ -2,36 +2,34 @@
2
2
 
3
3
  require 'colored'
4
4
 
5
- module Cri::CoreExtensions
6
-
7
- # @deprecated
8
- module String
9
-
10
- # @see Cri::StringFormatter#to_paragraphs
11
- def to_paragraphs
12
- Cri::StringFormatter.new.to_paragraphs(self)
13
- end
14
-
15
- # @see Cri::StringFormatter#to_paragraphs
16
- def wrap_and_indent(width, indentation)
17
- Cri::StringFormatter.new.wrap_and_indent(self, width, indentation)
18
- end
19
-
20
- # @see Cri::StringFormatter#format_as_title
21
- def formatted_as_title
22
- Cri::StringFormatter.new.format_as_title(self)
5
+ module Cri
6
+ module CoreExtensions
7
+ # @deprecated
8
+ module String
9
+ # @see Cri::StringFormatter#to_paragraphs
10
+ def to_paragraphs
11
+ Cri::StringFormatter.new.to_paragraphs(self)
12
+ end
13
+
14
+ # @see Cri::StringFormatter#to_paragraphs
15
+ def wrap_and_indent(width, indentation)
16
+ Cri::StringFormatter.new.wrap_and_indent(self, width, indentation)
17
+ end
18
+
19
+ # @see Cri::StringFormatter#format_as_title
20
+ def formatted_as_title
21
+ Cri::StringFormatter.new.format_as_title(self)
22
+ end
23
+
24
+ # @see Cri::StringFormatter#format_as_command
25
+ def formatted_as_command
26
+ Cri::StringFormatter.new.format_as_command(self)
27
+ end
28
+
29
+ # @see Cri::StringFormatter#format_as_option
30
+ def formatted_as_option
31
+ Cri::StringFormatter.new.format_as_option(self)
32
+ end
23
33
  end
24
-
25
- # @see Cri::StringFormatter#format_as_command
26
- def formatted_as_command
27
- Cri::StringFormatter.new.format_as_command(self)
28
- end
29
-
30
- # @see Cri::StringFormatter#format_as_option
31
- def formatted_as_option
32
- Cri::StringFormatter.new.format_as_option(self)
33
- end
34
-
35
34
  end
36
-
37
35
  end
@@ -1,10 +1,17 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Cri
4
-
5
4
  # The {HelpRenderer} class is responsible for generating a string containing
6
5
  # the help for a given command, intended to be printed on the command line.
7
6
  class HelpRenderer
7
+ # The line width of the help output
8
+ LINE_WIDTH = 78
9
+
10
+ # The indentation of descriptions
11
+ DESC_INDENT = 4
12
+
13
+ # The spacing between an option name and option description
14
+ OPT_DESC_SPACING = 6
8
15
 
9
16
  # Creates a new help renderer for the given command.
10
17
  #
@@ -12,7 +19,7 @@ module Cri
12
19
  #
13
20
  # @option params [Boolean] :verbose true if the help output should be
14
21
  # verbose, false otherwise.
15
- def initialize(cmd, params={})
22
+ def initialize(cmd, params = {})
16
23
  @cmd = cmd
17
24
  @is_verbose = params.fetch(:verbose, false)
18
25
  @io = params.fetch(:io, $stdout)
@@ -40,32 +47,32 @@ module Cri
40
47
  def append_summary(text)
41
48
  return if @cmd.summary.nil?
42
49
 
43
- text << fmt.format_as_title("name", @io) << "\n"
50
+ text << fmt.format_as_title('name', @io) << "\n"
44
51
  text << " #{fmt.format_as_command(@cmd.name, @io)} - #{@cmd.summary}" << "\n"
45
52
  unless @cmd.aliases.empty?
46
- text << " aliases: " << @cmd.aliases.map { |a| fmt.format_as_command(a, @io) }.join(' ') << "\n"
53
+ text << ' aliases: ' << @cmd.aliases.map { |a| fmt.format_as_command(a, @io) }.join(' ') << "\n"
47
54
  end
48
55
  end
49
56
 
50
57
  def append_usage(text)
51
58
  return if @cmd.usage.nil?
52
59
 
53
- path = [ @cmd.supercommand ]
60
+ path = [@cmd.supercommand]
54
61
  path.unshift(path[0].supercommand) until path[0].nil?
55
62
  formatted_usage = @cmd.usage.gsub(/^([^\s]+)/) { |m| fmt.format_as_command(m, @io) }
56
63
  full_usage = path[1..-1].map { |c| fmt.format_as_command(c.name, @io) + ' ' }.join + formatted_usage
57
64
 
58
65
  text << "\n"
59
- text << fmt.format_as_title("usage", @io) << "\n"
60
- text << fmt.wrap_and_indent(full_usage, 78, 4) << "\n"
66
+ text << fmt.format_as_title('usage', @io) << "\n"
67
+ text << fmt.wrap_and_indent(full_usage, LINE_WIDTH, DESC_INDENT) << "\n"
61
68
  end
62
69
 
63
70
  def append_description(text)
64
71
  return if @cmd.description.nil?
65
72
 
66
73
  text << "\n"
67
- text << fmt.format_as_title("description", @io) << "\n"
68
- text << fmt.wrap_and_indent(@cmd.description, 78, 4) + "\n"
74
+ text << fmt.format_as_title('description', @io) << "\n"
75
+ text << fmt.wrap_and_indent(@cmd.description, LINE_WIDTH, DESC_INDENT) + "\n"
69
76
  end
70
77
 
71
78
  def append_subcommands(text)
@@ -80,13 +87,15 @@ module Cri
80
87
 
81
88
  # Command
82
89
  shown_subcommands.sort_by { |cmd| cmd.name }.each do |cmd|
83
- text << sprintf(" %-#{length+4}s %s\n",
84
- fmt.format_as_command(cmd.name, @io),
85
- cmd.summary)
90
+ text <<
91
+ format(
92
+ " %-#{length + DESC_INDENT}s %s\n",
93
+ fmt.format_as_command(cmd.name, @io),
94
+ cmd.summary)
86
95
  end
87
96
 
88
97
  # Hidden notice
89
- if !@is_verbose
98
+ unless @is_verbose
90
99
  diff = @cmd.subcommands.size - shown_subcommands.size
91
100
  case diff
92
101
  when 0
@@ -98,12 +107,34 @@ module Cri
98
107
  end
99
108
  end
100
109
 
110
+ def length_for_opt_defs(opt_defs)
111
+ opt_defs.map do |opt_def|
112
+ string = ''
113
+
114
+ # Always pretend there is a short option
115
+ string << '-X'
116
+
117
+ if opt_def[:long]
118
+ string << ' --' + opt_def[:long]
119
+ end
120
+
121
+ case opt_def[:argument]
122
+ when :required
123
+ string << '=<value>'
124
+ when :optional
125
+ string << '=[<value>]'
126
+ end
127
+
128
+ string.size
129
+ end.max
130
+ end
131
+
101
132
  def append_options(text)
102
133
  groups = { 'options' => @cmd.option_definitions }
103
134
  if @cmd.supercommand
104
135
  groups["options for #{@cmd.supercommand.name}"] = @cmd.supercommand.global_option_definitions
105
136
  end
106
- length = groups.values.inject(&:+).map { |o| o[:long].to_s.size }.max
137
+ length = length_for_opt_defs(groups.values.inject(&:+))
107
138
  groups.keys.sort.each do |name|
108
139
  defs = groups[name]
109
140
  append_option_group(text, name, defs, length)
@@ -119,19 +150,70 @@ module Cri
119
150
 
120
151
  ordered_defs = defs.sort_by { |x| x[:short] || x[:long] }
121
152
  ordered_defs.each do |opt_def|
122
- text << format_opt_def(opt_def, length)
123
- text << opt_def[:desc] << "\n"
153
+ unless opt_def[:hidden]
154
+ text << format_opt_def(opt_def, length)
155
+ text << fmt.wrap_and_indent(opt_def[:desc], LINE_WIDTH, length + OPT_DESC_SPACING + DESC_INDENT, true) << "\n"
156
+ end
124
157
  end
125
158
  end
126
159
 
127
- def format_opt_def(opt_def, length)
128
- opt_text = sprintf(
129
- " %-2s %-#{length+6}s",
130
- opt_def[:short] ? ('-' + opt_def[:short]) : '',
131
- opt_def[:long] ? ('--' + opt_def[:long]) : '')
132
- fmt.format_as_option(opt_text, @io)
160
+ def short_value_postfix_for(opt_def)
161
+ value_postfix =
162
+ case opt_def[:argument]
163
+ when :required
164
+ '<value>'
165
+ when :optional
166
+ '[<value>]'
167
+ else
168
+ nil
169
+ end
170
+
171
+ if value_postfix
172
+ opt_def[:long] ? '' : ' ' + value_postfix
173
+ else
174
+ ''
175
+ end
133
176
  end
134
177
 
135
- end
178
+ def long_value_postfix_for(opt_def)
179
+ value_postfix =
180
+ case opt_def[:argument]
181
+ when :required
182
+ '=<value>'
183
+ when :optional
184
+ '[=<value>]'
185
+ else
186
+ nil
187
+ end
188
+
189
+ if value_postfix
190
+ opt_def[:long] ? value_postfix : ''
191
+ else
192
+ ''
193
+ end
194
+ end
136
195
 
196
+ def format_opt_def(opt_def, length)
197
+ short_value_postfix = short_value_postfix_for(opt_def)
198
+ long_value_postfix = long_value_postfix_for(opt_def)
199
+
200
+ opt_text = ''
201
+ opt_text_len = 0
202
+ if opt_def[:short]
203
+ opt_text << fmt.format_as_option('-' + opt_def[:short], @io)
204
+ opt_text << short_value_postfix
205
+ opt_text << ' '
206
+ opt_text_len += 1 + opt_def[:short].size + short_value_postfix.size + 1
207
+ else
208
+ opt_text << ' '
209
+ opt_text_len += 3
210
+ end
211
+ opt_text << fmt.format_as_option('--' + opt_def[:long], @io) if opt_def[:long]
212
+ opt_text << long_value_postfix
213
+ opt_text_len += 2 + opt_def[:long].size if opt_def[:long]
214
+ opt_text_len += long_value_postfix.size
215
+
216
+ ' ' + opt_text + ' ' * (length + OPT_DESC_SPACING - opt_text_len)
217
+ end
218
+ end
137
219
  end