knife-role-spaghetti 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/.travis.yml CHANGED
@@ -3,5 +3,4 @@ rvm:
3
3
  - 1.9.2
4
4
  - 1.9.3
5
5
  env:
6
- - CHEF_VERSION=0.10.8
7
6
  - CHEF_VERSION=10.12.0
data/README.md CHANGED
@@ -69,6 +69,13 @@ Running through the neato renderer (with the `-N` switch) produces this image:
69
69
 
70
70
  ## Changelog
71
71
 
72
+ ### v0.0.3
73
+ * Fixed JSON roles loading #7 - Thanks @miah & @tezz!
74
+ * Re-implemented the DRY proposed by @jtimberman in #1, with a different method
75
+ * Prevent a role and recipe sharing the same name from colliding
76
+ * Figured out correct testing requirements matrix for Travis
77
+ * Added some more verbose logging options
78
+
72
79
  ### v0.0.2
73
80
  * Updated CLI banner to reflect that filename is not required, renamed for clarity
74
81
  * Improved handling cases where a role contains recipes named the same as the role
data/features/cli.feature CHANGED
@@ -6,7 +6,7 @@ Feature: Ensure that the Command Line Interface works as designed
6
6
  Background:
7
7
  Given a file named ".chef/knife.rb" with:
8
8
  """
9
- role_path ["#{File.dirname(__FILE__)}/../roles"]
9
+ role_path "#{File.dirname(__FILE__)}/../roles"
10
10
  """
11
11
  And a file named "roles/webserver.rb" with:
12
12
  """
@@ -64,3 +64,13 @@ Scenario: Running with no filename, the format flag and no format, should fail
64
64
  Scenario: Running with no filename, the format flag and no format, should fail
65
65
  When I run `knife role spaghetti failfile.png -G`
66
66
  Then the exit status should be 1
67
+
68
+ Scenario: Running with verbose flags provides better output
69
+ When I successfully run `knife role spaghetti verbose.png -VV`
70
+ Then the output should contain:
71
+ """
72
+ DEBUG: Output format is: png
73
+ DEBUG: Output filename is: verbose.png
74
+ DEBUG: Loaded role is: role[webserver]
75
+ A Role dependency graph has been written to verbose.png
76
+ """
@@ -21,7 +21,7 @@ Scenario: Running against a knife.rb with undefined roles directory should fail
21
21
  Scenario: Running against a directory with multiple roles succeeds
22
22
  Given a file named ".chef/knife.rb" with:
23
23
  """
24
- role_path ["#{File.dirname(__FILE__)}/../roles"]
24
+ role_path "#{File.dirname(__FILE__)}/../roles"
25
25
  """
26
26
  And a file named "roles/webserver.rb" with:
27
27
  """
@@ -57,7 +57,7 @@ Scenario: Running against a directory with multiple roles succeeds
57
57
  Scenario: Running against embedded roles succeeds
58
58
  Given a file named ".chef/knife.rb" with:
59
59
  """
60
- role_path ["#{File.dirname(__FILE__)}/../roles"]
60
+ role_path "#{File.dirname(__FILE__)}/../roles"
61
61
  """
62
62
  And a file named "roles/webserver.rb" with:
63
63
  """
@@ -86,3 +86,40 @@ Scenario: Running against embedded roles succeeds
86
86
  """
87
87
  When I successfully run `knife role spaghetti embedded.png`
88
88
  Then the exit status should be 0
89
+
90
+ Scenario: Running against only json role files succeeds.
91
+ Given a file named ".chef/knife.rb" with:
92
+ """
93
+ role_path "#{File.dirname(__FILE__)}/../roles"
94
+ """
95
+ And a file named "roles/webserver.json" with:
96
+ """
97
+ {
98
+ "name": "webserver",
99
+ "chef_type": "role",
100
+ "json_class": "Chef::Role",
101
+ "default_attributes": {
102
+ "apache2": {
103
+ "listen_ports": [
104
+ "80",
105
+ "443"
106
+ ]
107
+ }
108
+ },
109
+ "description": "The base role for systems that serve HTTP traffic",
110
+ "run_list": [
111
+ "recipe[apache2]",
112
+ "recipe[apache2::mod_ssl]",
113
+ "role[monitor]"
114
+ ],
115
+ "env_run_lists" : {
116
+ },
117
+ "override_attributes": {
118
+ "apache2": {
119
+ "max_children": "50"
120
+ }
121
+ }
122
+ }
123
+ """
124
+ When I successfully run `knife role spaghetti webserver.png`
125
+ Then the exit status should be 0
@@ -5,6 +5,7 @@ module KnifeRoleSpaghetti
5
5
 
