clamp 1.2.0.beta1 → 1.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +5 -5
  2. data/.editorconfig +9 -0
  3. data/.gitignore +1 -1
  4. data/.rspec +1 -0
  5. data/.rubocop.yml +26 -19
  6. data/.travis.yml +3 -6
  7. data/CHANGES.md +17 -1
  8. data/Gemfile +8 -6
  9. data/Guardfile +3 -1
  10. data/README.md +36 -43
  11. data/Rakefile +8 -0
  12. data/clamp.gemspec +8 -6
  13. data/examples/admin +3 -2
  14. data/examples/defaulted +4 -3
  15. data/examples/flipflop +1 -0
  16. data/examples/fubar +1 -0
  17. data/examples/gitdown +2 -1
  18. data/examples/scoop +3 -2
  19. data/examples/speak +3 -2
  20. data/examples/subcommand_missing +1 -0
  21. data/examples/word +1 -0
  22. data/lib/clamp.rb +3 -1
  23. data/lib/clamp/attribute/declaration.rb +5 -0
  24. data/lib/clamp/attribute/definition.rb +25 -11
  25. data/lib/clamp/attribute/instance.rb +25 -3
  26. data/lib/clamp/command.rb +9 -1
  27. data/lib/clamp/errors.rb +7 -3
  28. data/lib/clamp/help.rb +38 -17
  29. data/lib/clamp/messages.rb +25 -15
  30. data/lib/clamp/option/declaration.rb +5 -1
  31. data/lib/clamp/option/definition.rb +9 -3
  32. data/lib/clamp/option/parsing.rb +38 -43
  33. data/lib/clamp/parameter/declaration.rb +4 -0
  34. data/lib/clamp/parameter/definition.rb +9 -3
  35. data/lib/clamp/parameter/parsing.rb +5 -1
  36. data/lib/clamp/subcommand/declaration.rb +17 -15
  37. data/lib/clamp/subcommand/definition.rb +5 -6
  38. data/lib/clamp/subcommand/execution.rb +12 -1
  39. data/lib/clamp/subcommand/parsing.rb +4 -0
  40. data/lib/clamp/truthy.rb +4 -2
  41. data/lib/clamp/version.rb +3 -1
  42. data/spec/clamp/command_group_spec.rb +29 -11
  43. data/spec/clamp/command_spec.rb +130 -48
  44. data/spec/clamp/help_spec.rb +63 -0
  45. data/spec/clamp/messages_spec.rb +5 -4
  46. data/spec/clamp/option/definition_spec.rb +13 -11
  47. data/spec/clamp/option_module_spec.rb +3 -1
  48. data/spec/clamp/option_reordering_spec.rb +6 -4
  49. data/spec/clamp/parameter/definition_spec.rb +14 -12
  50. data/spec/spec_helper.rb +3 -3
  51. metadata +9 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: aec7a5c34695b2517afb8215a0cbe8e9e4b2c8b9
4
- data.tar.gz: f20e0d18b9e4be570fc7ae1f349d4d022f0f7644
2
+ SHA256:
3
+ metadata.gz: c164c63137c57502ad15e11ab471b2607661868298e5330a8a4961dfea629537
4
+ data.tar.gz: 297e0abb1ead811d567eea7e668a91ba7c99654657a358016abb5cdbfd13168d
5
5
  SHA512:
