hammer_cli 0.0.18 → 0.1.0

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 (66) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -314
  3. data/bin/hammer +45 -6
  4. data/config/cli.modules.d/module_config_template.yml +4 -0
  5. data/config/cli_config.template.yml +9 -11
  6. data/doc/developer_docs.md +1 -0
  7. data/doc/i18n.md +85 -0
  8. data/doc/installation.md +321 -0
  9. data/lib/hammer_cli.rb +3 -0
  10. data/lib/hammer_cli/abstract.rb +15 -24
  11. data/lib/hammer_cli/apipie/command.rb +13 -7
  12. data/lib/hammer_cli/apipie/options.rb +14 -16
  13. data/lib/hammer_cli/apipie/read_command.rb +6 -1
  14. data/lib/hammer_cli/apipie/resource.rb +48 -58
  15. data/lib/hammer_cli/apipie/write_command.rb +5 -1
  16. data/lib/hammer_cli/completer.rb +77 -21
  17. data/lib/hammer_cli/connection.rb +44 -0
  18. data/lib/hammer_cli/exception_handler.rb +15 -4
  19. data/lib/hammer_cli/exceptions.rb +6 -0
  20. data/lib/hammer_cli/i18n.rb +95 -0
  21. data/lib/hammer_cli/logger.rb +3 -3
  22. data/lib/hammer_cli/main.rb +12 -11
  23. data/lib/hammer_cli/modules.rb +19 -6
  24. data/lib/hammer_cli/options/normalizers.rb +42 -7
  25. data/lib/hammer_cli/options/option_definition.rb +2 -2
  26. data/lib/hammer_cli/output.rb +1 -0
  27. data/lib/hammer_cli/output/adapter/abstract.rb +20 -0
  28. data/lib/hammer_cli/output/adapter/base.rb +49 -78
  29. data/lib/hammer_cli/output/adapter/csv.rb +5 -5
  30. data/lib/hammer_cli/output/adapter/table.rb +41 -10
  31. data/lib/hammer_cli/output/dsl.rb +1 -1
  32. data/lib/hammer_cli/output/field_filter.rb +21 -0
  33. data/lib/hammer_cli/output/fields.rb +44 -78
  34. data/lib/hammer_cli/output/formatters.rb +38 -0
  35. data/lib/hammer_cli/settings.rb +28 -6
  36. data/lib/hammer_cli/shell.rb +58 -57
  37. data/lib/hammer_cli/utils.rb +14 -0
  38. data/lib/hammer_cli/validator.rb +5 -5
  39. data/lib/hammer_cli/version.rb +1 -1
  40. data/locale/Makefile +64 -0
  41. data/locale/hammer-cli.pot +203 -0
  42. data/locale/zanata.xml +29 -0
  43. data/test/unit/apipie/command_test.rb +42 -25
  44. data/test/unit/apipie/read_command_test.rb +10 -7
  45. data/test/unit/apipie/write_command_test.rb +9 -8
  46. data/test/unit/completer_test.rb +206 -21
  47. data/test/unit/connection_test.rb +68 -0
  48. data/test/unit/fixtures/apipie/architectures.json +153 -0
  49. data/test/unit/fixtures/apipie/documented.json +79 -0
  50. data/test/unit/fixtures/json_input/invalid.json +12 -0
  51. data/test/unit/fixtures/json_input/valid.json +12 -0
  52. data/test/unit/history_test.rb +71 -0
  53. data/test/unit/main_test.rb +9 -0
  54. data/test/unit/modules_test.rb +22 -6
  55. data/test/unit/options/field_filter_test.rb +27 -0
  56. data/test/unit/options/normalizers_test.rb +53 -0
  57. data/test/unit/output/adapter/base_test.rb +162 -10
  58. data/test/unit/output/adapter/csv_test.rb +16 -3
  59. data/test/unit/output/adapter/table_test.rb +97 -13
  60. data/test/unit/output/dsl_test.rb +74 -6
  61. data/test/unit/output/fields_test.rb +93 -62
  62. data/test/unit/output/formatters_test.rb +47 -0
  63. data/test/unit/settings_test.rb +35 -4
  64. data/test/unit/utils_test.rb +45 -0
  65. metadata +85 -4
  66. data/test/unit/apipie/fake_api.rb +0 -101