6
6
  deps do
7
7
  require 'chef/role'
8
+ require 'chef/knife/core/object_loader'
8
9
  require 'graphviz'
9
10
  end
10
11
 
@@ -25,18 +26,23 @@ module KnifeRoleSpaghetti
25
26
 
26
27
  # OPTIMIZE: Add an option to display cookbooks instead of recipes?
27
28
 
29
+ def loader
30
+ @loader ||= Chef::Knife::Core::ObjectLoader.new(Chef::Role, ui)
31
+ end
32
+
28
33
  def run
29
34
 
30
35
  self.config = Chef::Config.merge!(config)
31
36
 
32
37
  # OPTIMIZE: Maybe instead of a flag, infer the graph format from fileext?
33
38
 
34
- # Parse the configuration options, provide defaults where needed
39
+ # Parse the configuration options, provide defaults where needed
35
40
  if config[:graphformat]
36
41
  output_format = config[:graphformat].to_sym
37
42
  else
38
43
  output_format = :png
39
44
  end
45
+ Chef::Log.debug("Output format is: #{output_format}")
40
46
 
41
47
  # Determine of a filename has been passed
42
48
  if @name_args.size >= 1
@@ -44,9 +50,12 @@ module KnifeRoleSpaghetti
44
50
  else
45
51
  filename = "role-spaghetti.#{output_format}"
46
52
  end
53
+ Chef::Log.debug("Output filename is: #{filename}")
54
+
55
+ loaded_roles = loader.find_all_objects(config[:role_path])
47
56
 
48
57
  # If we can't find any roles, it's pointless to continue.
49
- if Dir.glob(File.join(Chef::Config.role_path, '*.rb')).size == 0
58
+ if loaded_roles.size == 0
50
59
  ui.fatal("No roles were found in role_path: #{config[:role_path]}")
51
60
  ui.fatal("Ensure that your knife.rb has the correct path.")
52
61
  exit 1
@@ -60,18 +69,14 @@ module KnifeRoleSpaghetti
60
69
  :compound => "true"
61
70
  )
62
71
 
63
- Dir.glob(File.join(Chef::Config.role_path, '*.{rb,json}')) do |role_file|
72
+ loaded_roles.each do |role_file|
73
+ # Create an absolute path, since some file references include relative paths
74
+ abspath = File.absolute_path(File.join(config[:role_path], role_file))
64
75
 
65
- role = Chef::Role.new
76
+ # The object_from_file method figures out the ruby/json logic
77
+ role = loader.object_from_file(abspath)
66
78
 
67
- if File.extname(role_file) == '.rb'
68
- role.from_file(role_file)
69
- elsif File.extname(role_file) == '.json'
70
- js_file = Chef::JSONCompat.from_json(IO.read(role_file))
71
- role = Chef::Role.json_create(js_file)
72
- else
73
- ui.error("This shouldn't happen, the file must be either rb or json")
74
- end
79
+ Chef::Log.debug("Loaded role is: #{role}")
75
80
 
76
81
  # OPTIMIZE: Handle environment run_lists
77
82
 
@@ -87,12 +92,13 @@ module KnifeRoleSpaghetti
87
92
  g.node[:shape] = "box"
88
93
  g.node[:style] = "rounded"
89
94
  g.node[:color] = "red"
95
+ rli_node = g.add_nodes("#{rli.name}_role", :label => rli.name)
90
96
  else
91
97
  g.node[:shape] = "component"
92
98
  g.node[:color] = "blue"
99
+ rli_node = g.add_nodes(rli.name)
93
100
  end
94
101
 
95
- rli_node = g.add_nodes(rli.name)
96
102
  g.add_edges(role_node, rli_node)
97
103
  end
98
104
 
@@ -1,3 +1,3 @@
1
1
  module KnifeRoleSpaghetti
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: knife-role-spaghetti
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-21 00:00:00.000000000 Z
12
+ date: 2012-08-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: chef
@@ -162,7 +162,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
162
162
  version: '0'
163
163
  requirements: []
164
164
  rubyforge_project:
165
- rubygems_version: 1.8.24
165
+ rubygems_version: 1.8.23
166
166
  signing_key:
167
167
  specification_version: 3
168
168
  summary: Cut through the Role spaghetti with a Knife, Chef.