6
- metadata.gz: 554f0e8fefe510adeacd74357333302d2f3ae9a4b98f87e0140956e4b35ff6f60b7b3031260b8cba2c2f96079b201ebc4c6256bed160d52038a079e7538defda
7
- data.tar.gz: 85d29744e560feb6c06096739df752128bd1df915237da53b1c7ea7150ade1d3516016eb3014c7fc1f2958fdcf2074c35e00d6aa64057a8c8c56c9c82094f879
6
+ metadata.gz: 3773151ffa64b908d26c569877bb27704bf68efe658d9b6ebd48c009bcbc1a4d0a3fce2c4f16a02ed379e126dd436ef018ff1eac56334fcc8f467402fad6c995
7
+ data.tar.gz: 8104ea9b1d9a42669234cb0d82cc441efd7a6f94ed5cba542a502ae1cb2797d977530a07bbe649d98dab551e9078b434711e091e9d0b3716799522c04436d8c9
@@ -0,0 +1,9 @@
1
+ root = true
2
+
3
+ [*]
4
+ indent_style = space
5
+ indent_size = 2
6
+ end_of_line = lf
7
+ charset = utf-8
8
+ trim_trailing_whitespace = true
9
+ insert_final_newline = true
data/.gitignore CHANGED
@@ -1,8 +1,8 @@
1
1
  *.gem
2
2
  .bundle
3
+ .markdownlint*
3
4
  .rvmrc
4
5
  .yardoc
5
6
  doc
6
7
  pkg/*
7
8
  Gemfile.lock
8
-
data/.rspec CHANGED
@@ -1 +1,2 @@
1
1
  --color
2
+ --warnings
@@ -1,17 +1,40 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.1
3
+
1
4
  Eval:
2
5
  Exclude:
3
6
  - "Rakefile"
4
7
 
8
+ Layout/EmptyLinesAroundBlockBody:
9
+ Enabled: false
10
+
11
+ Layout/EmptyLinesAroundClassBody:
12
+ EnforcedStyle: empty_lines
13
+
14
+ Layout/EmptyLinesAroundModuleBody:
15
+ Enabled: false
16
+
5
17
  Metrics/AbcSize:
6
18
  Enabled: false
7
19
 
20
+ Metrics/BlockLength:
21
+ Exclude:
22
+ - "spec/**/*"
23
+
8
24
  Metrics/LineLength:
9
25
  Max: 120
10
26
 
11
27
  Metrics/MethodLength:
12
28
  Max: 30
13
29
 
14
- Style/AccessorMethodName:
30
+ Naming/AccessorMethodName:
31
+ Enabled: false
32
+
33
+ Naming/FileName:
34
+ Exclude:
35
+ - "bin/*"
36
+
37
+ Naming/PredicateName:
15
38
  Enabled: false
16
39
 
17
40
  Style/ClassAndModuleChildren:
@@ -22,35 +45,19 @@ Style/ClassAndModuleChildren:
22
45
  Style/Documentation:
23
46
  Exclude:
24
47
  - "lib/**/version.rb"
48
+ - "examples/*"
25
49
  - "spec/**/*"
26
50
 
27
- Style/EmptyLinesAroundBlockBody:
28
- Enabled: false
29
-
30
- Style/EmptyLinesAroundClassBody:
31
- EnforcedStyle: empty_lines
32
-
33
- Style/EmptyLinesAroundModuleBody:
34
- Enabled: false
35
-
36
51
  Style/Encoding:
37
- EnforcedStyle: when_needed
38
52
  Enabled: true
39
53
 
40
- Style/FileName:
41
- Exclude:
42
- - "bin/*"
43
-
44
- Style/HashSyntax:
45
- EnforcedStyle: hash_rockets
46
-
47
54
  Style/Lambda:
48
55
  Enabled: false
49
56
 
50
57
  Style/NumericLiterals:
51
58
  Enabled: false
52
59
 
53
- Style/PredicateName:
60
+ Style/StderrPuts:
54
61
  Enabled: false
55
62
 
56
63
  Style/StringLiterals:
@@ -1,8 +1,5 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.1.8
4
- - 2.2.4
5
- - 2.3.1
6
- before_install:
7
- - gem update --system
8
- - gem install bundler
3
+ - 2.3
4
+ - 2.5
5
+ - 2.6
data/CHANGES.md CHANGED
@@ -1,6 +1,22 @@
1
1
  # Changelog
2
2
 