@@ -0,0 +1,68 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+
3
+ describe HammerCLI::Connection do
4
+
5
+ before :each do
6
+ # clean up global settings
7
+ HammerCLI::Connection.drop_all
8
+ HammerCLI::Settings.load({:_params => {:interactive => false}})
9
+ end
10
+
11
+ let(:connection) { HammerCLI::Connection }
12
+
13
+ class Connector < HammerCLI::AbstractConnector
14
+
15
+ attr_reader :url
16
+
17
+ def initialize(params)
18
+ @url = params[:url]
19
+ super
20
+ end
21
+
22
+ end
23
+
24
+ it "should return the conection" do
25
+ conn = connection.create(:test, {})
26
+ conn.must_be_kind_of HammerCLI::AbstractConnector
27
+ end
28
+
29
+ it "should create the connection only once" do
30
+ conn1 = connection.create(:test, {})
31
+ conn2 = connection.create(:test, {})
32
+ conn1.must_equal conn2
33
+ end
34
+
35
+ it "should test the connection" do
36
+ connection.exist?(:test).must_equal false
37
+ conn1 = connection.create(:test, {})
38
+ connection.exist?(:test).must_equal true
39
+ end
40
+
41
+ it "should get the connection" do
42
+ conn1 = connection.create(:test, {})
43
+ conn2 = connection.get(:test)
44
+ conn1.must_equal conn2
45
+ end
46
+
47
+
48
+ it "should be able to drop all" do
49
+ conn1 = connection.create(:test, {})
50
+ connection.drop_all
51
+ conn2 = connection.create(:test, {})
52
+ conn1.wont_equal conn2 # TODO
53
+ end
54
+
55
+ it "should drop the connection" do
56
+ conn1 = connection.create(:test, {})
57
+ connection.drop(:test)
58
+ conn2 = connection.create(:test, {})
59
+ conn1.wont_equal conn2
60
+ end
61
+
62
+ it "should accept custom connector" do
63
+ conn = connection.create(:test, {:url => 'URL'}, :connector => Connector)
64
+ conn.must_be_kind_of Connector
65
+ conn.url.must_equal 'URL'
66
+ end
67
+
68
+ end
@@ -0,0 +1,153 @@
1
+ {
2
+ "docs": {
3
+ "api_url": "/api",
4
+ "copyright": "",
5
+ "doc_url": "/apidoc/v2",
6
+ "info": "Another API description",
7
+ "name": "Foreman",
8
+ "resources": {
9
+ "architectures": {
10
+ "api_url": "/api",
11
+ "doc_url": "/apidoc/v2/architectures",
12
+ "formats": null,
13
+ "full_description": null,
14
+ "methods": [
15
+ {
16
+ "apis": [
17
+ {
18
+ "api_url": "/api/architectures",
19
+ "http_method": "GET",
20
+ "short_description": "List all architectures."
21
+ }
22
+ ],
23
+ "doc_url": "/apidoc/v2/architectures/index",
24
+ "errors": [],
25
+ "examples": [
26
+ "GET /api/architectures\n200\n[\n {\n \"architecture\": {\n \"name\": \"s390\",\n \"id\": 381564594,\n \"updated_at\": \"2012-12-18T15:24:42Z\",\n \"operatingsystem_ids\": [],\n \"created_at\": \"2012-12-18T15:24:42Z\"\n }\n },\n {\n \"architecture\": {\n \"name\": \"sparc\",\n \"id\": 331892513,\n \"updated_at\": \"2012-12-18T15:24:42Z\",\n \"operatingsystem_ids\": [\n 442321401\n ],\n \"created_at\": \"2012-12-18T15:24:42Z\"\n }\n },\n {\n \"architecture\": {\n \"name\": \"x86_64\",\n \"id\": 501905019,\n \"updated_at\": \"2012-12-18T15:24:42Z\",\n \"operatingsystem_ids\": [\n 331303656,\n 309172073,\n 1073012828\n ],\n \"created_at\": \"2012-12-18T15:24:42Z\"\n }\n }\n]"
27
+ ],
28
+ "formats": null,
29
+ "full_description": "",
30
+ "name": "index",
31
+ "params": [
32
+ {
33
+ "allow_nil": false,
34
+ "description": "\n<p>filter results</p>\n",
35
+ "expected_type": "string",
36
+ "full_name": "search",
37
+ "name": "search",
38
+ "required": false,
39
+ "validator": "Must be String"
40
+ },
41
+ {
42
+ "allow_nil": false,
43
+ "description": "\n<p>sort results</p>\n",
44
+ "expected_type": "string",
45
+ "full_name": "order",
46
+ "name": "order",
47
+ "required": false,
48
+ "validator": "Must be String"
49
+ },
50
+ {
51
+ "allow_nil": false,
52
+ "description": "\n<p>paginate results</p>\n",
53
+ "expected_type": "string",
54
+ "full_name": "page",
55
+ "name": "page",
56
+ "required": false,
57
+ "validator": "Must be String"
58
+ },
59
+ {
60
+ "allow_nil": false,
61
+ "description": "\n<p>number of entries per request</p>\n",
62
+ "expected_type": "string",
63
+ "full_name": "per_page",
64
+ "name": "per_page",
65
+ "required": false,
66
+ "validator": "Must be String"
67
+ }
68
+ ],
69
+ "see": []
70
+ },
71
+ {
72
+ "apis": [
73
+ {
74
+ "api_url": "/api/architectures/:id",
75
+ "http_method": "GET",
76
+ "short_description": "Show an architecture."
77
+ }
78
+ ],
79
+ "doc_url": "/apidoc/v2/architectures/show",
80
+ "errors": [],
81
+ "examples": [
82
+ "GET /api/architectures/x86_64\n200\n{\n \"architecture\": {\n \"name\": \"x86_64\",\n \"id\": 501905019,\n \"updated_at\": \"2012-12-18T15:24:42Z\",\n \"operatingsystem_ids\": [\n 309172073,\n 1073012828,\n 331303656\n ],\n \"created_at\": \"2012-12-18T15:24:42Z\"\n }\n}"
83
+ ],
84
+ "formats": null,
85
+ "full_description": "",
86
+ "name": "show",
87
+ "params": [
88
+ {
89
+ "allow_nil": false,
90
+ "description": "",
91
+ "expected_type": "string",
92
+ "full_name": "id",
93
+ "name": "id",
94
+ "required": true,
95
+ "validator": "Must be an identifier, string from 1 to 128 characters containing only alphanumeric characters, space, underscore(_), hypen(-) with no leading or trailing space."
96
+ }
97
+ ],
98
+ "see": []
99
+ },
100
+ {
101
+ "apis": [
102
+ {
103
+ "api_url": "/api/architectures",
104
+ "http_method": "POST",
105
+ "short_description": "Create an architecture."
106
+ }
107
+ ],
108
+ "doc_url": "/apidoc/v2/architectures/create",
109
+ "errors": [],
110
+ "examples": [
111
+ "POST /api/architectures\n{\n \"architecture\": {\n \"name\": \"i386\"\n }\n}\n200\n{\n \"architecture\": {\n \"name\": \"i386\",\n \"id\": 501905020,\n \"updated_at\": \"2012-12-18T15:24:43Z\",\n \"operatingsystem_ids\": [],\n \"created_at\": \"2012-12-18T15:24:43Z\"\n }\n}"
112
+ ],
113
+ "formats": null,
114
+ "full_description": "",
115
+ "name": "create",
116
+ "params": [
117
+ {
118
+ "allow_nil": false,
119
+ "description": "",
120
+ "expected_type": "hash",
121
+ "full_name": "architecture",
122
+ "name": "architecture",
123
+ "params": [
124
+ {
125
+ "allow_nil": false,
126
+ "description": "",
127
+ "expected_type": "string",
128
+ "full_name": "architecture[name]",
129
+ "name": "name",
130
+ "required": true,
131
+ "validator": "Must be String"
132
+ },
133
+ {
134
+ "allow_nil": false,
135
+ "description": "\n<p>Operatingsystem ID\u2019s</p>\n",
136
+ "expected_type": "array",
137
+ "full_name": "architecture[operatingsystem_ids]",
138
+ "name": "operatingsystem_ids",
139
+ "required": false,
140
+ "validator": "Must be Array"
141
+ }
142
+ ],
143
+ "required": true,
144
+ "validator": "Must be a Hash"
145
+ }
146
+ ],
147
+ "see": []
148
+ }
149
+ ]
150
+ }
151
+ }
152
+ }
153
+ }
@@ -0,0 +1,79 @@
1
+ {
2
+ "docs": {
3
+ "name": "Documented",
4
+ "api_url": "/api",
5
+ "version": "v2",
6
+ "short_description": null,
7
+ "full_description": null,
8
+ "doc_url": "/apidoc/v2/documented",
9
+ "resources": {
10
+ "documented": {
11
+ "methods": [
12
+ {
13
+ "name": "index",
14
+ "examples": [],
15
+ "errors": [],
16
+ "params": [
17
+ {
18
+ "allow_null": false,
19
+ "name": "se_arch_val-ue",
20
+ "full_name": "se_arch_val-ue_full_name",
21
+ "validator": "Must be String",
22
+ "description": "<p>filter results</p>",
23
+ "expected_type": "string",
24
+ "required": false
25
+ }
26
+ ],
27
+ "full_description": ""
28
+ },
29
+ {
30
+ "name": "create",
31
+ "examples": [],
32
+ "errors": [],
33
+ "params": [
34
+ {
35
+ "allow_null": false,
36
+ "name": "documented",
37
+ "full_name": "documented",
38
+ "validator": "Must be a Hash",
39
+ "description": "",
40
+ "expected_type": "hash",
41
+ "required": true,
42
+ "params": [
43
+ {
44
+ "name": "name",
45
+ "allow_null": false,
46
+ "full_name": "documented[name]",
47
+ "validator": "Must be String",
48
+ "expected_type": "string",
49
+ "description": "",
50
+ "required": false
51
+ },
52
+ {
53
+ "name": "provider",
54
+ "allow_null": false,
55
+ "full_name": "documented[provider]",
56
+ "validator": "Must be String",
57
+ "expected_type": "string",
58
+ "description": "<p>Providers include Libvirt, Ovirt, EC2, Vmware, Openstack, Rackspace</p>",
59
+ "required": false
60
+ },
61
+ {
62
+ "name": "array_param",
63
+ "allow_null": false,
64
+ "full_name": "documented[array_param]",
65
+ "validator": "Must be Array",
66
+ "expected_type": "string",
67
+ "description": "",
68
+ "required": true
69
+ }
70
+ ]
71
+ }
72
+ ],
73
+ "full_description": ""
74
+ }
75
+ ]
76
+ }
77
+ }
78
+ }
79
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ units:[
3
+ {
4
+ name:zip,
5
+ version:10.0
6
+ },
7
+ {
8
+ name:zap,
9
+ version:9.0
10
+ }
11
+ ]
12
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "units":[
3
+ {
4
+ "name":"zip",
5
+ "version":"10.0"
6
+ },
7
+ {
8
+ "name":"zap",
9
+ "version":"9.0"
10
+ }
11
+ ]
12
+ }
@@ -0,0 +1,71 @@
1
+ require 'tempfile'
2
+
3
+ describe HammerCLI::ShellHistory do
4
+
5
+ before :each do
6
+ # Readline::HISOTRY does not implement #clear in Ruby 1.8
7
+ while not Readline::HISTORY.empty?
8
+ Readline::HISTORY.pop
9
+ end
10
+ end
11
+
12
+ let :history_file do
13
+ file = Tempfile.new('history')
14
+ file.puts "line 1"
15
+ file.puts "line 2"
16
+ file.close
17
+ file
18
+ end
19
+
20
+ let :new_file do
21
+ Tempfile.new('history')
22
+ end
23
+
24
+ describe "loading old history" do
25
+
26
+ it "skips loading if the file does not exist" do
27
+ history = HammerCLI::ShellHistory.new(new_file.path)
28
+
29
+ Readline::HISTORY.to_a.must_equal []
30
+ end
31
+
32
+ it "preseeds readline's history" do
33
+ history = HammerCLI::ShellHistory.new(history_file.path)
34
+
35
+ Readline::HISTORY.to_a.must_equal ["line 1", "line 2"]
36
+ end
37
+ end
38
+
39
+ describe "saving history" do
40
+ it "creates history file if it does not exist" do
41
+ history = HammerCLI::ShellHistory.new(new_file.path)
42
+ history.push("some command ")
43
+
44
+ File.exist?(new_file.path).must_equal true
45
+ end
46
+
47
+ it "appends history to the given file" do
48
+ history = HammerCLI::ShellHistory.new(new_file.path)
49
+ history.push("some command ")
50
+ history.push("another command ")
51
+
52
+ new_file.read.must_equal "some command\nanother command\n"
53
+ end
54
+
55
+ it "appends to readline's history" do
56
+ history = HammerCLI::ShellHistory.new(history_file.path)
57
+ history.push("line 3")
58
+
59
+ Readline::HISTORY.to_a.must_equal ["line 1", "line 2", "line 3"]
60
+ end
61
+
62
+ it "doesn't save exit command" do
63
+ history = HammerCLI::ShellHistory.new(history_file.path)
64
+ history.push("exit ")
65
+
66
+ Readline::HISTORY.to_a.must_equal ["line 1", "line 2"]
67
+ end
68
+ end
69
+
70
+ end
71
+
@@ -41,6 +41,15 @@ describe HammerCLI::MainCommand do
41
41
  end
