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.
- checksums.yaml +5 -5
- data/.editorconfig +9 -0
- data/.gitignore +1 -1
- data/.rspec +1 -0
- data/.rubocop.yml +26 -19
- data/.travis.yml +3 -6
- data/CHANGES.md +17 -1
- data/Gemfile +8 -6
- data/Guardfile +3 -1
- data/README.md +36 -43
- data/Rakefile +8 -0
- data/clamp.gemspec +8 -6
- data/examples/admin +3 -2
- data/examples/defaulted +4 -3
- data/examples/flipflop +1 -0
- data/examples/fubar +1 -0
- data/examples/gitdown +2 -1
- data/examples/scoop +3 -2
- data/examples/speak +3 -2
- data/examples/subcommand_missing +1 -0
- data/examples/word +1 -0
- data/lib/clamp.rb +3 -1
- data/lib/clamp/attribute/declaration.rb +5 -0
- data/lib/clamp/attribute/definition.rb +25 -11
- data/lib/clamp/attribute/instance.rb +25 -3
- data/lib/clamp/command.rb +9 -1
- data/lib/clamp/errors.rb +7 -3
- data/lib/clamp/help.rb +38 -17
- data/lib/clamp/messages.rb +25 -15
- data/lib/clamp/option/declaration.rb +5 -1
- data/lib/clamp/option/definition.rb +9 -3
- data/lib/clamp/option/parsing.rb +38 -43
- data/lib/clamp/parameter/declaration.rb +4 -0
- data/lib/clamp/parameter/definition.rb +9 -3
- data/lib/clamp/parameter/parsing.rb +5 -1
- data/lib/clamp/subcommand/declaration.rb +17 -15
- data/lib/clamp/subcommand/definition.rb +5 -6
- data/lib/clamp/subcommand/execution.rb +12 -1
- data/lib/clamp/subcommand/parsing.rb +4 -0
- data/lib/clamp/truthy.rb +4 -2
- data/lib/clamp/version.rb +3 -1
- data/spec/clamp/command_group_spec.rb +29 -11
- data/spec/clamp/command_spec.rb +130 -48
- data/spec/clamp/help_spec.rb +63 -0
- data/spec/clamp/messages_spec.rb +5 -4
- data/spec/clamp/option/definition_spec.rb +13 -11
- data/spec/clamp/option_module_spec.rb +3 -1
- data/spec/clamp/option_reordering_spec.rb +6 -4
- data/spec/clamp/parameter/definition_spec.rb +14 -12
- data/spec/spec_helper.rb +3 -3
- metadata +9 -7
@@ -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
|
data/spec/clamp/messages_spec.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
3
|
require "spec_helper"
|
3
4
|
|
@@ -6,8 +7,8 @@ describe Clamp::Messages do
|
|
6
7
|
describe "message" do
|
7
8
|
before do
|
8
9
|
Clamp.messages = {
|
9
|
-
:
|
10
|
-
:
|
10
|
+
too_many_arguments: "Way too many!",
|
11
|
+
custom_message: "Say %<what>s to %<whom>s"
|
11
12
|
}
|
12
13
|
end
|
13
14
|
|
@@ -24,7 +25,7 @@ describe Clamp::Messages do
|
|
24
25
|
end
|
25
26
|
|
26
27
|
it "formats the message" do
|
27
|
-
expect(Clamp.message(:custom_message, :
|
28
|
+
expect(Clamp.message(:custom_message, what: "hello", whom: "Clamp")).to eql "Say hello to Clamp"
|
28
29
|
end
|
29
30
|
end
|
30
31
|
|
@@ -33,7 +34,7 @@ describe Clamp::Messages do
|
|
33
34
|
default_msg = Clamp.message(:too_many_arguments).clone
|
34
35
|
|
35
36
|
Clamp.messages = {
|
36
|
-
:
|
37
|
+
too_many_arguments: "Way too many!"
|
37
38
|
}
|
38
39
|
Clamp.clear_messages!
|
39
40
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "spec_helper"
|
2
4
|
|
3
5
|
describe Clamp::Option::Definition do
|
@@ -27,7 +29,7 @@ describe Clamp::Option::Definition do
|
|
27
29
|
end
|
28
30
|
|
29
31
|
it "can be overridden" do
|
30
|
-
option = described_class.new("--key-file", "FILE", "SSH identity", :
|
32
|
+
option = described_class.new("--key-file", "FILE", "SSH identity", attribute_name: "ssh_identity")
|
31
33
|
expect(option.attribute_name).to eql "ssh_identity"
|
32
34
|
end
|
33
35
|
|
@@ -49,7 +51,7 @@ describe Clamp::Option::Definition do
|
|
49
51
|
end
|
50
52
|
|
51
53
|
it "can be overridden" do
|
52
|
-
option = described_class.new("-n", "N", "iterations", :
|
54
|
+
option = described_class.new("-n", "N", "iterations", default: 1)
|
53
55
|
expect(option.default_value).to eql 1
|
54
56
|
end
|
55
57
|
|
@@ -149,7 +151,7 @@ describe Clamp::Option::Definition do
|
|
149
151
|
context "with an associated environment variable" do
|
150
152
|
|
151
153
|
let(:option) do
|
152
|
-
described_class.new("-x", "X", "mystery option", :
|
154
|
+
described_class.new("-x", "X", "mystery option", environment_variable: "APP_X")
|
153
155
|
end
|
154
156
|
|
155
157
|
describe "#help" do
|
@@ -163,7 +165,7 @@ describe Clamp::Option::Definition do
|
|
163
165
|
context "and a default value" do
|
164
166
|
|
165
167
|
let(:option) do
|
166
|
-
described_class.new("-x", "X", "mystery option", :
|
168
|
+
described_class.new("-x", "X", "mystery option", environment_variable: "APP_X", default: "xyz")
|
167
169
|
end
|
168
170
|
|
169
171
|
describe "#help" do
|
@@ -181,7 +183,7 @@ describe Clamp::Option::Definition do
|
|
181
183
|
context "multivalued" do
|
182
184
|
|
183
185
|
let(:option) do
|
184
|
-
described_class.new(["-H", "--header"], "HEADER", "extra header", :
|
186
|
+
described_class.new(["-H", "--header"], "HEADER", "extra header", multivalued: true)
|
185
187
|
end
|
186
188
|
|
187
189
|
it "is multivalued" do
|
@@ -195,7 +197,7 @@ describe Clamp::Option::Definition do
|
|
195
197
|
end
|
196
198
|
|
197
199
|
it "can be overridden" do
|
198
|
-
option = described_class.new("-H", "HEADER", "extra header", :
|
200
|
+
option = described_class.new("-H", "HEADER", "extra header", multivalued: true, default: [1, 2, 3])
|
199
201
|
expect(option.default_value).to eql [1, 2, 3]
|
200
202
|
end
|
201
203
|
|
@@ -247,19 +249,19 @@ describe Clamp::Option::Definition do
|
|
247
249
|
it "rejects :default" do
|
248
250
|
expect do
|
249
251
|
described_class.new("--key-file", "FILE", "SSH identity",
|
250
|
-
:
|
252
|
+
required: true, default: "hello")
|
251
253
|
end.to raise_error(ArgumentError)
|
252
254
|
end
|
253
255
|
|
254
256
|
it "rejects :flag options" do
|
255
257
|
expect do
|
256
|
-
described_class.new("--awesome", :flag, "Be awesome?", :
|
258
|
+
described_class.new("--awesome", :flag, "Be awesome?", required: true)
|
257
259
|
end.to raise_error(ArgumentError)
|
258
260
|
end
|
259
261
|
end
|
260
262
|
|
261
263
|
describe "a hidden option" do
|
262
|
-
let(:option) { described_class.new("--unseen", :flag, "Something", :
|
264
|
+
let(:option) { described_class.new("--unseen", :flag, "Something", hidden: true) }
|
263
265
|
it "is hidden" do
|
264
266
|
expect(option).to be_hidden
|
265
267
|
end
|
@@ -268,7 +270,7 @@ describe Clamp::Option::Definition do
|
|
268
270
|
describe "a hidden option in a command" do
|
269
271
|
let(:command_class) do
|
270
272
|
Class.new(Clamp::Command) do
|
271
|
-
option "--unseen", :flag, "Something", :
|
273
|
+
option "--unseen", :flag, "Something", hidden: true
|
272
274
|
|
273
275
|
def execute
|
274
276
|
# this space intentionally left blank
|
@@ -277,7 +279,7 @@ describe Clamp::Option::Definition do
|
|
277
279
|
end
|
278
280
|
|
279
281
|
it "is not shown in the help" do
|
280
|
-
expect(command_class.help("foo")).not_to match
|
282
|
+
expect(command_class.help("foo")).not_to match(/^ +--unseen +Something$/)
|
281
283
|
end
|
282
284
|
|
283
285
|
it "sets the expected accessor" do
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "spec_helper"
|
2
4
|
|
3
5
|
describe Clamp::Command do
|
@@ -10,7 +12,7 @@ describe Clamp::Command do
|
|
10
12
|
|
11
13
|
shared_options = Module.new do
|
12
14
|
extend Clamp::Option::Declaration
|
13
|
-
option "--size", "SIZE", :
|
15
|
+
option "--size", "SIZE", default: 4
|
14
16
|
end
|
15
17
|
|
16
18
|
command_class = Class.new(Clamp::Command) do
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "spec_helper"
|
2
4
|
|
3
5
|
describe Clamp::Command do
|
@@ -23,7 +25,7 @@ describe Clamp::Command do
|
|
23
25
|
|
24
26
|
option "--loud", :flag, "say it loud"
|
25
27
|
|
26
|
-
parameter "WORDS ...", "the thing to say", :
|
28
|
+
parameter "WORDS ...", "the thing to say", attribute_name: :words
|
27
29
|
|
28
30
|
def execute
|
29
31
|
message = words.join(" ")
|
@@ -37,17 +39,17 @@ describe Clamp::Command do
|
|
37
39
|
end
|
38
40
|
|
39
41
|
it "still works" do
|
40
|
-
command.run(%w
|
42
|
+
command.run(%w[say foo])
|
41
43
|
expect(stdout).to eql("foo\n")
|
42
44
|
end
|
43
45
|
|
44
46
|
it "honours options after positional arguments" do
|
45
|
-
command.run(%w
|
47
|
+
command.run(%w[say blah --verbose])
|
46
48
|
expect(stdout).to eql("blahblahblah\n")
|
47
49
|
end
|
48
50
|
|
49
51
|
it "honours options declared on subcommands" do
|
50
|
-
command.run(%w
|
52
|
+
command.run(%w[say --loud blah])
|
51
53
|
expect(stdout).to eql("BLAH\n")
|
52
54
|
end
|
53
55
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "spec_helper"
|
2
4
|
|
3
5
|
describe Clamp::Parameter::Definition do
|
@@ -27,7 +29,7 @@ describe Clamp::Parameter::Definition do
|
|
27
29
|
end
|
28
30
|
|
29
31
|
it "can be overridden" do
|
30
|
-
parameter = described_class.new("COLOR", "hue of choice", :
|
32
|
+
parameter = described_class.new("COLOR", "hue of choice", attribute_name: "hue")
|
31
33
|
expect(parameter.attribute_name).to eql "hue"
|
32
34
|
end
|
33
35
|
|
@@ -36,9 +38,9 @@ describe Clamp::Parameter::Definition do
|
|
36
38
|
describe "#consume" do
|
37
39
|
|
38
40
|
it "consumes one argument" do
|
39
|
-
arguments = %w
|
41
|
+
arguments = %w[a b c]
|
40
42
|
expect(parameter.consume(arguments)).to eql ["a"]
|
41
|
-
expect(arguments).to eql %w
|
43
|
+
expect(arguments).to eql %w[b c]
|
42
44
|
end
|
43
45
|
|
44
46
|
describe "with no arguments" do
|
@@ -77,9 +79,9 @@ describe Clamp::Parameter::Definition do
|
|
77
79
|
describe "#consume" do
|
78
80
|
|
79
81
|
it "consumes one argument" do
|
80
|
-
arguments = %w
|
82
|
+
arguments = %w[a b c]
|
81
83
|
expect(parameter.consume(arguments)).to eql ["a"]
|
82
|
-
expect(arguments).to eql %w
|
84
|
+
expect(arguments).to eql %w[b c]
|
83
85
|
end
|
84
86
|
|
85
87
|
describe "with no arguments" do
|
@@ -124,8 +126,8 @@ describe Clamp::Parameter::Definition do
|
|
124
126
|
describe "#consume" do
|
125
127
|
|
126
128
|
it "consumes all the remaining arguments" do
|
127
|
-
arguments = %w
|
128
|
-
expect(parameter.consume(arguments)).to eql %w
|
129
|
+
arguments = %w[a b c]
|
130
|
+
expect(parameter.consume(arguments)).to eql %w[a b c]
|
129
131
|
expect(arguments).to eql []
|
130
132
|
end
|
131
133
|
|
@@ -145,7 +147,7 @@ describe Clamp::Parameter::Definition do
|
|
145
147
|
context "with a weird parameter name, and an explicit attribute_name" do
|
146
148
|
|
147
149
|
let(:parameter) do
|
148
|
-
described_class.new("KEY=VALUE ...", "config-settings", :
|
150
|
+
described_class.new("KEY=VALUE ...", "config-settings", attribute_name: :config_settings)
|
149
151
|
end
|
150
152
|
|
151
153
|
describe "#attribute_name" do
|
@@ -197,13 +199,13 @@ describe Clamp::Parameter::Definition do
|
|
197
199
|
context "with specified default value" do
|
198
200
|
|
199
201
|
let(:parameter) do
|
200
|
-
described_class.new("[FILES] ...", "files to process", :
|
202
|
+
described_class.new("[FILES] ...", "files to process", default: %w[a b c])
|
201
203
|
end
|
202
204
|
|
203
205
|
describe "#default_value" do
|
204
206
|
|
205
207
|
it "is that specified" do
|
206
|
-
expect(parameter.default_value).to eql %w
|
208
|
+
expect(parameter.default_value).to eql %w[a b c]
|
207
209
|
end
|
208
210
|
|
209
211
|
end
|
@@ -219,8 +221,8 @@ describe Clamp::Parameter::Definition do
|
|
219
221
|
describe "#consume" do
|
220
222
|
|
221
223
|
it "consumes all the remaining arguments" do
|
222
|
-
arguments = %w
|
223
|
-
expect(parameter.consume(arguments)).to eql %w
|
224
|
+
arguments = %w[a b c]
|
225
|
+
expect(parameter.consume(arguments)).to eql %w[a b c]
|
224
226
|
expect(arguments).to eql []
|
225
227
|
end
|
226
228
|
|
data/spec/spec_helper.rb
CHANGED
@@ -1,16 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "rspec"
|
2
4
|
require "clamp"
|
3
5
|
require "stringio"
|
4
6
|
|
5
7
|
RSpec.configure do |config|
|
6
8
|
|
7
|
-
config.mock_with :rr
|
8
|
-
|
9
9
|
config.around(:each) do |example|
|
10
10
|
begin
|
11
11
|
example.run
|
12
12
|
rescue SystemExit => e
|
13
|
-
|
13
|
+
raise "Unexpected exit with status #{e.status}"
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
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.2
|
4
|
+
version: 1.3.2
|
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: 2020-08-20 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |
|
14
14
|
Clamp provides an object-model for command-line utilities.
|
@@ -19,6 +19,7 @@ extensions: []
|
|
19
19
|
extra_rdoc_files: []
|
20
20
|
files:
|
21
21
|
- ".autotest"
|
22
|
+
- ".editorconfig"
|
22
23
|
- ".gitignore"
|
23
24
|
- ".rspec"
|
24
25
|
- ".rubocop.yml"
|
@@ -61,13 +62,14 @@ files:
|
|
61
62
|
- lib/clamp/version.rb
|
62
63
|
- spec/clamp/command_group_spec.rb
|
63
64
|
- spec/clamp/command_spec.rb
|
65
|
+
- spec/clamp/help_spec.rb
|
64
66
|
- spec/clamp/messages_spec.rb
|
65
67
|
- spec/clamp/option/definition_spec.rb
|
66
68
|
- spec/clamp/option_module_spec.rb
|
67
69
|
- spec/clamp/option_reordering_spec.rb
|
68
70
|
- spec/clamp/parameter/definition_spec.rb
|
69
71
|
- spec/spec_helper.rb
|
70
|
-
homepage:
|
72
|
+
homepage: https://github.com/mdub/clamp
|
71
73
|
licenses:
|
72
74
|
- MIT
|
73
75
|
metadata: {}
|
@@ -82,18 +84,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
82
84
|
version: '0'
|
83
85
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
84
86
|
requirements:
|
85
|
-
- - "
|
87
|
+
- - ">="
|
86
88
|
- !ruby/object:Gem::Version
|
87
|
-
version:
|
89
|
+
version: '0'
|
88
90
|
requirements: []
|
89
|
-
|
90
|
-
rubygems_version: 2.6.13
|
91
|
+
rubygems_version: 3.1.2
|
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
|