clamp 1.4.0 → 1.5.1
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.
- checksums.yaml +4 -4
- data/CHANGES.md +8 -0
- data/README.md +44 -0
- data/examples/gitdown +1 -0
- data/lib/clamp/completion/bash_generator.rb +207 -0
- data/lib/clamp/completion/fish_generator.rb +176 -0
- data/lib/clamp/completion/zsh_generator.rb +123 -0
- data/lib/clamp/completion.rb +187 -0
- data/lib/clamp/version.rb +1 -1
- metadata +5 -21
- data/.autotest +0 -11
- data/.editorconfig +0 -10
- data/.github/workflows/ci.yml +0 -31
- data/.gitignore +0 -9
- data/.rspec +0 -2
- data/.rubocop.yml +0 -74
- data/CODEOWNERS +0 -1
- data/Gemfile +0 -20
- data/Guardfile +0 -45
- data/Rakefile +0 -18
- data/clamp.gemspec +0 -28
- data/spec/clamp/command_group_spec.rb +0 -438
- data/spec/clamp/command_option_module_spec.rb +0 -40
- data/spec/clamp/command_option_reordering_spec.rb +0 -58
- data/spec/clamp/command_spec.rb +0 -1280
- data/spec/clamp/help/builder_spec.rb +0 -81
- data/spec/clamp/messages_spec.rb +0 -50
- data/spec/clamp/option/definition_spec.rb +0 -343
- data/spec/clamp/parameter/definition_spec.rb +0 -314
- data/spec/spec_helper.rb +0 -65
|
@@ -1,81 +0,0 @@
|
|
|
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
|
-
before do
|
|
34
|
-
|
|
35
|
-
builder.row("foo", "bar")
|
|
36
|
-
builder.row("flibble", "blurk")
|
|
37
|
-
builder.row("x", "y")
|
|
38
|
-
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
let(:expected_output) do
|
|
42
|
-
[
|
|
43
|
-
" foo bar\n",
|
|
44
|
-
" flibble blurk\n",
|
|
45
|
-
" x y\n"
|
|
46
|
-
]
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
it "arranges them in two columns" do
|
|
50
|
-
expect(output.lines).to eq expected_output
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
context "with a mixture of lines and rows" do
|
|
56
|
-
|
|
57
|
-
before do
|
|
58
|
-
|
|
59
|
-
builder.line("ABCDEFGHIJKLMNOP")
|
|
60
|
-
builder.row("flibble", "blurk")
|
|
61
|
-
builder.line("Another section heading")
|
|
62
|
-
builder.row("x", "y")
|
|
63
|
-
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
let(:expected_output) do
|
|
67
|
-
[
|
|
68
|
-
"ABCDEFGHIJKLMNOP\n",
|
|
69
|
-
" flibble blurk\n",
|
|
70
|
-
"Another section heading\n",
|
|
71
|
-
" x y\n"
|
|
72
|
-
]
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
it "still arranges them in two columns" do
|
|
76
|
-
expect(output.lines).to eq expected_output
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
end
|
data/spec/clamp/messages_spec.rb
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "spec_helper"
|
|
4
|
-
|
|
5
|
-
describe Clamp::Messages do
|
|
6
|
-
|
|
7
|
-
describe "message" do
|
|
8
|
-
before do
|
|
9
|
-
Clamp.messages = {
|
|
10
|
-
too_many_arguments: "Way too many!",
|
|
11
|
-
custom_message: "Say %<what>s to %<whom>s"
|
|
12
|
-
}
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
after do
|
|
16
|
-
Clamp.clear_messages!
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
it "allows setting custom messages" do
|
|
20
|
-
expect(Clamp.message(:too_many_arguments)).to eq "Way too many!"
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
it "fallbacks to a default message" do
|
|
24
|
-
expect(Clamp.message(:no_value_provided)).to eq "no value provided"
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
it "formats the message" do
|
|
28
|
-
expect(Clamp.message(:custom_message, what: "hello", whom: "Clamp")).to eq "Say hello to Clamp"
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
describe "clear_messages!" do
|
|
33
|
-
let!(:default_msg) { Clamp.message(:too_many_arguments).clone }
|
|
34
|
-
|
|
35
|
-
before do
|
|
36
|
-
|
|
37
|
-
Clamp.messages = {
|
|
38
|
-
too_many_arguments: "Way too many!"
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
Clamp.clear_messages!
|
|
42
|
-
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
it "clears messages to the defualt state" do
|
|
46
|
-
expect(Clamp.message(:too_many_arguments)).to eq default_msg
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
end
|
|
@@ -1,343 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "spec_helper"
|
|
4
|
-
|
|
5
|
-
describe Clamp::Option::Definition do
|
|
6
|
-
|
|
7
|
-
context "with String argument" do
|
|
8
|
-
|
|
9
|
-
let(:option) do
|
|
10
|
-
described_class.new("--key-file", "FILE", "SSH identity")
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
it "has a long_switch" do
|
|
14
|
-
expect(option.long_switch).to eq "--key-file"
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
it "has a type" do
|
|
18
|
-
expect(option.type).to eq "FILE"
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
it "has a description" do
|
|
22
|
-
expect(option.description).to eq "SSH identity"
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
describe "#attribute_name" do
|
|
26
|
-
|
|
27
|
-
it "is derived from the (long) switch" do
|
|
28
|
-
expect(option.attribute_name).to eq "key_file"
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
it "can be overridden" do
|
|
32
|
-
option = described_class.new("--key-file", "FILE", "SSH identity", attribute_name: "ssh_identity")
|
|
33
|
-
expect(option.attribute_name).to eq "ssh_identity"
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
describe "#write_method" do
|
|
39
|
-
|
|
40
|
-
it "is derived from the attribute_name" do
|
|
41
|
-
expect(option.write_method).to eq "key_file="
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
describe "#default_value" do
|
|
47
|
-
|
|
48
|
-
it "defaults to nil" do
|
|
49
|
-
option = described_class.new("-n", "N", "iterations")
|
|
50
|
-
expect(option.default_value).to be_nil
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
it "can be overridden" do
|
|
54
|
-
option = described_class.new("-n", "N", "iterations", default: 1)
|
|
55
|
-
expect(option.default_value).to eq 1
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
describe "#help" do
|
|
61
|
-
|
|
62
|
-
it "combines switch, type and description" do
|
|
63
|
-
expect(option.help).to eq ["--key-file FILE", "SSH identity"]
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
context "when flag" do
|
|
71
|
-
|
|
72
|
-
let(:option) do
|
|
73
|
-
described_class.new("--verbose", :flag, "Blah blah blah")
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
describe "#default_conversion_block" do
|
|
77
|
-
|
|
78
|
-
context "with 'true' value" do
|
|
79
|
-
it "converts to true" do
|
|
80
|
-
expect(option.default_conversion_block.call("true")).to be true
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
context "with 'yes' value" do
|
|
85
|
-
it "converts to true" do
|
|
86
|
-
expect(option.default_conversion_block.call("yes")).to be true
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
context "with 'false' value" do
|
|
91
|
-
it "converts to false" do
|
|
92
|
-
expect(option.default_conversion_block.call("false")).to be false
|
|
93
|
-
end
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
context "with 'no' value" do
|
|
97
|
-
it "converts to false" do
|
|
98
|
-
expect(option.default_conversion_block.call("no")).to be false
|
|
99
|
-
end
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
describe "#help" do
|
|
105
|
-
|
|
106
|
-
it "excludes option argument" do
|
|
107
|
-
expect(option.help).to eq ["--verbose", "Blah blah blah"]
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
context "when negatable flag" do
|
|
115
|
-
|
|
116
|
-
let(:option) do
|
|
117
|
-
described_class.new("--[no-]force", :flag, "Force installation")
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
describe "positive form" do
|
|
121
|
-
it "handles this" do
|
|
122
|
-
expect(option.handles?("--force")).to be true
|
|
123
|
-
end
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
describe "negative form" do
|
|
127
|
-
it "handles this" do
|
|
128
|
-
expect(option.handles?("--no-force")).to be true
|
|
129
|
-
end
|
|
130
|
-
end
|
|
131
|
-
|
|
132
|
-
describe "#flag_set?" do
|
|
133
|
-
|
|
134
|
-
describe "positive variant" do
|
|
135
|
-
it "returns true" do
|
|
136
|
-
expect(option.flag_set?("--force")).to be true
|
|
137
|
-
end
|
|
138
|
-
end
|
|
139
|
-
|
|
140
|
-
describe "negative variant" do
|
|
141
|
-
it "returns false" do
|
|
142
|
-
expect(option.flag_set?("--no-force")).to be false
|
|
143
|
-
end
|
|
144
|
-
end
|
|
145
|
-
|
|
146
|
-
end
|
|
147
|
-
|
|
148
|
-
describe "#attribute_name" do
|
|
149
|
-
|
|
150
|
-
it "is derived from the (long) switch" do
|
|
151
|
-
expect(option.attribute_name).to eq "force"
|
|
152
|
-
end
|
|
153
|
-
|
|
154
|
-
end
|
|
155
|
-
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
context "with both short and long switches" do
|
|
159
|
-
|
|
160
|
-
let(:option) do
|
|
161
|
-
described_class.new(["-k", "--key-file"], "FILE", "SSH identity")
|
|
162
|
-
end
|
|
163
|
-
|
|
164
|
-
describe "long switch" do
|
|
165
|
-
it "handles this" do
|
|
166
|
-
expect(option.handles?("--key-file")).to be true
|
|
167
|
-
end
|
|
168
|
-
end
|
|
169
|
-
|
|
170
|
-
describe "short switch" do
|
|
171
|
-
it "handles this" do
|
|
172
|
-
expect(option.handles?("-k")).to be true
|
|
173
|
-
end
|
|
174
|
-
end
|
|
175
|
-
|
|
176
|
-
describe "#help" do
|
|
177
|
-
|
|
178
|
-
it "includes both switches" do
|
|
179
|
-
expect(option.help).to eq ["-k, --key-file FILE", "SSH identity"]
|
|
180
|
-
end
|
|
181
|
-
|
|
182
|
-
end
|
|
183
|
-
|
|
184
|
-
end
|
|
185
|
-
|
|
186
|
-
context "with an associated environment variable" do
|
|
187
|
-
|
|
188
|
-
let(:option) do
|
|
189
|
-
described_class.new("-x", "X", "mystery option", environment_variable: "APP_X")
|
|
190
|
-
end
|
|
191
|
-
|
|
192
|
-
describe "#help" do
|
|
193
|
-
|
|
194
|
-
it "describes environment variable" do
|
|
195
|
-
expect(option.help).to eq ["-x X", "mystery option (default: $APP_X)"]
|
|
196
|
-
end
|
|
197
|
-
|
|
198
|
-
end
|
|
199
|
-
|
|
200
|
-
context "with a default value" do
|
|
201
|
-
|
|
202
|
-
let(:option) do
|
|
203
|
-
described_class.new("-x", "X", "mystery option", environment_variable: "APP_X", default: "xyz")
|
|
204
|
-
end
|
|
205
|
-
|
|
206
|
-
describe "#help" do
|
|
207
|
-
|
|
208
|
-
it "describes both environment variable and default" do
|
|
209
|
-
expect(option.help).to eq ["-x X", %{mystery option (default: $APP_X, or "xyz")}]
|
|
210
|
-
end
|
|
211
|
-
|
|
212
|
-
end
|
|
213
|
-
|
|
214
|
-
end
|
|
215
|
-
|
|
216
|
-
context "when it is required" do
|
|
217
|
-
|
|
218
|
-
let(:option) do
|
|
219
|
-
described_class.new("-x", "X", "mystery option", environment_variable: "APP_X", required: true)
|
|
220
|
-
end
|
|
221
|
-
|
|
222
|
-
describe "#help" do
|
|
223
|
-
|
|
224
|
-
it "describes the environment variable as the default" do
|
|
225
|
-
expect(option.help).to eql ["-x X", %{mystery option (required, default: $APP_X)}]
|
|
226
|
-
end
|
|
227
|
-
|
|
228
|
-
end
|
|
229
|
-
|
|
230
|
-
end
|
|
231
|
-
|
|
232
|
-
end
|
|
233
|
-
|
|
234
|
-
context "when multivalued" do
|
|
235
|
-
|
|
236
|
-
let(:option) do
|
|
237
|
-
described_class.new(["-H", "--header"], "HEADER", "extra header", multivalued: true)
|
|
238
|
-
end
|
|
239
|
-
|
|
240
|
-
it "is multivalued" do
|
|
241
|
-
expect(option).to be_multivalued
|
|
242
|
-
end
|
|
243
|
-
|
|
244
|
-
describe "#default_value" do
|
|
245
|
-
|
|
246
|
-
it "defaults to an empty Array" do
|
|
247
|
-
expect(option.default_value).to be_empty
|
|
248
|
-
end
|
|
249
|
-
|
|
250
|
-
it "can be overridden" do
|
|
251
|
-
option = described_class.new("-H", "HEADER", "extra header", multivalued: true, default: [1, 2, 3])
|
|
252
|
-
expect(option.default_value).to eq [1, 2, 3]
|
|
253
|
-
end
|
|
254
|
-
|
|
255
|
-
end
|
|
256
|
-
|
|
257
|
-
describe "#attribute_name" do
|
|
258
|
-
|
|
259
|
-
it "gets a _list suffix" do
|
|
260
|
-
expect(option.attribute_name).to eq "header_list"
|
|
261
|
-
end
|
|
262
|
-
|
|
263
|
-
end
|
|
264
|
-
|
|
265
|
-
describe "#append_method" do
|
|
266
|
-
|
|
267
|
-
it "is derived from the attribute_name" do
|
|
268
|
-
expect(option.append_method).to eq "append_to_header_list"
|
|
269
|
-
end
|
|
270
|
-
|
|
271
|
-
end
|
|
272
|
-
|
|
273
|
-
end
|
|
274
|
-
|
|
275
|
-
describe "in subcommand" do
|
|
276
|
-
|
|
277
|
-
let(:command_class) do
|
|
278
|
-
|
|
279
|
-
Class.new(Clamp::Command) do
|
|
280
|
-
subcommand "foo", "FOO!" do
|
|
281
|
-
option "--bar", "BAR", "Bars foo."
|
|
282
|
-
end
|
|
283
|
-
end
|
|
284
|
-
|
|
285
|
-
end
|
|
286
|
-
|
|
287
|
-
describe "Command#help" do
|
|
288
|
-
|
|
289
|
-
it "includes help for each option exactly once" do
|
|
290
|
-
subcommand = command_class.send(:find_subcommand, "foo")
|
|
291
|
-
subcommand_help = subcommand.subcommand_class.help("")
|
|
292
|
-
expect(subcommand_help.lines.grep(/--bar BAR/).count).to eq 1
|
|
293
|
-
end
|
|
294
|
-
|
|
295
|
-
end
|
|
296
|
-
|
|
297
|
-
end
|
|
298
|
-
|
|
299
|
-
describe "a required option" do
|
|
300
|
-
it "rejects :default" do
|
|
301
|
-
expect do
|
|
302
|
-
described_class.new("--key-file", "FILE", "SSH identity",
|
|
303
|
-
required: true, default: "hello")
|
|
304
|
-
end.to raise_error(ArgumentError)
|
|
305
|
-
end
|
|
306
|
-
|
|
307
|
-
it "rejects :flag options" do
|
|
308
|
-
expect do
|
|
309
|
-
described_class.new("--awesome", :flag, "Be awesome?", required: true)
|
|
310
|
-
end.to raise_error(ArgumentError)
|
|
311
|
-
end
|
|
312
|
-
end
|
|
313
|
-
|
|
314
|
-
describe "a hidden option" do
|
|
315
|
-
let(:option) { described_class.new("--unseen", :flag, "Something", hidden: true) }
|
|
316
|
-
|
|
317
|
-
it "is hidden" do
|
|
318
|
-
expect(option).to be_hidden
|
|
319
|
-
end
|
|
320
|
-
end
|
|
321
|
-
|
|
322
|
-
describe "a hidden option in a command" do
|
|
323
|
-
let(:command_class) do
|
|
324
|
-
Class.new(Clamp::Command) do
|
|
325
|
-
option "--unseen", :flag, "Something", hidden: true
|
|
326
|
-
|
|
327
|
-
def execute
|
|
328
|
-
# this space intentionally left blank
|
|
329
|
-
end
|
|
330
|
-
end
|
|
331
|
-
end
|
|
332
|
-
|
|
333
|
-
it "is not shown in the help" do
|
|
334
|
-
expect(command_class.help("foo")).not_to match(/^ +--unseen +Something$/)
|
|
335
|
-
end
|
|
336
|
-
|
|
337
|
-
it "sets the expected accessor" do
|
|
338
|
-
command = command_class.new("foo")
|
|
339
|
-
command.run(["--unseen"])
|
|
340
|
-
expect(command).to be_unseen
|
|
341
|
-
end
|
|
342
|
-
end
|
|
343
|
-
end
|