42
42
 
43
43
 
44
+ describe "verbose" do
45
+
46
+ it "stores into context" do
47
+ cmd.run(["-v"])
48
+ context[:verbose].must_equal true
49
+ end
50
+
51
+ end
52
+
44
53
  end
45
54
 
46
55
  end
@@ -18,7 +18,8 @@ describe HammerCLI::Modules do
18
18
  before :each do
19
19
  HammerCLI::Settings.clear
20
20
  HammerCLI::Settings.load({
21
- :modules => ["hammer_cli_tom", "hammer_cli_jerry"]
21
+ :tom => { :enable_module => true },
22
+ :jerry => { :enable_module => true },
22
23
  })
23
24
 
24
25
  @log_output = Logging::Appenders['__test__']
@@ -27,13 +28,22 @@ describe HammerCLI::Modules do
27
28
 
28
29
  describe "names" do
29
30
  it "must return list of modules" do
30
- HammerCLI::Modules.names.must_equal ["hammer_cli_tom", "hammer_cli_jerry"]
31
+ HammerCLI::Modules.names.sort.must_equal ["hammer_cli_tom", "hammer_cli_jerry"].sort
31
32
  end
32
33
 
33
34
  it "must return empty array by default" do
34
35
  HammerCLI::Settings.clear
35
36
  HammerCLI::Modules.names.must_equal []
