hammer_cli 0.1.0 → 0.1.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/README.md +13 -5
- data/config/cli_config.template.yml +12 -3
- data/doc/creating_apipie_commands.md +53 -56
- data/doc/creating_commands.md +25 -19
- data/doc/developer_docs.md +3 -2
- data/doc/development_tips.md +3 -3
- data/doc/i18n.md +3 -3
- data/doc/installation.md +24 -207
- data/doc/installation_deb.md +48 -0
- data/doc/installation_gem.md +30 -0
- data/doc/installation_rpm.md +53 -0
- data/doc/installation_source.md +31 -0
- data/doc/option_builders.md +77 -0
- data/doc/option_normalizers.md +5 -5
- data/doc/writing_a_plugin.md +9 -9
- data/lib/hammer_cli.rb +1 -0
- data/lib/hammer_cli/abstract.rb +21 -8
- data/lib/hammer_cli/apipie.rb +1 -2
- data/lib/hammer_cli/apipie/command.rb +37 -64
- data/lib/hammer_cli/apipie/option_builder.rb +69 -0
- data/lib/hammer_cli/apipie/options.rb +1 -61
- data/lib/hammer_cli/clamp.rb +15 -0
- data/lib/hammer_cli/i18n.rb +14 -2
- data/lib/hammer_cli/logger.rb +1 -1
- data/lib/hammer_cli/option_builder.rb +43 -0
- data/lib/hammer_cli/options/option_definition.rb +6 -0
- data/lib/hammer_cli/output/adapter/abstract.rb +2 -2
- data/lib/hammer_cli/output/adapter/base.rb +6 -3
- data/lib/hammer_cli/output/adapter/table.rb +19 -2
- data/lib/hammer_cli/output/definition.rb +4 -0
- data/lib/hammer_cli/output/fields.rb +9 -0
- data/lib/hammer_cli/output/formatters.rb +20 -8
- data/lib/hammer_cli/utils.rb +1 -1
- data/lib/hammer_cli/version.rb +1 -1
- data/locale/hammer-cli.pot +103 -79
- data/test/unit/abstract_test.rb +62 -0
- data/test/unit/apipie/command_test.rb +12 -197
- data/test/unit/apipie/option_builder_test.rb +110 -0
- data/test/unit/i18n_test.rb +50 -0
- data/test/unit/option_builder_test.rb +33 -0
- data/test/unit/output/adapter/abstract_test.rb +26 -3
- data/test/unit/output/adapter/base_test.rb +20 -3
- data/test/unit/output/adapter/csv_test.rb +2 -2
- data/test/unit/output/adapter/table_test.rb +24 -1
- data/test/unit/output/definition_test.rb +13 -0
- data/test/unit/output/formatters_test.rb +17 -1
- data/test/unit/utils_test.rb +1 -1
- metadata +101 -88
- data/lib/hammer_cli/apipie/read_command.rb +0 -41
- data/lib/hammer_cli/apipie/write_command.rb +0 -49
- data/test/unit/apipie/read_command_test.rb +0 -37
- data/test/unit/apipie/write_command_test.rb +0 -41
data/test/unit/abstract_test.rb
CHANGED
@@ -267,6 +267,68 @@ describe HammerCLI::AbstractCommand do
|
|
267
267
|
|
268
268
|
end
|
269
269
|
|
270
|
+
describe "option builder" do
|
271
|
+
|
272
|
+
it "uses builder container as default" do
|
273
|
+
HammerCLI::AbstractCommand.option_builder.class.must_equal HammerCLI::OptionBuilderContainer
|
274
|
+
end
|
275
|
+
|
276
|
+
it "Default builder container is empty" do
|
277
|
+
HammerCLI::AbstractCommand.option_builder.builders.empty?.must_equal true
|
278
|
+
end
|
279
|
+
|
280
|
+
it "can be initialized with custom builder" do
|
281
|
+
cmd = Class.new(HammerCLI::AbstractCommand) do
|
282
|
+
def self.custom_option_builders
|
283
|
+
[:builder_1, :builder_2]
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
cmd.option_builder.builders.must_equal [:builder_1, :builder_2]
|
288
|
+
end
|
289
|
+
|
290
|
+
end
|
291
|
+
|
292
|
+
describe "build options" do
|
293
|
+
|
294
|
+
class TestOptionBuilder
|
295
|
+
|
296
|
+
def build(build_options={})
|
297
|
+
[
|
298
|
+
HammerCLI::Options::OptionDefinition.new(["--test"], "TEST", "test"),
|
299
|
+
HammerCLI::Options::OptionDefinition.new(["--test2"], "TEST2", "test2")
|
300
|
+
]
|
301
|
+
end
|
302
|
+
|
303
|
+
end
|
304
|
+
|
305
|
+
class TestBuilderCmd < HammerCLI::AbstractCommand
|
306
|
+
|
307
|
+
def self.option_builder
|
308
|
+
TestOptionBuilder.new
|
309
|
+
end
|
310
|
+
|
311
|
+
end
|
312
|
+
|
313
|
+
before :each do
|
314
|
+
# define implicit options and clear them all
|
315
|
+
TestBuilderCmd.recognised_options
|
316
|
+
TestBuilderCmd.declared_options.clear
|
317
|
+
end
|
318
|
+
|
319
|
+
it "should use option builder" do
|
320
|
+
TestBuilderCmd.build_options
|
321
|
+
TestBuilderCmd.recognised_options.map(&:switches).flatten.sort.must_equal ["--test", "--test2"].sort
|
322
|
+
end
|
323
|
+
|
324
|
+
it "should skip options that already exist" do
|
325
|
+
TestBuilderCmd.option(["--test"], "TEST", "original_test")
|
326
|
+
TestBuilderCmd.build_options
|
327
|
+
TestBuilderCmd.recognised_options.map(&:description).flatten.sort.must_equal ["original_test", "test2"].sort
|
328
|
+
end
|
329
|
+
|
330
|
+
end
|
331
|
+
|
270
332
|
it "should inherit command_name" do
|
271
333
|
class CmdName1 < HammerCLI::AbstractCommand
|
272
334
|
command_name 'cmd'
|
@@ -26,92 +26,12 @@ describe HammerCLI::Apipie::Command do
|
|
26
26
|
let(:ctx) { { :adapter => :silent, :interactive => false } }
|
27
27
|
let(:cmd_class) { TestCommand.dup }
|
28
28
|
let(:cmd) { cmd_class.new("", ctx) }
|
29
|
+
let(:cmd_run) { cmd.run([]) }
|
29
30
|
|
30
31
|
before :each do
|
31
32
|
HammerCLI::Connection.drop_all
|
32
33
|
end
|
33
34
|
|
34
|
-
context "setting identifiers" do
|
35
|
-
|
36
|
-
let(:option_switches) { cmd_class.declared_options.map(&:switches).sort }
|
37
|
-
let(:option_attribute_names) { cmd_class.declared_options.map(&:attribute_name).sort }
|
38
|
-
|
39
|
-
class Cmd1 < TestCommand
|
40
|
-
identifiers :id, :name, :label
|
41
|
-
apipie_options
|
42
|
-
end
|
43
|
-
|
44
|
-
class Cmd2 < Cmd1
|
45
|
-
identifiers :id
|
46
|
-
apipie_options
|
47
|
-
end
|
48
|
-
|
49
|
-
it "must not set any option by default" do
|
50
|
-
cmd_class.apipie_options
|
51
|
-
cmd_class.declared_options.must_equal []
|
52
|
-
end
|
53
|
-
|
54
|
-
it "can set option --id" do
|
55
|
-
cmd_class.identifiers :id
|
56
|
-
cmd_class.apipie_options
|
57
|
-
option_switches.must_equal [["--id"]]
|
58
|
-
option_attribute_names.must_equal [HammerCLI.option_accessor_name("id")]
|
59
|
-
end
|
60
|
-
|
61
|
-
it "can set option --name" do
|
62
|
-
cmd_class.identifiers :name
|
63
|
-
cmd_class.apipie_options
|
64
|
-
option_switches.must_equal [["--name"]]
|
65
|
-
option_attribute_names.must_equal [HammerCLI.option_accessor_name("name")]
|
66
|
-
end
|
67
|
-
|
68
|
-
it "can set option --label" do
|
69
|
-
cmd_class.identifiers :label
|
70
|
-
cmd_class.apipie_options
|
71
|
-
option_switches.must_equal [["--label"]]
|
72
|
-
option_attribute_names.must_equal [HammerCLI.option_accessor_name("label")]
|
73
|
-
end
|
74
|
-
|
75
|
-
it "can set multiple identifiers" do
|
76
|
-
cmd_class.identifiers :id, :name, :label
|
77
|
-
cmd_class.apipie_options
|
78
|
-
option_switches.must_equal [["--id"], ["--label"], ["--name"]]
|
79
|
-
option_attribute_names.must_equal HammerCLI.option_accessor_name("id", "label", "name")
|
80
|
-
end
|
81
|
-
|
82
|
-
it "can change option reader" do
|
83
|
-
cmd_class.identifiers :name, :id => :option_id_read_method
|
84
|
-
cmd_class.apipie_options
|
85
|
-
option_switches.must_equal [["--id"], ["--name"]]
|
86
|
-
option_attribute_names.must_equal HammerCLI.option_accessor_name("id_read_method", "name")
|
87
|
-
end
|
88
|
-
|
89
|
-
it "can override inentifiers in inherrited classes" do
|
90
|
-
Cmd2.new("").class.declared_options.map(&:switches).must_equal [["--id"]]
|
91
|
-
end
|
92
|
-
|
93
|
-
context "require identifiers" do
|
94
|
-
|
95
|
-
it "must require one of declared identifiers" do
|
96
|
-
cmd_class.identifiers :id, :name
|
97
|
-
cmd_class.apipie_options
|
98
|
-
cmd.run(["--id=1"]).must_equal HammerCLI::EX_OK
|
99
|
-
end
|
100
|
-
|
101
|
-
it "must raise exception when no attribute is passed" do
|
102
|
-
cmd_class.identifiers :id, :name
|
103
|
-
cmd_class.apipie_options
|
104
|
-
cmd.run([]).must_equal HammerCLI::EX_USAGE
|
105
|
-
end
|
106
|
-
|
107
|
-
it "must run without error when no identifiers are declared" do
|
108
|
-
cmd.run([]).must_equal HammerCLI::EX_OK
|
109
|
-
end
|
110
|
-
|
111
|
-
end
|
112
|
-
|
113
|
-
end
|
114
|
-
|
115
35
|
context "setting resources" do
|
116
36
|
|
117
37
|
it "should set resource and action together" do
|
@@ -164,126 +84,21 @@ describe HammerCLI::Apipie::Command do
|
|
164
84
|
end
|
165
85
|
end
|
166
86
|
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
{ :apidoc_cache_dir => 'test/unit/fixtures/apipie', :apidoc_cache_name => 'documented' }
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
let(:cmd_class) { DocumentedCommand.dup }
|
176
|
-
let(:cmd) { cmd_class.new("", ctx) }
|
177
|
-
|
178
|
-
context "with one simple param" do
|
179
|
-
|
180
|
-
let(:option) { cmd_class.declared_options[0] }
|
181
|
-
|
182
|
-
before :each do
|
183
|
-
cmd_class.resource :documented, :index
|
184
|
-
cmd_class.apipie_options
|
185
|
-
end
|
186
|
-
|
187
|
-
it "should create an option for the parameter" do
|
188
|
-
cmd_class.declared_options.length.must_equal 1
|
189
|
-
end
|
190
|
-
|
191
|
-
it "should set correct switch" do
|
192
|
-
option.switches.must_be :include?, '--se-arch-val-ue'
|
193
|
-
end
|
194
|
-
|
195
|
-
it "should set correct attribute name" do
|
196
|
-
option.attribute_name.must_equal HammerCLI.option_accessor_name('se_arch_val_ue')
|
197
|
-
end
|
198
|
-
|
199
|
-
it "should set description with html tags stripped" do
|
200
|
-
option.description.must_equal 'filter results'
|
201
|
-
end
|
202
|
-
end
|
203
|
-
|
204
|
-
context "required options" do
|
205
|
-
before :each do
|
206
|
-
cmd_class.resource :documented, :create
|
207
|
-
cmd_class.apipie_options
|
208
|
-
end
|
209
|
-
|
210
|
-
let(:required_options) { cmd_class.declared_options.reject{|opt| !opt.required?} }
|
211
|
-
|
212
|
-
it "should set required flag for the required options" do
|
213
|
-
required_options.map(&:attribute_name).sort.must_equal [HammerCLI.option_accessor_name("array_param")]
|
214
|
-
end
|
215
|
-
end
|
216
|
-
|
217
|
-
context "with hash params" do
|
218
|
-
before :each do
|
219
|
-
cmd_class.resource :documented, :create
|
220
|
-
cmd_class.apipie_options
|
221
|
-
end
|
222
|
-
|
223
|
-
it "should create options for all parameters except the hash" do
|
224
|
-
cmd_class.declared_options.map(&:attribute_name).sort.must_equal HammerCLI.option_accessor_name("array_param", "name", "provider")
|
225
|
-
end
|
226
|
-
|
227
|
-
it "should name the options correctly" do
|
228
|
-
cmd_class.declared_options.map(&:attribute_name).sort.must_equal HammerCLI.option_accessor_name("array_param", "name", "provider")
|
229
|
-
end
|
230
|
-
end
|
231
|
-
|
232
|
-
context "array params" do
|
233
|
-
before :each do
|
234
|
-
cmd_class.resource :documented, :create
|
235
|
-
cmd_class.apipie_options
|
236
|
-
end
|
237
|
-
|
238
|
-
let(:cmd) do
|
239
|
-
cmd_class.new("").tap do |cmd|
|
240
|
-
cmd.stubs(:execute).returns(0)
|
241
|
-
end
|
242
|
-
end
|
243
|
-
|
244
|
-
it "should parse comma separated string to array" do
|
245
|
-
cmd.run(["--array-param=valA,valB,valC"])
|
246
|
-
cmd.get_option_value(:array_param).must_equal ['valA', 'valB', 'valC']
|
247
|
-
end
|
248
|
-
|
249
|
-
it "should parse string to array of length 1" do
|
250
|
-
cmd.run(["--array-param=valA"])
|
251
|
-
cmd.get_option_value(:array_param).must_equal ['valA']
|
252
|
-
end
|
87
|
+
it "should raise exception when no action is defined" do
|
88
|
+
cmd.stubs(:handle_exception).returns(HammerCLI::EX_SOFTWARE)
|
89
|
+
cmd_run.must_equal HammerCLI::EX_SOFTWARE
|
90
|
+
end
|
253
91
|
|
254
|
-
|
255
|
-
cmd.run(['--array-param='])
|
256
|
-
cmd.get_option_value(:array_param).must_equal []
|
257
|
-
end
|
92
|
+
context "resource defined" do
|
258
93
|
|
94
|
+
before :each do
|
95
|
+
HammerCLI::Connection.drop_all
|
96
|
+
ApipieBindings::API.any_instance.stubs(:call).returns([])
|
97
|
+
cmd.class.resource :architectures, :index
|
259
98
|
end
|
260
99
|
|
261
|
-
|
262
|
-
|
263
|
-
before :each do
|
264
|
-
cmd_class.resource :documented, :create
|
265
|
-
end
|
266
|
-
|
267
|
-
it "should skip filtered options" do
|
268
|
-
cmd_class.apipie_options :without => ["provider", "name"]
|
269
|
-
cmd_class.declared_options.map(&:attribute_name).sort.must_equal [HammerCLI.option_accessor_name("array_param")]
|
270
|
-
end
|
271
|
-
|
272
|
-
it "should skip filtered options defined as symbols" do
|
273
|
-
cmd_class.apipie_options :without => [:provider, :name]
|
274
|
-
cmd_class.declared_options.map(&:attribute_name).sort.must_equal [HammerCLI.option_accessor_name("array_param")]
|
275
|
-
end
|
276
|
-
|
277
|
-
it "should skip single filtered option in array" do
|
278
|
-
cmd_class.apipie_options :without => ["provider"]
|
279
|
-
cmd_class.declared_options.map(&:attribute_name).sort.must_equal HammerCLI.option_accessor_name("array_param", "name")
|
280
|
-
end
|
281
|
-
|
282
|
-
it "should skip single filtered option" do
|
283
|
-
cmd_class.apipie_options :without => "provider"
|
284
|
-
cmd_class.declared_options.map(&:attribute_name).sort.must_equal HammerCLI.option_accessor_name("array_param", "name")
|
285
|
-
end
|
286
|
-
|
100
|
+
it "should perform a call to api when resource is defined" do
|
101
|
+
cmd_run.must_equal 0
|
287
102
|
end
|
288
103
|
|
289
104
|
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../test_helper')
|
2
|
+
|
3
|
+
|
4
|
+
describe HammerCLI::OptionBuilderContainer do
|
5
|
+
|
6
|
+
end
|
7
|
+
|
8
|
+
describe HammerCLI::Apipie::OptionBuilder do
|
9
|
+
|
10
|
+
let(:api) do
|
11
|
+
ApipieBindings::API.new({
|
12
|
+
:apidoc_cache_dir => 'test/unit/fixtures/apipie',
|
13
|
+
:apidoc_cache_name => 'documented'
|
14
|
+
})
|
15
|
+
end
|
16
|
+
|
17
|
+
before :each do
|
18
|
+
HammerCLI::I18n.clear
|
19
|
+
end
|
20
|
+
|
21
|
+
let(:action) {api.resource(:documented).action(:index)}
|
22
|
+
let(:builder) { HammerCLI::Apipie::OptionBuilder.new(action) }
|
23
|
+
let(:builder_options) { {} }
|
24
|
+
let(:options) { builder.build(builder_options) }
|
25
|
+
|
26
|
+
context "with one simple param" do
|
27
|
+
|
28
|
+
it "should create an option for the parameter" do
|
29
|
+
options.length.must_equal 1
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should set correct switch" do
|
33
|
+
options[0].switches.must_be :include?, '--se-arch-val-ue'
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should set correct attribute name" do
|
37
|
+
options[0].attribute_name.must_equal HammerCLI.option_accessor_name('se_arch_val_ue')
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should set description with html tags stripped" do
|
41
|
+
options[0].description.must_equal 'filter results'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
context "required options" do
|
47
|
+
|
48
|
+
let(:action) {api.resource(:documented).action(:create)}
|
49
|
+
let(:required_options) { builder.build.reject{|opt| !opt.required?} }
|
50
|
+
|
51
|
+
it "should set required flag for the required options" do
|
52
|
+
required_options.map(&:attribute_name).sort.must_equal [HammerCLI.option_accessor_name("array_param")]
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should not require any option when requirements are disabled" do
|
56
|
+
builder.require_options = false
|
57
|
+
required_options.map(&:attribute_name).sort.must_equal []
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
context "with hash params" do
|
63
|
+
let(:action) {api.resource(:documented).action(:create)}
|
64
|
+
|
65
|
+
it "should create options for all parameters except the hash" do
|
66
|
+
options.map(&:attribute_name).sort.must_equal HammerCLI.option_accessor_name("array_param", "name", "provider")
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should name the options correctly" do
|
70
|
+
options.map(&:attribute_name).sort.must_equal HammerCLI.option_accessor_name("array_param", "name", "provider")
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context "setting correct normalizers" do
|
75
|
+
let(:action) {api.resource(:documented).action(:create)}
|
76
|
+
|
77
|
+
it "should set array normalizer" do
|
78
|
+
array_option = options.find {|o| o.attribute_name == HammerCLI.option_accessor_name("array_param") }
|
79
|
+
array_option.value_formatter.class.must_equal HammerCLI::Options::Normalizers::List
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
context "filtering options" do
|
86
|
+
let(:action) {api.resource(:documented).action(:create)}
|
87
|
+
|
88
|
+
it "should skip filtered options" do
|
89
|
+
builder_options[:without] = ["provider", "name"]
|
90
|
+
options.map(&:attribute_name).sort.must_equal [HammerCLI.option_accessor_name("array_param")]
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should skip filtered options defined as symbols" do
|
94
|
+
builder_options[:without] = [:provider, :name]
|
95
|
+
options.map(&:attribute_name).sort.must_equal [HammerCLI.option_accessor_name("array_param")]
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should skip single filtered option in array" do
|
99
|
+
builder_options[:without] = ["provider"]
|
100
|
+
options.map(&:attribute_name).sort.must_equal HammerCLI.option_accessor_name("array_param", "name")
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should skip single filtered option" do
|
104
|
+
builder_options[:without] = "provider"
|
105
|
+
options.map(&:attribute_name).sort.must_equal HammerCLI.option_accessor_name("array_param", "name")
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
|
4
|
+
describe HammerCLI::I18n do
|
5
|
+
|
6
|
+
class TestLocaleDomain < HammerCLI::I18n::AbstractLocaleDomain
|
7
|
+
|
8
|
+
def initialize(name, available)
|
9
|
+
@name = name
|
10
|
+
@available = available
|
11
|
+
end
|
12
|
+
|
13
|
+
def locale_dir
|
14
|
+
File.dirname(__FILE__)
|
15
|
+
end
|
16
|
+
|
17
|
+
def domain_name
|
18
|
+
@name
|
19
|
+
end
|
20
|
+
|
21
|
+
def available?
|
22
|
+
@available
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
before :each do
|
27
|
+
HammerCLI::I18n.clear
|
28
|
+
end
|
29
|
+
|
30
|
+
let(:domain1) { TestLocaleDomain.new('domain1', true) }
|
31
|
+
let(:domain2) { TestLocaleDomain.new('domain2', true) }
|
32
|
+
let(:unavailable_domain) { TestLocaleDomain.new('domain3', false) }
|
33
|
+
|
34
|
+
it "registers available domains at gettext" do
|
35
|
+
FastGettext.expects(:add_text_domain).with do |name, options|
|
36
|
+
(name == domain1.domain_name) && (options[:path] == domain1.locale_dir) && (options[:type] == domain1.type)
|
37
|
+
end
|
38
|
+
HammerCLI::I18n.add_domain(domain1)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "skips registering domains that are not available" do
|
42
|
+
HammerCLI::I18n.add_domain(domain1)
|
43
|
+
HammerCLI::I18n.add_domain(domain2)
|
44
|
+
HammerCLI::I18n.add_domain(unavailable_domain)
|
45
|
+
HammerCLI::I18n.domains.must_equal [domain1, domain2]
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
end
|
50
|
+
|