hammer_cli 0.0.18 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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