3
- ## PENDING
3
+ ## 1.3.2 (2020-08-20)
4
+
5
+ * Fix Ruby warnings.
6
+
7
+ ## 1.3.1 (2019-07-11)
8
+
9
+ * Choose a sensible column width in generated help, based on content.
10
+ * Fix issue#99: extraneous parameter names in subcommand help.
11
+
12
+ ## 1.3.0 (2018-06-17)
13
+
14
+ * Add `.execute` DSL method.
15
+ * Append '(required)' to the description of required options.
16
+ * Fix issue#75: don't generate `default_XXX` method unless a default is specified.
17
+ * Fix issue#90: allow required options to be provided after subcommands.
18
+
19
+ ## 1.2.0 (2018-02-12)
4
20
 
5
21
  * Add option to `Clamp.allow_options_after_parameters`.
6
22
 
data/Gemfile CHANGED
@@ -1,15 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source "http://rubygems.org"
2
4
 
3
5
  gemspec
4
6
 
5
7
  group :development do
6
- gem "guard-rspec", "~> 4.6.5", :require => false
7
- gem "listen", "~> 3.0.2"
8
- gem "rake", "~> 10.4"
9
- gem "rubocop", "~> 0.43.0", :require => false
8
+ gem "guard-rspec", "~> 4.7", require: false
9
+ gem "highline"
10
+ gem "listen", "~> 3.0"
11
+ gem "rake", "~> 12.3"
12
+ gem "rubocop", "~> 0.57.2", "<= 0.58", require: false
10
13
  end
11
14
 
12
15
  group :test do
13
- gem "rspec", "~> 3.5.0"
14
- gem "rr", "~> 1.2.0"
16
+ gem "rspec", "~> 3.7"
15
17
  end
data/Guardfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # A sample Guardfile
2
4
  # More info at https://github.com/guard/guard#readme
3
5
 
@@ -24,7 +26,7 @@
24
26
  # * zeus: 'zeus rspec' (requires the server to be started separately)
25
27
  # * 'just' rspec: 'rspec'
26
28
 
27
- guard :rspec, :cmd => "bundle exec rspec" do
29
+ guard :rspec, cmd: "bundle exec rspec" do
28
30
  require "guard/rspec/dsl"
29
31
  dsl = Guard::RSpec::Dsl.new(self)
30
32
 
data/README.md CHANGED
@@ -1,5 +1,4 @@
1
- Clamp
2
- =====
1
+ # Clamp
3
2
 
