knife-role-spaghetti 0.0.2 → 0.0.3

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.
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.