cri 2.6.1 → 2.7.0

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.
@@ -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