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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +13 -5
  3. data/config/cli_config.template.yml +12 -3
  4. data/doc/creating_apipie_commands.md +53 -56
  5. data/doc/creating_commands.md +25 -19
  6. data/doc/developer_docs.md +3 -2
  7. data/doc/development_tips.md +3 -3
  8. data/doc/i18n.md +3 -3
  9. data/doc/installation.md +24 -207
  10. data/doc/installation_deb.md +48 -0
  11. data/doc/installation_gem.md +30 -0
  12. data/doc/installation_rpm.md +53 -0
  13. data/doc/installation_source.md +31 -0
  14. data/doc/option_builders.md +77 -0
  15. data/doc/option_normalizers.md +5 -5
  16. data/doc/writing_a_plugin.md +9 -9
  17. data/lib/hammer_cli.rb +1 -0
  18. data/lib/hammer_cli/abstract.rb +21 -8
  19. data/lib/hammer_cli/apipie.rb +1 -2
  20. data/lib/hammer_cli/apipie/command.rb +37 -64
  21. data/lib/hammer_cli/apipie/option_builder.rb +69 -0
  22. data/lib/hammer_cli/apipie/options.rb +1 -61
  23. data/lib/hammer_cli/clamp.rb +15 -0
  24. data/lib/hammer_cli/i18n.rb +14 -2
  25. data/lib/hammer_cli/logger.rb +1 -1
  26. data/lib/hammer_cli/option_builder.rb +43 -0
  27. data/lib/hammer_cli/options/option_definition.rb +6 -0
  28. data/lib/hammer_cli/output/adapter/abstract.rb +2 -2
  29. data/lib/hammer_cli/output/adapter/base.rb +6 -3
  30. data/lib/hammer_cli/output/adapter/table.rb +19 -2
  31. data/lib/hammer_cli/output/definition.rb +4 -0
  32. data/lib/hammer_cli/output/fields.rb +9 -0
  33. data/lib/hammer_cli/output/formatters.rb +20 -8
  34. data/lib/hammer_cli/utils.rb +1 -1
  35. data/lib/hammer_cli/version.rb +1 -1
  36. data/locale/hammer-cli.pot +103 -79
  37. data/test/unit/abstract_test.rb +62 -0
  38. data/test/unit/apipie/command_test.rb +12 -197
  39. data/test/unit/apipie/option_builder_test.rb +110 -0
  40. data/test/unit/i18n_test.rb +50 -0
  41. data/test/unit/option_builder_test.rb +33 -0
  42. data/test/unit/output/adapter/abstract_test.rb +26 -3
  43. data/test/unit/output/adapter/base_test.rb +20 -3
  44. data/test/unit/output/adapter/csv_test.rb +2 -2
  45. data/test/unit/output/adapter/table_test.rb +24 -1
  46. data/test/unit/output/definition_test.rb +13 -0
  47. data/test/unit/output/formatters_test.rb +17 -1
  48. data/test/unit/utils_test.rb +1 -1
  49. metadata +101 -88
  50. data/lib/hammer_cli/apipie/read_command.rb +0 -41
  51. data/lib/hammer_cli/apipie/write_command.rb +0 -49
  52. data/test/unit/apipie/read_command_test.rb +0 -37
  53. data/test/unit/apipie/write_command_test.rb +0 -41
@@ -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
- context "apipie generated options" do
168
-
169
- class DocumentedCommand < HammerCLI::Apipie::Command
170
- def self.resource_config
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
- it "should parse empty string to empty array" do
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
- context "filtering options" do
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
+