clamp 1.3.0 → 1.3.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +1 -1
- data/CHANGES.md +5 -0
- data/Gemfile +1 -1
- data/README.md +33 -42
- data/lib/clamp/help.rb +30 -11
- data/lib/clamp/subcommand/execution.rb +1 -1
- data/lib/clamp/version.rb +1 -1
- data/spec/clamp/command_group_spec.rb +2 -2
- data/spec/clamp/command_spec.rb +13 -0
- data/spec/clamp/help_spec.rb +63 -0
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: c397bb4c7fbc93ee71f4df0dbeaf3513e0372dcbe12ed0ace0b89ac54bd932de
|
4
|
+
data.tar.gz: 28088d25dd5a855aca74a77caa3172b2b30259e33fc5223a1d302fe4a302ef2a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4ee42ec998257b428af64d243b0a89f7345bbe9aad098414a9a99a53d53007489036bc7c4c8d7d03bb53f4bbaecf095e1c0d60860faec50b5b5b67bfafe4cf5f
|
7
|
+
data.tar.gz: d7bd94bbea00c26fca7d388411959c92a864399b9c89c907a07008a10cc326c9eedb553091caa0602771a367e81baded339ed6bba5a86da80ee5a116dc977f5b
|
data/.gitignore
CHANGED
data/CHANGES.md
CHANGED
data/Gemfile
CHANGED
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", :
|
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", :
|
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", :
|
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", :
|
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", :
|
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", :
|
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", :
|
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", :
|
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
|
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", :
|
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", :
|
262
|
+
option "--flavour", "FLAVOUR", "ice-cream flavour", default: "chocolate"
|
269
263
|
|
270
|
-
parameter "[HOST]", "server host", :
|
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", :
|
270
|
+
option "--http-port", "PORT", "web-server port", default: 9000
|
277
271
|
|
278
272
|
option "--admin-port", "PORT", "admin port"
|
279
273
|
|
@@ -287,18 +281,18 @@ 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", :
|
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", :
|
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
|
-
By default, Clamp only recognises options _before_ positional parameters.
|
295
|
+
By default, Clamp only recognises options _before_ positional parameters.
|
302
296
|
|
303
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.
|
304
298
|
|
@@ -310,8 +304,7 @@ If you want Clamp to allow options and parameters to be "interspersed" in this w
|
|
310
304
|
Clamp.allow_options_after_parameters = true
|
311
305
|
```
|
312
306
|
|
313
|
-
Declaring Subcommands
|
314
|
-
---------------------
|
307
|
+
## Declaring Subcommands
|
315
308
|
|
316
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.
|
317
310
|
|
@@ -402,8 +395,7 @@ Clamp do
|
|
402
395
|
end
|
403
396
|
```
|
404
397
|
|
405
|
-
Getting help
|
406
|
-
------------
|
398
|
+
## Getting help
|
407
399
|
|
408
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`.
|
409
401
|
|
@@ -421,27 +413,27 @@ Options:
|
|
421
413
|
-h, --help print help
|
422
414
|
```
|
423
415
|
|
424
|
-
Localization
|
425
|
-
------------
|
416
|
+
## Localization
|
426
417
|
|
427
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.
|
428
419
|
|
429
420
|
Example usage:
|
421
|
+
|
430
422
|
```ruby
|
431
423
|
require 'gettext'
|
432
424
|
|
433
425
|
Clamp.messages = {
|
434
|
-
:
|
435
|
-
:
|
436
|
-
:
|
437
|
-
:
|
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")
|
438
430
|
# ...
|
439
431
|
}
|
440
432
|
```
|
433
|
+
|
441
434
|
See [messages.rb](https://github.com/mdub/clamp/blob/master/lib/clamp/messages.rb) for full list of available messages.
|
442
435
|
|
443
|
-
License
|
444
|
-
-------
|
436
|
+
## License
|
445
437
|
|
446
438
|
Copyright (C) 2011 [Mike Williams](mailto:mdub@dogbiscuit.org)
|
447
439
|
|
@@ -462,7 +454,6 @@ THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
462
454
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
463
455
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
464
456
|
|
465
|
-
Contributing to Clamp
|
466
|
-
---------------------
|
457
|
+
## Contributing to Clamp
|
467
458
|
|
468
459
|
Source-code for Clamp is [on Github](https://github.com/mdub/clamp).
|
data/lib/clamp/help.rb
CHANGED
@@ -56,34 +56,55 @@ module Clamp
|
|
56
56
|
class Builder
|
57
57
|
|
58
58
|
def initialize
|
59
|
-
@
|
59
|
+
@lines = []
|
60
60
|
end
|
61
61
|
|
62
62
|
def string
|
63
|
-
|
63
|
+
left_column_width = lines.grep(Array).map(&:first).map(&:size).max
|
64
|
+
StringIO.new.tap do |out|
|
65
|
+
lines.each do |line|
|
66
|
+
case line
|
67
|
+
when Array
|
68
|
+
line[0] = line[0].ljust(left_column_width)
|
69
|
+
line.unshift("")
|
70
|
+
out.puts(line.join(" "))
|
71
|
+
else
|
72
|
+
out.puts(line)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end.string
|
76
|
+
end
|
77
|
+
|
78
|
+
def line(text = "")
|
79
|
+
@lines << text
|
80
|
+
end
|
81
|
+
|
82
|
+
def row(lhs, rhs)
|
83
|
+
@lines << [lhs, rhs]
|
64
84
|
end
|
65
85
|
|
66
86
|
def add_usage(invocation_path, usage_descriptions)
|
67
|
-
|
87
|
+
line Clamp.message(:usage_heading) + ":"
|
68
88
|
usage_descriptions.each do |usage|
|
69
|
-
|
89
|
+
line " #{invocation_path} #{usage}".rstrip
|
70
90
|
end
|
71
91
|
end
|
72
92
|
|
73
93
|
def add_description(description)
|
74
94
|
return unless description
|
75
|
-
|
76
|
-
|
95
|
+
line
|
96
|
+
line description.gsub(/^/, " ")
|
77
97
|
end
|
78
98
|
|
79
99
|
DETAIL_FORMAT = " %-29s %s".freeze
|
80
100
|
|
81
101
|
def add_list(heading, items)
|
82
|
-
|
102
|
+
line
|
103
|
+
line "#{heading}:"
|
83
104
|
items.reject { |i| i.respond_to?(:hidden?) && i.hidden? }.each do |item|
|
84
105
|
label, description = item.help
|
85
106
|
description.each_line do |line|
|
86
|
-
|
107
|
+
row(label, line)
|
87
108
|
label = ""
|
88
109
|
end
|
89
110
|
end
|
@@ -91,9 +112,7 @@ module Clamp
|
|
91
112
|
|
92
113
|
private
|
93
114
|
|
94
|
-
|
95
|
-
@out.puts(*args)
|
96
|
-
end
|
115
|
+
attr_accessor :lines
|
97
116
|
|
98
117
|
end
|
99
118
|
|
data/lib/clamp/version.rb
CHANGED
@@ -261,9 +261,9 @@ describe Clamp::Command do
|
|
261
261
|
|
262
262
|
it "shows parameter in usage help" do
|
263
263
|
begin
|
264
|
-
command.run(["stuff", "say", "--help"])
|
264
|
+
command.run(["stuff", "say", "loud", "--help"])
|
265
265
|
rescue Clamp::HelpWanted => e
|
266
|
-
expect(e.command.invocation_path).to eql("with THING say")
|
266
|
+
expect(e.command.invocation_path).to eql("with THING say loud")
|
267
267
|
end
|
268
268
|
end
|
269
269
|
|
data/spec/clamp/command_spec.rb
CHANGED
@@ -435,6 +435,19 @@ describe Clamp::Command do
|
|
435
435
|
|
436
436
|
end
|
437
437
|
|
438
|
+
context "with option arguments that look like options" do
|
439
|
+
|
440
|
+
before do
|
441
|
+
command.parse(%w[--flavour=-dashing- --scoops -1])
|
442
|
+
end
|
443
|
+
|
444
|
+
it "sets the options" do
|
445
|
+
expect(command.flavour).to eq("-dashing-")
|
446
|
+
expect(command.scoops).to eq(-1)
|
447
|
+
end
|
448
|
+
|
449
|
+
end
|
450
|
+
|
438
451
|
context "with option-like things beyond the arguments" do
|
439
452
|
|
440
453
|
it "treats them as positional arguments" do
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
describe Clamp::Help::Builder do
|
6
|
+
|
7
|
+
subject(:builder) { described_class.new }
|
8
|
+
|
9
|
+
def output
|
10
|
+
builder.string
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "#line" do
|
14
|
+
|
15
|
+
it "adds a line of text" do
|
16
|
+
builder.line("blah")
|
17
|
+
expect(output).to eq("blah\n")
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#row" do
|
23
|
+
|
24
|
+
it "adds two strings separated by spaces" do
|
25
|
+
builder.row("LHS", "RHS")
|
26
|
+
expect(output).to eq(" LHS RHS\n")
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
context "with multiple rows" do
|
32
|
+
|
33
|
+
it "arranges them in two columns" do
|
34
|
+
builder.row("foo", "bar")
|
35
|
+
builder.row("flibble", "blurk")
|
36
|
+
builder.row("x", "y")
|
37
|
+
expect(output.lines).to eq [
|
38
|
+
" foo bar\n",
|
39
|
+
" flibble blurk\n",
|
40
|
+
" x y\n"
|
41
|
+
]
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
context "with a mixture of lines and rows" do
|
47
|
+
|
48
|
+
it "still arranges them in two columns" do
|
49
|
+
builder.line("ABCDEFGHIJKLMNOP")
|
50
|
+
builder.row("flibble", "blurk")
|
51
|
+
builder.line("Another section heading")
|
52
|
+
builder.row("x", "y")
|
53
|
+
expect(output.lines).to eq [
|
54
|
+
"ABCDEFGHIJKLMNOP\n",
|
55
|
+
" flibble blurk\n",
|
56
|
+
"Another section heading\n",
|
57
|
+
" x y\n"
|
58
|
+
]
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: clamp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Williams
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-07-11 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |
|
14
14
|
Clamp provides an object-model for command-line utilities.
|
@@ -61,6 +61,7 @@ files:
|
|
61
61
|
- lib/clamp/version.rb
|
62
62
|
- spec/clamp/command_group_spec.rb
|
63
63
|
- spec/clamp/command_spec.rb
|
64
|
+
- spec/clamp/help_spec.rb
|
64
65
|
- spec/clamp/messages_spec.rb
|
65
66
|
- spec/clamp/option/definition_spec.rb
|
66
67
|
- spec/clamp/option_module_spec.rb
|
@@ -87,13 +88,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
87
88
|
version: '0'
|
88
89
|
requirements: []
|
89
90
|
rubyforge_project:
|
90
|
-
rubygems_version: 2.
|
91
|
+
rubygems_version: 2.7.6
|
91
92
|
signing_key:
|
92
93
|
specification_version: 4
|
93
94
|
summary: a minimal framework for command-line utilities
|
94
95
|
test_files:
|
95
96
|
- spec/clamp/command_group_spec.rb
|
96
97
|
- spec/clamp/command_spec.rb
|
98
|
+
- spec/clamp/help_spec.rb
|
97
99
|
- spec/clamp/messages_spec.rb
|
98
100
|
- spec/clamp/option/definition_spec.rb
|
99
101
|
- spec/clamp/option_module_spec.rb
|