cri 2.7.0 → 2.7.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +3 -3
- data/Gemfile.lock +15 -13
- data/NEWS.md +7 -0
- data/README.adoc +5 -5
- data/Rakefile +5 -3
- data/cri.gemspec +2 -2
- data/lib/cri.rb +1 -3
- data/lib/cri/argument_array.rb +0 -2
- data/lib/cri/command.rb +17 -19
- data/lib/cri/command_dsl.rb +16 -18
- data/lib/cri/command_runner.rb +1 -3
- data/lib/cri/commands/basic_help.rb +5 -7
- data/lib/cri/commands/basic_root.rb +0 -2
- data/lib/cri/core_ext.rb +0 -2
- data/lib/cri/core_ext/string.rb +0 -2
- data/lib/cri/help_renderer.rb +6 -13
- data/lib/cri/option_parser.rb +10 -12
- data/lib/cri/platform.rb +0 -2
- data/lib/cri/string_formatter.rb +1 -3
- data/lib/cri/version.rb +1 -3
- data/test/helper.rb +3 -5
- data/test/test_argument_array.rb +0 -2
- data/test/test_base.rb +1 -4
- data/test/test_basic_help.rb +0 -2
- data/test/test_basic_root.rb +1 -3
- data/test/test_command.rb +25 -27
- data/test/test_command_dsl.rb +30 -32
- data/test/test_command_runner.rb +2 -4
- data/test/test_option_parser.rb +60 -62
- data/test/test_string_formatter.rb +0 -2
- metadata +6 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 125652850f61d27f4d91ec9e3bbfa46f25c03d11
|
4
|
+
data.tar.gz: dd5156012cb91ad551377bd807cd9b544300a618
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cd917c4f792476b45868a6c95c3a1a75ee88c3b49bdb05dd18e30bc637e69fe476d6a0f5d57cbdd86ddbc3e5d07ee24e63f8dd1a23bf207dbfc913e763237b81
|
7
|
+
data.tar.gz: b697f2c2897405954a4c66437515648b4e3e18631bf3cb9059ef0e221a8bf5412d0bd1b744099ece0e894fc278406765c0754766347011507374ae69fa0642cc
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,16 +1,14 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
cri (2.7.
|
4
|
+
cri (2.7.1)
|
5
5
|
colored (~> 1.2)
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
10
|
asciidoctor (1.5.2)
|
11
|
-
ast (2.
|
12
|
-
astrolabe (1.3.0)
|
13
|
-
parser (>= 2.2.0.pre.3, < 3.0)
|
11
|
+
ast (2.3.0)
|
14
12
|
colored (1.2)
|
15
13
|
coveralls (0.8.1)
|
16
14
|
json (~> 1.8)
|
@@ -27,22 +25,22 @@ GEM
|
|
27
25
|
mime-types (2.5)
|
28
26
|
minitest (5.6.1)
|
29
27
|
netrc (0.10.3)
|
30
|
-
parser (2.
|
31
|
-
ast (
|
32
|
-
powerpack (0.1.
|
33
|
-
rainbow (2.
|
28
|
+
parser (2.3.3.1)
|
29
|
+
ast (~> 2.2)
|
30
|
+
powerpack (0.1.1)
|
31
|
+
rainbow (2.1.0)
|
34
32
|
rake (10.4.2)
|
35
33
|
rest-client (1.8.0)
|
36
34
|
http-cookie (>= 1.0.2, < 2.0)
|
37
35
|
mime-types (>= 1.16, < 3.0)
|
38
36
|
netrc (~> 0.7)
|
39
|
-
rubocop (0.
|
40
|
-
|
41
|
-
parser (>= 2.2.2.1, < 3.0)
|
37
|
+
rubocop (0.46.0)
|
38
|
+
parser (>= 2.3.1.1, < 3.0)
|
42
39
|
powerpack (~> 0.1)
|
43
40
|
rainbow (>= 1.99.1, < 3.0)
|
44
|
-
ruby-progressbar (~> 1.
|
45
|
-
|
41
|
+
ruby-progressbar (~> 1.7)
|
42
|
+
unicode-display_width (~> 1.0, >= 1.0.1)
|
43
|
+
ruby-progressbar (1.8.1)
|
46
44
|
simplecov (0.10.0)
|
47
45
|
docile (~> 1.1.0)
|
48
46
|
json (~> 1.8)
|
@@ -55,6 +53,7 @@ GEM
|
|
55
53
|
unf (0.1.4)
|
56
54
|
unf_ext
|
57
55
|
unf_ext (0.0.7.1)
|
56
|
+
unicode-display_width (1.1.1)
|
58
57
|
yard (0.8.7.6)
|
59
58
|
|
60
59
|
PLATFORMS
|
@@ -69,3 +68,6 @@ DEPENDENCIES
|
|
69
68
|
rake
|
70
69
|
rubocop
|
71
70
|
yard
|
71
|
+
|
72
|
+
BUNDLED WITH
|
73
|
+
1.13.6
|
data/NEWS.md
CHANGED
data/README.adoc
CHANGED
@@ -6,13 +6,13 @@ link:https://coveralls.io/r/ddfreyne/cri[image:http://img.shields.io/coveralls/d
|
|
6
6
|
link:https://codeclimate.com/github/ddfreyne/cri[image:http://img.shields.io/codeclimate/github/ddfreyne/cri.svg[]]
|
7
7
|
link:http://inch-ci.org/github/ddfreyne/cri/[image:http://inch-ci.org/github/ddfreyne/cri.svg[]]
|
8
8
|
|
9
|
-
Cri is a library for building easy-to-use
|
9
|
+
Cri is a library for building easy-to-use command-line tools with support for
|
10
10
|
nested commands.
|
11
11
|
|
12
12
|
== Usage ==
|
13
13
|
|
14
14
|
The central concept in Cri is the _command_, which has option definitions as
|
15
|
-
well as code for actually executing itself. In Cri, the
|
15
|
+
well as code for actually executing itself. In Cri, the command-line tool
|
16
16
|
itself is a command as well.
|
17
17
|
|
18
18
|
Here’s a sample command definition:
|
@@ -45,7 +45,7 @@ end
|
|
45
45
|
--------------------------------------------------------------------------------
|
46
46
|
|
47
47
|
To run this command, invoke the `#run` method with the raw arguments. For
|
48
|
-
example, for a root command (the
|
48
|
+
example, for a root command (the command-line tool itself), the command could
|
49
49
|
be called like this:
|
50
50
|
|
51
51
|
[source,ruby]
|
@@ -84,7 +84,7 @@ description 'This command does a lot of stuff. I really mean a lot.'
|
|
84
84
|
--------------------------------------------------------------------------------
|
85
85
|
|
86
86
|
These lines of the command definition specify the name of the command (or the
|
87
|
-
|
87
|
+
command-line tool, if the command is the root command), the usage, a list of
|
88
88
|
aliases that can be used to call this command, a one-line summary and a (long)
|
89
89
|
description. The usage should not include a “usage:” prefix nor the name of
|
90
90
|
the supercommand, because the latter will be automatically prepended.
|
@@ -174,7 +174,7 @@ into manageable pieces.
|
|
174
174
|
|
175
175
|
=== Subcommands ===
|
176
176
|
|
177
|
-
Commands can have subcommands. For example, the `git`
|
177
|
+
Commands can have subcommands. For example, the `git` command-line tool would be
|
178
178
|
represented by a command that has subcommands named `commit`, `add`, and so on.
|
179
179
|
Commands with subcommands do not use a run block; execution will always be
|
180
180
|
dispatched to a subcommand (or none, if no subcommand is found).
|
data/Rakefile
CHANGED
@@ -22,8 +22,10 @@ task :test_unit do
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
RuboCop::RakeTask.new(:test_style)
|
25
|
+
RuboCop::RakeTask.new(:test_style) do |task|
|
26
|
+
task.options = %w(--display-cop-names --format simple)
|
27
|
+
end
|
26
28
|
|
27
|
-
task :
|
29
|
+
task test: [:test_unit, :test_style]
|
28
30
|
|
29
|
-
task :
|
31
|
+
task default: :test
|
data/cri.gemspec
CHANGED
@@ -7,8 +7,8 @@ Gem::Specification.new do |s|
|
|
7
7
|
s.name = 'cri'
|
8
8
|
s.version = Cri::VERSION
|
9
9
|
s.homepage = 'http://stoneship.org/software/cri/' # TODO: CREATE A WEB SITE YOU SILLY PERSON
|
10
|
-
s.summary = 'a library for building easy-to-use
|
11
|
-
s.description = 'Cri allows building easy-to-use
|
10
|
+
s.summary = 'a library for building easy-to-use command-line tools'
|
11
|
+
s.description = 'Cri allows building easy-to-use command-line interfaces with support for subcommands.'
|
12
12
|
s.license = 'MIT'
|
13
13
|
|
14
14
|
s.author = 'Denis Defreyne'
|
data/lib/cri.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
require 'cri/version'
|
4
2
|
|
5
|
-
# The namespace for Cri, a library for building easy-to-use
|
3
|
+
# The namespace for Cri, a library for building easy-to-use command-line tools
|
6
4
|
# with support for nested commands.
|
7
5
|
module Cri
|
8
6
|
# A generic error class for all Cri-specific errors.
|
data/lib/cri/argument_array.rb
CHANGED
data/lib/cri/command.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
module Cri
|
4
|
-
# Cri::Command represents a command that can be executed on the
|
5
|
-
# It is also used for the
|
2
|
+
# Cri::Command represents a command that can be executed on the command line.
|
3
|
+
# It is also used for the command-line tool itself.
|
6
4
|
class Command
|
7
5
|
# Delegate used for partitioning the list of arguments and options. This
|
8
6
|
# delegate will stop the parser as soon as the first argument, i.e. the
|
@@ -25,8 +23,7 @@ module Cri
|
|
25
23
|
# @param [Cri::OptionParser] option_parser The option parser
|
26
24
|
#
|
27
25
|
# @return [void]
|
28
|
-
def option_added(_key, _value, _option_parser)
|
29
|
-
end
|
26
|
+
def option_added(_key, _value, _option_parser); end
|
30
27
|
|
31
28
|
# Called when an argument is parsed.
|
32
29
|
#
|
@@ -47,7 +44,7 @@ module Cri
|
|
47
44
|
|
48
45
|
# @return [Set<Cri::Command>] This command’s subcommands
|
49
46
|
attr_accessor :commands
|
50
|
-
|
47
|
+
alias subcommands commands
|
51
48
|
|
52
49
|
# @return [String] The name
|
53
50
|
attr_accessor :name
|
@@ -69,7 +66,7 @@ module Cri
|
|
69
66
|
# @return [Boolean] true if the command is hidden (e.g. because it is
|
70
67
|
# deprecated), false otherwise
|
71
68
|
attr_accessor :hidden
|
72
|
-
|
69
|
+
alias hidden? hidden
|
73
70
|
|
74
71
|
# @return [Array<Hash>] The list of option definitions
|
75
72
|
attr_accessor :option_definitions
|
@@ -140,7 +137,7 @@ module Cri
|
|
140
137
|
if [-1, 0].include? block.arity
|
141
138
|
dsl.instance_eval(&block)
|
142
139
|
else
|
143
|
-
|
140
|
+
yield(dsl)
|
144
141
|
end
|
145
142
|
self
|
146
143
|
end
|
@@ -177,7 +174,7 @@ module Cri
|
|
177
174
|
if [-1, 0].include? block.arity
|
178
175
|
dsl.instance_eval(&block)
|
179
176
|
else
|
180
|
-
|
177
|
+
yield(dsl)
|
181
178
|
end
|
182
179
|
|
183
180
|
# Create command
|
@@ -217,19 +214,19 @@ module Cri
|
|
217
214
|
def command_named(name)
|
218
215
|
commands = commands_named(name)
|
219
216
|
|
220
|
-
if commands.
|
217
|
+
if commands.empty?
|
221
218
|
$stderr.puts "#{self.name}: unknown command '#{name}'\n"
|
222
219
|
exit 1
|
223
220
|
elsif commands.size > 1
|
224
221
|
$stderr.puts "#{self.name}: '#{name}' is ambiguous:"
|
225
|
-
$stderr.puts " #{commands.map
|
222
|
+
$stderr.puts " #{commands.map(&:name).sort.join(' ')}"
|
226
223
|
exit 1
|
227
224
|
else
|
228
225
|
commands[0]
|
229
226
|
end
|
230
227
|
end
|
231
228
|
|
232
|
-
# Runs the command with the given
|
229
|
+
# Runs the command with the given command-line arguments, possibly invoking
|
233
230
|
# subcommands and passing on the options and arguments.
|
234
231
|
#
|
235
232
|
# @param [Array<String>] opts_and_args A list of unparsed arguments
|
@@ -261,7 +258,7 @@ module Cri
|
|
261
258
|
end
|
262
259
|
end
|
263
260
|
|
264
|
-
# Runs the actual command with the given
|
261
|
+
# Runs the actual command with the given command-line arguments, not
|
265
262
|
# invoking any subcommands. If the command does not have an execution
|
266
263
|
# block, an error ir raised.
|
267
264
|
#
|
@@ -277,7 +274,8 @@ module Cri
|
|
277
274
|
def run_this(opts_and_args, parent_opts = {})
|
278
275
|
# Parse
|
279
276
|
parser = Cri::OptionParser.new(
|
280
|
-
opts_and_args, global_option_definitions
|
277
|
+
opts_and_args, global_option_definitions
|
278
|
+
)
|
281
279
|
handle_parser_errors_while { parser.run }
|
282
280
|
local_opts = parser.options
|
283
281
|
global_opts = parent_opts.merge(parser.options)
|
@@ -288,8 +286,8 @@ module Cri
|
|
288
286
|
|
289
287
|
# Execute
|
290
288
|
if block.nil?
|
291
|
-
|
292
|
-
|
289
|
+
raise NotImplementedError,
|
290
|
+
"No implementation available for '#{name}'"
|
293
291
|
end
|
294
292
|
block.call(global_opts, args, self)
|
295
293
|
end
|
@@ -341,8 +339,8 @@ module Cri
|
|
341
339
|
]
|
342
340
|
end
|
343
341
|
|
344
|
-
def handle_parser_errors_while
|
345
|
-
|
342
|
+
def handle_parser_errors_while
|
343
|
+
yield
|
346
344
|
rescue Cri::OptionParser::IllegalOptionError => e
|
347
345
|
$stderr.puts "#{name}: illegal option -- #{e}"
|
348
346
|
exit 1
|
data/lib/cri/command_dsl.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
module Cri
|
4
2
|
# The command DSL is a class that is used for building and modifying
|
5
3
|
# commands.
|
@@ -48,7 +46,7 @@ module Cri
|
|
48
46
|
#
|
49
47
|
# @return [void]
|
50
48
|
def aliases(*args)
|
51
|
-
@command.aliases = args.flatten.map
|
49
|
+
@command.aliases = args.flatten.map(&:to_s)
|
52
50
|
end
|
53
51
|
|
54
52
|
# Sets the command summary.
|
@@ -114,20 +112,20 @@ module Cri
|
|
114
112
|
hidden = params.fetch(:hidden, false)
|
115
113
|
|
116
114
|
if short.nil? && long.nil?
|
117
|
-
|
115
|
+
raise ArgumentError, 'short and long options cannot both be nil'
|
118
116
|
end
|
119
117
|
|
120
118
|
@command.option_definitions << {
|
121
|
-
:
|
122
|
-
:
|
123
|
-
:
|
124
|
-
:
|
125
|
-
:
|
126
|
-
:
|
127
|
-
:
|
119
|
+
short: short.nil? ? nil : short.to_s,
|
120
|
+
long: long.nil? ? nil : long.to_s,
|
121
|
+
desc: desc,
|
122
|
+
argument: requiredness,
|
123
|
+
multiple: multiple,
|
124
|
+
block: block,
|
125
|
+
hidden: hidden,
|
128
126
|
}
|
129
127
|
end
|
130
|
-
|
128
|
+
alias opt option
|
131
129
|
|
132
130
|
# Adds a new option with a required argument to the command. If a block is
|
133
131
|
# given, it will be executed when the option is successfully parsed.
|
@@ -148,7 +146,7 @@ module Cri
|
|
148
146
|
#
|
149
147
|
# @see {#option}
|
150
148
|
def required(short, long, desc, params = {}, &block)
|
151
|
-
params = params.merge(:
|
149
|
+
params = params.merge(argument: :required)
|
152
150
|
option(short, long, desc, params, &block)
|
153
151
|
end
|
154
152
|
|
@@ -171,10 +169,10 @@ module Cri
|
|
171
169
|
#
|
172
170
|
# @see {#option}
|
173
171
|
def flag(short, long, desc, params = {}, &block)
|
174
|
-
params = params.merge(:
|
172
|
+
params = params.merge(argument: :forbidden)
|
175
173
|
option(short, long, desc, params, &block)
|
176
174
|
end
|
177
|
-
|
175
|
+
alias forbidden flag
|
178
176
|
|
179
177
|
# Adds a new option with an optional argument to the command. If a block
|
180
178
|
# is given, it will be executed when the option is successfully parsed.
|
@@ -195,7 +193,7 @@ module Cri
|
|
195
193
|
#
|
196
194
|
# @see {#option}
|
197
195
|
def optional(short, long, desc, params = {}, &block)
|
198
|
-
params = params.merge(:
|
196
|
+
params = params.merge(argument: :optional)
|
199
197
|
option(short, long, desc, params, &block)
|
200
198
|
end
|
201
199
|
|
@@ -213,8 +211,8 @@ module Cri
|
|
213
211
|
# @return [void]
|
214
212
|
def run(&block)
|
215
213
|
unless [2, 3].include?(block.arity)
|
216
|
-
|
217
|
-
|
214
|
+
raise ArgumentError,
|
215
|
+
'The block given to Cri::Command#run expects two or three args'
|
218
216
|
end
|
219
217
|
|
220
218
|
@command.block = block
|
data/lib/cri/command_runner.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
module Cri
|
4
2
|
# A command runner is responsible for the execution of a command. Using it
|
5
3
|
# is optional, but it is useful for commands whose execution block is large.
|
@@ -40,7 +38,7 @@ module Cri
|
|
40
38
|
#
|
41
39
|
# @abstract
|
42
40
|
def run
|
43
|
-
|
41
|
+
raise NotImplementedError, 'Cri::CommandRunner subclasses must implement #run'
|
44
42
|
end
|
45
43
|
end
|
46
44
|
end
|
@@ -1,21 +1,19 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
name 'help'
|
4
2
|
usage 'help [command_name]'
|
5
3
|
summary 'show help'
|
6
4
|
description <<-EOS
|
7
5
|
Show help for the given command, or show general help. When no command is
|
8
6
|
given, a list of available commands is displayed, as well as a list of global
|
9
|
-
|
10
|
-
command-specific
|
7
|
+
command-line options. When a command is given, a command description, as well
|
8
|
+
as command-specific command-line options, are shown.
|
11
9
|
EOS
|
12
10
|
|
13
11
|
flag :v, :verbose, 'show more detailed help'
|
14
12
|
|
15
13
|
run do |opts, args, cmd|
|
16
14
|
if cmd.supercommand.nil?
|
17
|
-
|
18
|
-
|
15
|
+
raise NoHelpAvailableError,
|
16
|
+
'No help available because the help command has no supercommand'
|
19
17
|
end
|
20
18
|
|
21
19
|
is_verbose = opts.fetch(:verbose, false)
|
@@ -23,5 +21,5 @@ run do |opts, args, cmd|
|
|
23
21
|
resolved_cmd = args.inject(cmd.supercommand) do |acc, name|
|
24
22
|
acc.command_named(name)
|
25
23
|
end
|
26
|
-
puts resolved_cmd.help(:
|
24
|
+
puts resolved_cmd.help(verbose: is_verbose, io: $stdout)
|
27
25
|
end
|