36
37
  end
38
+
39
+ it "must work with old modules config" do
40
+ HammerCLI::Settings.clear
41
+ HammerCLI::Settings.load({
42
+ :tom => {},
43
+ :modules => ['hammer_cli_tom', 'hammer_cli_jerry'],
44
+ })
45
+ HammerCLI::Modules.names.sort.must_equal ["hammer_cli_tom", "hammer_cli_jerry"].sort
46
+ end
37
47
  end
38
48
 
39
49
  describe "find by name" do
@@ -89,21 +99,27 @@ describe HammerCLI::Modules do
89
99
  describe "module not found" do
90
100
  before :each do
91
101
  HammerCLI::Modules.stubs(:require_module).raises(LoadError)
92
- @error_msg = "ERROR Modules : Module hammer_cli_tom not found"
102
+ @error_msg = "ERROR Modules : Error while loading module hammer_cli_tom"
93
103
  end
94
104
 
95
105
  it "must log an error if the load! fails" do
96
- proc { HammerCLI::Modules.load!("hammer_cli_tom") }.must_raise LoadError
106
+ capture_io do
107
+ proc { HammerCLI::Modules.load!("hammer_cli_tom") }.must_raise LoadError
108
+ end
97
109
  @log_output.readline.strip.must_equal @error_msg
98
110
  end
99
111
 
100
112
  it "must log an error if the load fails" do
101
- HammerCLI::Modules.load("hammer_cli_tom")
113
+ capture_io do
114
+ HammerCLI::Modules.load("hammer_cli_tom")
115
+ end
102
116
  @log_output.readline.strip.must_equal @error_msg
103
117
  end
104
118
 
105
119
  it "must return false when load fails" do
106
- HammerCLI::Modules.load("hammer_cli_tom").must_equal false
120
+ capture_io do
121
+ HammerCLI::Modules.load("hammer_cli_tom").must_equal false
122
+ end
107
123
  end
108
124
  end
109
125