4
3
  [![Gem Version](https://badge.fury.io/rb/clamp.png)](http://badge.fury.io/rb/clamp)
5
4
  [![Build Status](https://secure.travis-ci.org/mdub/clamp.png?branch=master)](http://travis-ci.org/mdub/clamp)
@@ -8,8 +7,7 @@ Clamp
8
7
 
9
8
  It handles boring stuff like parsing the command-line, and generating help, so you can get on with making your command actually do stuff.
10
9
 
11
- Not another one!
12
- ----------------
10
+ ## Not another one!
13
11
 
14
12
  Yeah, sorry. There are a bunch of existing command-line parsing libraries out there, and Clamp draws inspiration from a variety of sources, including [Thor], [optparse], and [Clip]. In the end, though, I wanted a slightly rounder wheel. (Although, Clamp has a _lot_ in common with Ara T. Howard's [main.rb]. Had I been aware of that project at the time, I might not have written Clamp.)
15
13
 
@@ -18,8 +16,7 @@ Yeah, sorry. There are a bunch of existing command-line parsing libraries out t
18
16
  [Clip]: http://clip.rubyforge.org/
19
17
  [main.rb]: https://github.com/ahoward/main
20
18
 
21
- Quick Start
22
- -----------
19
+ ## Quick Start
23
20
 
24
21
  A typical Clamp script looks like this:
25
22
 
@@ -29,11 +26,11 @@ require 'clamp'
29
26
  Clamp do
30
27
 
31
28
  option "--loud", :flag, "say it loud"
32
- option ["-n", "--iterations"], "N", "say it N times", :default => 1 do |s|
29
+ option ["-n", "--iterations"], "N", "say it N times", default: 1 do |s|
33
30
  Integer(s)
34
31
  end
35
32
 
36
- parameter "WORDS ...", "the thing to say", :attribute_name => :words
33
+ parameter "WORDS ...", "the thing to say", attribute_name: :words
37
34
 
38
35
  def execute
39
36
  the_truth = words.join(" ")
@@ -54,11 +51,11 @@ require 'clamp'
54
51
  class SpeakCommand < Clamp::Command
55
52
 
56
53
  option "--loud", :flag, "say it loud"
57
- option ["-n", "--iterations"], "N", "say it N times", :default => 1 do |s|
54
+ option ["-n", "--iterations"], "N", "say it N times", default: 1 do |s|
58
55
  Integer(s)
59
56
  end
60
57
 
61
- parameter "WORDS ...", "the thing to say", :attribute_name => :words
58
+ parameter "WORDS ...", "the thing to say", attribute_name: :words
62
59
 
63
60
  def execute
64
61
  the_truth = words.join(" ")
@@ -79,8 +76,7 @@ There are more examples demonstrating various features of Clamp [on Github][exam
79
76
 
80
77
  [examples]: https://github.com/mdub/clamp/tree/master/examples
81
78
 
82
- Declaring options
83
- -----------------
79
+ ## Declaring options
84
80
 
85
81
  Options are declared using the `option` method. The three required arguments are:
86
82
 
@@ -105,7 +101,7 @@ end
105
101
  If you don't like the inferred attribute name, you can override it:
106
102
 
107
103
  ```ruby
108
- option "--type", "TYPE", "type of widget", :attribute_name => :widget_type
104
+ option "--type", "TYPE", "type of widget", attribute_name: :widget_type
109
105
  # to avoid clobbering Object#type
110
106
  ```
111
107
 
@@ -140,7 +136,7 @@ Clamp will handle both "`--force`" and "`--no-force`" options, setting the value
140
136
  Although "required option" is an oxymoron, Clamp lets you mark an option as required, and will verify that a value is provided:
141
137
 
142
138
  ```ruby
143
- option "--password", "PASSWORD", "the secret password", :required => true
139
+ option "--password", "PASSWORD", "the secret password", required: true
144
140
  ```
145
141
 
146
142
  Note that it makes no sense to mark a `:flag` option, or one with a `:default`, as `:required`.
@@ -150,7 +146,7 @@ Note that it makes no sense to mark a `:flag` option, or one with a `:default`,
150
146
  Declaring an option "`:multivalued`" allows it to be specified multiple times on the command line.
151
147
 
152
148
  ```ruby
153
- option "--format", "FORMAT", "output format", :multivalued => true
149
+ option "--format", "FORMAT", "output format", multivalued: true
154
150
  ```
155
151
 
156
152
  The underlying attribute becomes an Array, and the suffix "`_list`" is appended to the default attribute name. In this case, an attribute called "`format_list`" would be generated (unless you override the default by specifying an `:attribute_name`).
@@ -160,12 +156,12 @@ The underlying attribute becomes an Array, and the suffix "`_list`" is appended
160
156
  Declaring an option "`:hidden`" will cause it to be hidden from `--help` output.
161
157
 
162
158
  ```ruby
163
- option "--some-option", "VALUE", "Just a little option", :hidden => true
159
+ option "--some-option", "VALUE", "Just a little option", hidden: true
164
160
  ```
165
161
 
166
162
  ### Version option
167
163
 
168
- A common idiom is to have an option `--version` that outputs the command version and doesn't run any subcommands. This can be acheived by:
164
+ A common idiom is to have an option `--version` that outputs the command version and doesn't run any subcommands. This can be achieved by:
169
165
 
170
166
  ```ruby
171
167
  option "--version", :flag, "Show version" do
@@ -174,8 +170,7 @@ option "--version", :flag, "Show version" do
174
170
  end
175
171
  ```
176
172
 
177
- Declaring parameters
178
- --------------------
173
+ ## Declaring parameters
179
174
 
180
175
  Positional parameters can be declared using `parameter`, specifying
181
176
 
@@ -203,13 +198,12 @@ parameter "[TARGET_DIR]", "target directory"
203
198
  Three dots at the end of a parameter name makes it "greedy" - it will consume all remaining command-line arguments. For example:
204
199
 
205
200
  ```ruby
206
- parameter "FILE ...", "input files", :attribute_name => :files
201
+ parameter "FILE ...", "input files", attribute_name: :files
207
202
  ```
208
203
 
209
204
  Like multivalued options, greedy parameters are backed by an Array attribute (named with a "`_list`" suffix, by default).
210
205
 
211
- Parsing and validation of options and parameters
212
- ------------------------------------------------
206
+ ## Parsing and validation of options and parameters
213
207
 
214
208
  When you `#run` a command, it will first attempt to `#parse` command-line arguments, and map them onto the declared options and parameters, before invoking your `#execute` method.
215
209
 
@@ -265,15 +259,15 @@ end
265
259
  Default values can be specified for options, and optional parameters:
266
260
 
267
261
  ```ruby
268
- option "--flavour", "FLAVOUR", "ice-cream flavour", :default => "chocolate"
262
+ option "--flavour", "FLAVOUR", "ice-cream flavour", default: "chocolate"
269
263
 
270
- parameter "[HOST]", "server host", :default => "localhost"
264
+ parameter "[HOST]", "server host", default: "localhost"
271
265
  ```
272
266
 
273
267
  For more advanced cases, you can also specify default values by defining a method called "`default_#{attribute_name}`":
274
268
 
275
269
  ```ruby
276
- option "--http-port", "PORT", "web-server port", :default => 9000
270
+ option "--http-port", "PORT", "web-server port", default: 9000
277
271
 
278
272
  option "--admin-port", "PORT", "admin port"
279
273
 
@@ -287,29 +281,30 @@ end
287
281
  Options (and optional parameters) can also be associated with environment variables:
288
282
 
289
283
  ```ruby
290
- option "--port", "PORT", "the port to listen on", :environment_variable => "MYAPP_PORT" do |val|
284
+ option "--port", "PORT", "the port to listen on", environment_variable: "MYAPP_PORT" do |val|
291
285
  val.to_i
292
286
  end
293
287
 
294
- parameter "[HOST]", "server address", :environment_variable => "MYAPP_HOST"
288
+ parameter "[HOST]", "server address", environment_variable: "MYAPP_HOST"
295
289
  ```
296
290
 
297
291
  Clamp will check the specified envariables in the absence of values supplied on the command line, before looking for a default value.
298
292
 
299
293
  ### Allowing options after parameters
300
294
 
301
- Many option-parsing libraries - notably [GNU `getopt(3)`](https://www.gnu.org/software/libc/manual/html_node/Using-Getopt.html) - allow option and parameter arguments to appear in any order on the command-line, e.g.
295
+ By default, Clamp only recognises options _before_ positional parameters.
296
+
297
+ Some other option-parsing libraries - notably [GNU `getopt(3)`](https://www.gnu.org/software/libc/manual/html_node/Using-Getopt.html) - allow option and parameter arguments to appear in any order on the command-line, e.g.
302
298
 
303
299
  foobar --foo=bar something --fnord=snuffle another-thing
304
300
 
305
- By default, Clamp does not allow options and parameters to be "interspersed" in this way. If you want that behaviour, set:
301
+ If you want Clamp to allow options and parameters to be "interspersed" in this way, set:
306
302
 
307
303
  ```ruby
308
304
  Clamp.allow_options_after_parameters = true
309
305
  ```
310
306
 
311
- Declaring Subcommands
312
- ---------------------
307
+ ## Declaring Subcommands
313
308
 
314
309
  Subcommand support helps you wrap a number of related commands into a single script (ala tools like "`git`"). Clamp will inspect the first command-line argument (after options are parsed), and delegate to the named subcommand.
315
310
 
@@ -400,8 +395,7 @@ Clamp do
400
395
  end
401
396
  ```
402
397
 
403
- Getting help
404
- ------------
398
+ ## Getting help
405
399
 
406
400
  All Clamp commands support a "`--help`" option, which outputs brief usage documentation, based on those seemingly useless extra parameters that you had to pass to `option` and `parameter`.
407
401
 
@@ -419,27 +413,27 @@ Options:
419
413
  -h, --help print help
420
414
  ```
421
415
 
422
- Localization
423
- ------------
416
+ ## Localization
424
417
 
425
418
  Clamp comes with support for overriding strings with custom translations. You can use localization library of your choice and override the strings at startup.
426
419
 
427
420
  Example usage:
421
+
428
422
  ```ruby
429
423
  require 'gettext'
430
424
 
431
425
  Clamp.messages = {
432
- :too_many_arguments => _("too many arguments"),
433
- :option_required => _("option '%<option>s' is required"),
434
- :option_or_env_required => _("option '%<option>s' (or env %<env>s) is required"),
435
- :option_argument_error => _("option '%<switch>s': %<message>s")
426
+ too_many_arguments: _("too many arguments"),
427
+ option_required: _("option '%<option>s' is required"),
428
+ option_or_env_required: _("option '%<option>s' (or env %<env>s) is required"),
429
+ option_argument_error: _("option '%<switch>s': %<message>s")
436
430
  # ...
437
431
  }
438
432
  ```
433
+
439
434
  See [messages.rb](https://github.com/mdub/clamp/blob/master/lib/clamp/messages.rb) for full list of available messages.
440
435
 
441
- License
442
- -------
436
+ ## License
443
437
 
444
438
  Copyright (C) 2011 [Mike Williams](mailto:mdub@dogbiscuit.org)
445
439
 
@@ -460,7 +454,6 @@ THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
460
454
  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
461
455
  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
462
456
 
463
- Contributing to Clamp
464
- ---------------------
457
+ ## Contributing to Clamp
465
458
 
466
459
  Source-code for Clamp is [on Github](https://github.com/mdub/clamp).
data/Rakefile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "bundler"
2
4
 
3
5
  Bundler::GemHelper.install_tasks
@@ -10,3 +12,9 @@ RSpec::Core::RakeTask.new do |t|
10
12
  t.pattern = "spec/**/*_spec.rb"
11
13
  t.rspec_opts = ["--colour", "--format", "documentation"]
12
14
  end
15
+
16
+ require "rubocop/rake_task"
17
+
18
+ RuboCop::RakeTask.new
19
+
20
+ task "default" => "rubocop"
@@ -1,4 +1,6 @@
1
- $LOAD_PATH.push File.expand_path("../lib", __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.push File.expand_path("lib", __dir__)
2
4
  require "clamp/version"
3
5
 
4
6
  Gem::Specification.new do |s|
@@ -8,15 +10,15 @@ Gem::Specification.new do |s|
8
10
  s.platform = Gem::Platform::RUBY
9
11
  s.authors = ["Mike Williams"]
10
12
  s.email = "mdub@dogbiscuit.org"
11
- s.homepage = "http://github.com/mdub/clamp"
13
+ s.homepage = "https://github.com/mdub/clamp"
12
14
 
13
15
  s.license = "MIT"
14
16
 
15
17
  s.summary = "a minimal framework for command-line utilities"
16
- s.description = <<EOF
17
- Clamp provides an object-model for command-line utilities.
18
- It handles parsing of command-line options, and generation of usage help.
19
- EOF
18
+ s.description = <<-TEXT.gsub(/^\s+/, "")
19
+ Clamp provides an object-model for command-line utilities.
20
+ It handles parsing of command-line options, and generation of usage help.
21
+ TEXT
20
22
 
21
23
  s.files = `git ls-files`.split("\n")
22
24
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")