chef_attrdoc 0.9.2 → 1.0.0.pre

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 ADDED
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.0
4
+ - 1.9.3
5
+ - jruby-19mode # JRuby in 1.9 mode
6
+ before_script:
7
+ - gem install bundler
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ # A sample Gemfile
2
+ source "https://rubygems.org"
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,30 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ chef_attrdoc (0.9.2)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ diff-lcs (1.2.5)
10
+ rake (10.3.2)
11
+ rspec (3.0.0)
12
+ rspec-core (~> 3.0.0)
13
+ rspec-expectations (~> 3.0.0)
14
+ rspec-mocks (~> 3.0.0)
15
+ rspec-core (3.0.2)
16
+ rspec-support (~> 3.0.0)
17
+ rspec-expectations (3.0.2)
18
+ diff-lcs (>= 1.2.0, < 2.0)
19
+ rspec-support (~> 3.0.0)
20
+ rspec-mocks (3.0.2)
21
+ rspec-support (~> 3.0.0)
22
+ rspec-support (3.0.2)
23
+
24
+ PLATFORMS
25
+ ruby
26
+
27
+ DEPENDENCIES
28
+ chef_attrdoc!
29
+ rake
30
+ rspec
data/README.md CHANGED
@@ -1,29 +1,74 @@
1
1
  chef_attrdoc
2
2
  ============
3
3
  [![Gem Version](https://badge.fury.io/rb/chef_attrdoc.png)](http://badge.fury.io/rb/chef_attrdoc)
4
+ [![Build Status](https://travis-ci.org/mapleoin/chef_attrdoc.svg?branch=master)](https://travis-ci.org/mapleoin/chef_attrdoc)
4
5
  [![Code Climate](https://codeclimate.com/github/mapleoin/chef_attrdoc.png)](https://codeclimate.com/github/mapleoin/chef_attrdoc)
5
6
 
6
7
  Extract documentation from chef cookbooks' attributes files and output it to the cookbook's README.md file.
7
8
 
8
-
9
9
  `chef_attrdoc` groups attribute initialization lines together with the comments immediately above them. Any lines containing an attribute initialization which are not separated by an empty line are considered a group. The comment immediately above them is assumed to describe the group of attributes below. Groups of attribute initialization lines which are not immediately preceded by a comment line are ignored and will not show up in the output.
10
10
 
11
11
  chef_attrdoc currently ignores *TODO*, *XXX*, *NOTE* and *foodcritic* comments.
12
12
 
13
13
  ### Usage:
14
14
 
15
- ```
16
- # gem install chef_attrdoc
17
- # chef_attrdoc ~/cookbooks/mycookbook
15
+ ```bash
16
+ $ gem install chef_attrdoc
17
+ $ chef_attrdoc ~/cookbooks/mycookbook
18
18
  ```
19
19
 
20
- `chef_attrdoc` will try to find an Attributes heading in the README.md file in that directory and replace its contents with the generated `attributes/default.rb` documentation.
20
+ `chef_attrdoc` will try to find an Attributes heading in the README.md file in that directory and replace its contents with the generated attributes documentation. The attributes documentation is compiled from all the files in the cookbook's `attributes/` directory. All the files ending in `.rb` in that directory are considered to be attributes files.
21
21
 
22
22
  `chef_attrdoc` uses ruby's stdlib `ripper` module and so does not have any dependencies.
23
23
 
24
+ `chef_attrdoc` currently requires `ruby >= 1.9`.
25
+
24
26
  ### Examples
25
27
 
26
- Here are some example outputs from openstack chef cookbooks:
28
+ ```bash
29
+ $ cat cookbook-example/attributes/default.rb
30
+ ```
31
+ # Copyright 1970, nobody
32
+
33
+ # this is the attribute
34
+ default['some']['attribute'] = 'foo'
35
+
36
+ default['this']['will']['be'] = 'ignored'
37
+
38
+ # NOTE code blocks without a comment are ignored as are those beginning
39
+ # NOTE with 'NOTE', 'XXX', 'TODO' or foodcritic comments
40
+
41
+ # a longer block of code
42
+ case something
43
+ when 'foo'
44
+ default['some']['foo'] = 'baz'
45
+ else
46
+ default['some']['foo'] = 'qux'
47
+ end
48
+ ```bash
49
+ $ chef_attrdoc cookbook-example --stdout
50
+ ```
51
+ ```
52
+ ## default.rb
53
+
54
+ this is the attribute
55
+
56
+ ```ruby
57
+ default['some']['attribute'] = 'foo'
58
+ ```
59
+
60
+ a longer block of code
61
+
62
+ ```ruby
63
+ case something
64
+ when 'foo'
65
+ default['some']['foo'] = 'baz'
66
+ else
67
+ default['some']['foo'] = 'qux'
68
+ end
69
+ ```
70
+
71
+ Here are some longer examples from openstack chef cookbooks:
27
72
 
28
73
  [openstack-compute attributes file](https://github.com/stackforge/cookbook-openstack-compute/blob/aa42f5c09a445cde7267e4b4d00a6ce893aa481e/attributes/default.rb) - [output](https://gist.github.com/mapleoin/6886586)
29
74
 
data/Rakefile CHANGED
@@ -1 +1,11 @@
1
- require "bundler/gem_tasks"
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:test) do |t|
5
+ t.rspec_opts = [].tap do |a|
6
+ a.push('--color')
7
+ a.push('--format progress')
8
+ end.join(' ')
9
+ end
10
+
11
+ task :default => [:test]
data/bin/chef_attrdoc CHANGED
@@ -31,28 +31,20 @@ opt_parser = OptionParser.new do |opts|
31
31
  end
32
32
  end.parse!
33
33
 
34
- file_path = ["attributes", "default.rb"]
34
+ dir_path = ["attributes"]
35
35
  unless ARGV.empty?
36
- file_path.unshift ARGV[0]
36
+ dir_path.unshift ARGV[0]
37
37
  unless options[:stdout]
38
38
  options[:readme] = File.join(ARGV[0], options[:readme])
39
39
  end
40
40
  end
41
- file_path = File.join file_path
42
41
 
43
42
  begin
44
- contents = IO.read(file_path)
45
- rescue Exception => e
46
- puts e.message
47
- exit
48
- end
49
-
50
- begin
51
- attrs = ChefAttrdoc::AttributesFile.new contents
43
+ attrs = ChefAttrdoc.process_attributes dir_path
52
44
  if options[:stdout]
53
- puts attrs.to_s
45
+ puts attrs
54
46
  else
55
- attrs.to_readme options[:readme]
47
+ ChefAttrdoc.write_readme options[:readme], attrs
56
48
  end
57
49
  rescue Exception => e
58
50
  if options[:debug]
data/chef_attrdoc.gemspec CHANGED
@@ -17,4 +17,7 @@ Gem::Specification.new do |spec|
17
17
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency 'rake'
22
+ spec.add_development_dependency 'rspec'
20
23
  end
@@ -1,3 +1,3 @@
1
1
  module ChefAttrdoc
2
- VERSION = "0.9.2"
2
+ VERSION = "1.0.0.pre"
3
3
  end
data/lib/chef_attrdoc.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
- # Copyright 2013, Ionuț Arțăriși <ionut@artarisi.eu>
3
+ # Copyright 2013-2014, Ionuț Arțăriși <ionut@artarisi.eu>
4
4
  #
5
5
  # Licensed under the Apache License, Version 2.0 (the "License");
6
6
  # you may not use this file except in compliance with the License.
@@ -130,28 +130,65 @@ module ChefAttrdoc
130
130
  end
131
131
  strings.join
132
132
  end
133
+ end
133
134
 
134
- def to_readme(readme)
135
- File.open(readme, File::RDWR) do |f|
136
- # XXX find a cleaner way and do this in one step
137
- content = f.read
138
- if content =~ /\nAttributes\s*=+\s*\n/
139
- updated = content.gsub(/(.*\nAttributes\s*=+\s*\n)(.+?)(\n\w+\s*\n=+.*)/m,
140
- '\1CHEF_ATTRDOC_UPDATING_TEMPLATE\3')
141
- elsif content =~ /\n[#]+\s*Attributes\s*\n/
142
- updated = content.gsub(/(?<before>.*\n(?<header>[#]+)\s*Attributes\s*\n)(.+?)(?<after>\n\k<header>\s*\w+\s*\n.*)/m,
143
- '\k<before>CHEF_ATTRDOC_UPDATING_TEMPLATE\k<after>')
144
- else
145
- raise StandardError, "Could not find Attributes heading in #{readme}. Please make sure your README file has proper markdown formatting and includes an Attributes heading."
146
- end
135
+ # open the :readme: Markdown file and replace the 'Attributes' section
136
+ # with the contents of :parsed:
137
+ def self.write_readme(readme, parsed)
138
+ File.open(readme, File::RDWR) do |f|
139
+ # TODO find a cleaner way and do this in one step
140
+ content = f.read
141
+ if content =~ /\nAttributes\s*=+\s*\n/
142
+ updated = content.gsub(/(?<before>.*\nAttributes\s*=+\s*\n)(?m:.+?)(?<after>\n.+\s*\n=+.*)/,
143
+ '\k<before>CHEF_ATTRDOC_UPDATING_TEMPLATE\k<after>')
144
+
145
+ # XXX hack because I couldn't figure out how to get another
146
+ # newline in between the <before> and the content
147
+ updated.sub!('CHEF_ATTRDOC_UPDATING_TEMPLATE',
148
+ "\nCHEF_ATTRDOC_UPDATING_TEMPLATE")
149
+ elsif content =~ /\n\#+\s*Attributes\s*\n/
150
+ updated = content.gsub(/(?<before>.*\n\#+\s*Attributes\s*\n)(.+?)(?<after>\n\#+.*)/m,
151
+ '\k<before>CHEF_ATTRDOC_UPDATING_TEMPLATE\k<after>')
152
+ else
153
+ raise StandardError, "Could not find Attributes heading in #{readme}. Please make sure your README file has proper markdown formatting and includes an Attributes heading."
154
+ end
155
+
156
+ updated.sub! 'CHEF_ATTRDOC_UPDATING_TEMPLATE', parsed
157
+ f.rewind
158
+ f.write(updated)
159
+ f.flush
160
+ f.truncate(f.pos)
161
+ end
162
+ end
147
163
 
148
- updated.sub! 'CHEF_ATTRDOC_UPDATING_TEMPLATE', self.to_s
149
- f.rewind
150
- f.write(updated)
151
- f.flush
152
- f.truncate(f.pos)
164
+ # return a list of [filename, file-contents] for each ruby file in :dir:
165
+ def self.attrs_contents(dir)
166
+ files_contents = []
167
+ filenames = Dir.glob(File.join(dir, '*.rb')).sort
168
+
169
+ filenames.each do |f|
170
+ begin
171
+ files_contents << [File.basename(f), IO.read(f)]
172
+ rescue Exception => e
173
+ abort e.message
153
174
  end
154
175
  end
176
+
177
+ files_contents
178
+ end
179
+
180
+ # takes a directory of attributes files and returns a string with
181
+ # Markdown content with the output of processing all the attributes
182
+ def self.process_attributes(dir)
183
+ files_contents = ChefAttrdoc.attrs_contents dir
184
+
185
+ output = []
186
+ files_contents.each do |filename, contents|
187
+ attrs = ChefAttrdoc::AttributesFile.new contents
188
+ output << "## #{filename}\n\n#{attrs}"
189
+ end
190
+
191
+ output.join("\n")
155
192
  end
156
193
  end
157
194
 
@@ -0,0 +1,276 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # Copyright 2014, Ionuț Arțăriși <ionut@artarisi.eu>
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ require 'chef_attrdoc'
19
+
20
+
21
+ describe ChefAttrdoc::AttributesFile do
22
+ ["TODO bar", "XXX foo bar", "NOTE(me) nasty bug",
23
+ ":pragma-foodcritic: ~FC024 - won't fix this"].each do |comm|
24
+ it "ignores \"#{comm}\" comment" do
25
+ text = <<END
26
+ # #{comm}
27
+ # good comment
28
+ default[good] = 'comment'
29
+ END
30
+ ca = ChefAttrdoc::AttributesFile.new(text)
31
+ expect(ca.to_s).to eq(<<-OUTPUT)
32
+ good comment
33
+
34
+ ```ruby
35
+ default[good] = 'comment'
36
+ ```
37
+
38
+ OUTPUT
39
+ end
40
+ end
41
+
42
+ it 'groups comments and several lines of code together' do
43
+ text = <<END
44
+ # first block
45
+ default[foo] = 'bar'
46
+ default[bar] = 'baz'
47
+
48
+ # second block
49
+ node.set[baz] = 'qux'
50
+ node.set[foo] = 'qux'
51
+ node.set[bar] = 'qux'
52
+ END
53
+ ca = ChefAttrdoc::AttributesFile.new(text)
54
+ expect(ca.to_s).to eq(<<-OUTPUT)
55
+ first block
56
+
57
+ ```ruby
58
+ default[foo] = 'bar'
59
+ default[bar] = 'baz'
60
+ ```
61
+
62
+ second block
63
+
64
+ ```ruby
65
+ node.set[baz] = 'qux'
66
+ node.set[foo] = 'qux'
67
+ node.set[bar] = 'qux'
68
+ ```
69
+
70
+ OUTPUT
71
+ end
72
+
73
+ it 'ignores code without comments' do
74
+ text = <<END
75
+ # first block
76
+ default[foo] = 'bar'
77
+ default[bar] = 'baz'
78
+
79
+ default[ignored] = false
80
+
81
+ # second block
82
+ node.set[baz] = 'qux'
83
+ END
84
+ ca = ChefAttrdoc::AttributesFile.new(text)
85
+ expect(ca.to_s).to eq(<<-OUTPUT)
86
+ first block
87
+
88
+ ```ruby
89
+ default[foo] = 'bar'
90
+ default[bar] = 'baz'
91
+ ```
92
+
93
+ second block
94
+
95
+ ```ruby
96
+ node.set[baz] = 'qux'
97
+ ```
98
+
99
+ OUTPUT
100
+ end
101
+
102
+ it 'ignores the first comments in a file' do
103
+ ca = ChefAttrdoc::AttributesFile.new(<<-INPUT)
104
+ #!/she/bang
105
+
106
+ # Copyright
107
+ # foo
108
+
109
+ # this is important
110
+ default[foo] = 'bar'
111
+ INPUT
112
+
113
+ expect(ca.to_s).to eq(<<-OUTPUT)
114
+ this is important
115
+
116
+ ```ruby
117
+ default[foo] = 'bar'
118
+ ```
119
+
120
+ OUTPUT
121
+ end
122
+
123
+ it 'handles platform group with lots of branches and hashes' do
124
+ text = <<END
125
+ # platform specific attributes
126
+ case platform
127
+ when "fedora", "redhat", "centos"
128
+ default["openstack"]["identity"]["user"] = "keystone"
129
+ default["openstack"]["identity"]["group"] = "keystone"
130
+ default["openstack"]["identity"]["platform"] = {
131
+ "memcache_python_packages" => [ "python-memcached" ],
132
+ "keystone_packages" => [ "openstack-keystone" ],
133
+ "keystone_process_name" => "keystone-all",
134
+ "package_options" => ""
135
+ }
136
+ when "suse"
137
+ default["openstack"]["identity"]["user"] = "openstack-keystone"
138
+ default["openstack"]["identity"]["platform"] = {
139
+ "mysql_python_packages" => [ "python-mysql" ],
140
+ "memcache_python_packages" => [ "python-python-memcached" ],
141
+ "keystone_process_name" => "keystone-all",
142
+ "package_options" => ""
143
+ }
144
+ END
145
+ ca = ChefAttrdoc::AttributesFile.new(text)
146
+ expect(ca.to_s).to eq(<<-END)
147
+ platform specific attributes
148
+
149
+ ```ruby
150
+ case platform
151
+ when "fedora", "redhat", "centos"
152
+ default["openstack"]["identity"]["user"] = "keystone"
153
+ default["openstack"]["identity"]["group"] = "keystone"
154
+ default["openstack"]["identity"]["platform"] = {
155
+ "memcache_python_packages" => [ "python-memcached" ],
156
+ "keystone_packages" => [ "openstack-keystone" ],
157
+ "keystone_process_name" => "keystone-all",
158
+ "package_options" => ""
159
+ }
160
+ when "suse"
161
+ default["openstack"]["identity"]["user"] = "openstack-keystone"
162
+ default["openstack"]["identity"]["platform"] = {
163
+ "mysql_python_packages" => [ "python-mysql" ],
164
+ "memcache_python_packages" => [ "python-python-memcached" ],
165
+ "keystone_process_name" => "keystone-all",
166
+ "package_options" => ""
167
+ }
168
+ ```
169
+
170
+ END
171
+ end
172
+
173
+ it 'handles comments over several lines which include blank lines' do
174
+ text = <<END
175
+ # my comment
176
+ #
177
+ # continued comment
178
+ #
179
+ default["some"]["actual"]["code"] = 42
180
+ END
181
+ ca = ChefAttrdoc::AttributesFile.new(text)
182
+ expect(ca.to_s).to eq(<<-END)
183
+ my comment
184
+
185
+ continued comment
186
+
187
+
188
+ ```ruby
189
+ default["some"]["actual"]["code"] = 42
190
+ ```
191
+
192
+ END
193
+ end
194
+
195
+ it 'keeps good inline comments' do
196
+ ca = ChefAttrdoc::AttributesFile.new(<<-INPUT)
197
+ # my comment
198
+ default["ignored"]["thing"] = 33 # a useful inline comment
199
+ default["foo"] = "bar"
200
+ INPUT
201
+ expect(ca.to_s).to eq(<<-OUTPUT)
202
+ my comment
203
+
204
+ ```ruby
205
+ default["ignored"]["thing"] = 33 # a useful inline comment
206
+ default["foo"] = "bar"
207
+ ```
208
+
209
+ OUTPUT
210
+ end
211
+
212
+ it 'discards ignored inline comments' do
213
+ ca = ChefAttrdoc::AttributesFile.new(<<-INPUT)
214
+ # my comment
215
+ default["ignored"]["thing"] = 33 # TODO(tommy) an ignored inline comment
216
+ default["foo"] = "bar"
217
+ INPUT
218
+ expect(ca.to_s).to eq(<<-OUTPUT)
219
+ my comment
220
+
221
+ ```ruby
222
+ default["ignored"]["thing"] = 33
223
+ default["foo"] = "bar"
224
+ ```
225
+
226
+ OUTPUT
227
+ end
228
+
229
+ it 'ignores inline comments on code with no leading comments' do
230
+ ca = ChefAttrdoc::AttributesFile.new(<<-INPUT)
231
+ # something good
232
+ foo = bar
233
+
234
+ default['something'] = 'bad' # foo
235
+ default['just']['more'] = 'code'
236
+ INPUT
237
+ expect(ca.to_s).to eq(<<-OUTPUT)
238
+ something good
239
+
240
+ ```ruby
241
+ foo = bar
242
+ ```
243
+
244
+ OUTPUT
245
+ end
246
+
247
+ it 'uses isolated comment blocks' do
248
+ ca = ChefAttrdoc::AttributesFile.new(<<-INPUT)
249
+ # foo bar
250
+ foo = bar
251
+
252
+ # comment we want to keep
253
+ # still good
254
+
255
+ # foo bar
256
+ foo = bar
257
+ INPUT
258
+ expect(ca.to_s).to eq(<<-OUTPUT)
259
+ foo bar
260
+
261
+ ```ruby
262
+ foo = bar
263
+ ```
264
+
265
+ comment we want to keep
266
+ still good
267
+
268
+ foo bar
269
+
270
+ ```ruby
271
+ foo = bar
272
+ ```
273
+
274
+ OUTPUT
275
+ end
276
+ end
@@ -19,227 +19,96 @@ require 'chef_attrdoc'
19
19
 
20
20
 
21
21
  describe ChefAttrdoc do
22
- ["TODO bar", "XXX foo bar", "NOTE(me) nasty bug",
23
- ":pragma-foodcritic: ~FC024 - won't fix this"].each do |comm|
24
- it "ignores \"#{comm}\" comment" do
25
- text = <<END
26
- # #{comm}
27
- # good comment
28
- default[good] = 'comment'
29
- END
30
- ca = ChefAttrdoc::AttributesFile.new(text)
31
- expect(ca.groups).to eq([["default[good] = 'comment'\n", "# good comment\n"]])
32
- end
33
- end
22
+ describe '#write_readme' do
23
+ context 'using Attributes\n========== syntax' do
24
+ it 'handles an Attributes section followed by a multiword header' do
25
+ readme = double('file').as_null_object
26
+ allow(readme).to receive(:read).and_return(<<-README)
34
27
 
35
- it "groups comments and several lines of code together" do
36
- text = <<END
37
- # first block
38
- default[foo] = 'bar'
39
- default[bar] = 'baz'
40
-
41
- # second block
42
- node.set[baz] = 'qux'
43
- node.set[foo] = 'qux'
44
- node.set[bar = 'qux'
45
- END
46
- ca = ChefAttrdoc::AttributesFile.new(text)
47
- expect(ca.groups).to eq([
48
- ["default[foo] = 'bar'\ndefault[bar] = 'baz'\n",
49
- "# first block\n"],
50
- ["node.set[baz] = 'qux'\nnode.set[foo] = 'qux'\nnode.set[bar = 'qux'\n",
51
- "# second block\n"]])
52
- end
28
+ Attributes
29
+ ==========
30
+ my attributes
53
31
 
54
- it "ignores code without comments" do
55
- text = <<END
56
- # first block
57
- default[foo] = 'bar'
58
- default[bar] = 'baz'
59
-
60
- default[ignored] = false
61
-
62
- # second block
63
- node.set[baz] = 'qux'
64
- END
65
- ca = ChefAttrdoc::AttributesFile.new(text)
66
- expect(ca.groups).to eq([
67
- ["default[foo] = 'bar'\ndefault[bar] = 'baz'\n", "# first block\n"],
68
- ["node.set[baz] = 'qux'\n", "# second block\n"]])
69
- end
32
+ are nice
70
33
 
71
- it "ignores the first comments in a file" do
72
- ca = ChefAttrdoc::AttributesFile.new(<<-INPUT)
73
- #!/she/bang
34
+ Another header
35
+ ==============
74
36
 
75
- # Copyright
76
- # foo
37
+ doc we won't touch
77
38
 
78
- # this is important
79
- default[foo] = 'bar'
80
- INPUT
39
+ README
40
+ allow(::File).to receive(:open).and_yield(readme)
41
+ expect(readme).to receive(:write).with(<<-README)
81
42
 
82
- expect(ca.to_s).to eq(<<-OUTPUT)
83
- this is important
43
+ Attributes
44
+ ==========
84
45
 
85
- ```ruby
86
- default[foo] = 'bar'
87
- ```
46
+ foo
88
47
 
89
- OUTPUT
90
- end
48
+ Another header
49
+ ==============
91
50
 
92
- it "handles platform group with lots of branches and hashes" do
93
- text = <<END
94
- # platform specific attributes
95
- case platform
96
- when "fedora", "redhat", "centos"
97
- default["openstack"]["identity"]["user"] = "keystone"
98
- default["openstack"]["identity"]["group"] = "keystone"
99
- default["openstack"]["identity"]["platform"] = {
100
- "memcache_python_packages" => [ "python-memcached" ],
101
- "keystone_packages" => [ "openstack-keystone" ],
102
- "keystone_process_name" => "keystone-all",
103
- "package_options" => ""
104
- }
105
- when "suse"
106
- default["openstack"]["identity"]["user"] = "openstack-keystone"
107
- default["openstack"]["identity"]["platform"] = {
108
- "mysql_python_packages" => [ "python-mysql" ],
109
- "memcache_python_packages" => [ "python-python-memcached" ],
110
- "keystone_process_name" => "keystone-all",
111
- "package_options" => ""
112
- }
113
- END
114
- ca = ChefAttrdoc::AttributesFile.new(text)
115
- expect(ca.to_s).to eq(<<-END)
116
- platform specific attributes
117
-
118
- ```ruby
119
- case platform
120
- when "fedora", "redhat", "centos"
121
- default["openstack"]["identity"]["user"] = "keystone"
122
- default["openstack"]["identity"]["group"] = "keystone"
123
- default["openstack"]["identity"]["platform"] = {
124
- "memcache_python_packages" => [ "python-memcached" ],
125
- "keystone_packages" => [ "openstack-keystone" ],
126
- "keystone_process_name" => "keystone-all",
127
- "package_options" => ""
128
- }
129
- when "suse"
130
- default["openstack"]["identity"]["user"] = "openstack-keystone"
131
- default["openstack"]["identity"]["platform"] = {
132
- "mysql_python_packages" => [ "python-mysql" ],
133
- "memcache_python_packages" => [ "python-python-memcached" ],
134
- "keystone_process_name" => "keystone-all",
135
- "package_options" => ""
136
- }
137
- ```
138
-
139
- END
140
- end
51
+ doc we won't touch
141
52
 
142
- it "handles comments over several lines which include blank lines" do
143
- text = <<END
144
- # my comment
145
- #
146
- # continued comment
147
- #
148
- default["some"]["actual"]["code"] = 42
149
- END
150
- ca = ChefAttrdoc::AttributesFile.new(text)
151
- expect(ca.to_s).to eq(<<-END)
152
- my comment
53
+ README
54
+ ChefAttrdoc.write_readme('filename', "foo\n")
55
+ end
56
+ end
57
+ context 'using ### Attributes syntax' do
58
+ it 'handles an Attributes section followed by a multiword header' do
59
+ readme = double('file').as_null_object
60
+ allow(readme).to receive(:read).and_return(<<-README)
153
61
 
154
- continued comment
62
+ ## Attributes
155
63
 
64
+ my attributes
156
65
 
157
- ```ruby
158
- default["some"]["actual"]["code"] = 42
159
- ```
66
+ are nice
160
67
 
161
- END
162
- end
68
+ ## Another header
163
69
 
164
- it "keeps good inline comments" do
165
- ca = ChefAttrdoc::AttributesFile.new(<<-INPUT)
166
- # my comment
167
- default["ignored"]["thing"] = 33 # a useful inline comment
168
- default["foo"] = "bar"
169
- INPUT
170
- expect(ca.to_s).to eq(<<-OUTPUT)
171
- my comment
70
+ doc we won't touch
71
+ README
72
+ allow(::File).to receive(:open).and_yield(readme)
73
+ expect(readme).to receive(:write).with(<<-README)
172
74
 
173
- ```ruby
174
- default["ignored"]["thing"] = 33 # a useful inline comment
175
- default["foo"] = "bar"
176
- ```
75
+ ## Attributes
177
76
 
178
- OUTPUT
179
- end
77
+ foo
180
78
 
181
- it "discards ignored inline comments" do
182
- ca = ChefAttrdoc::AttributesFile.new(<<-INPUT)
183
- # my comment
184
- default["ignored"]["thing"] = 33 # TODO(tommy) an ignored inline comment
185
- default["foo"] = "bar"
186
- INPUT
187
- expect(ca.to_s).to eq(<<-OUTPUT)
188
- my comment
79
+ ## Another header
189
80
 
190
- ```ruby
191
- default["ignored"]["thing"] = 33
192
- default["foo"] = "bar"
193
- ```
194
-
195
- OUTPUT
81
+ doc we won't touch
82
+ README
83
+ ChefAttrdoc.write_readme('filename', "foo\n")
84
+ end
85
+ end
196
86
  end
197
87
 
198
- it "ignores inline comments on code with no leading comments" do
199
- ca = ChefAttrdoc::AttributesFile.new(<<-INPUT)
200
- # something good
201
- foo = bar
202
-
203
- default['something'] = 'bad' # foo
204
- default['just']['more'] = 'code'
205
- INPUT
206
- expect(ca.to_s).to eq(<<-OUTPUT)
207
- something good
208
-
209
- ```ruby
210
- foo = bar
211
- ```
212
-
213
- OUTPUT
88
+ describe '#attrs_contents' do
89
+ it 'reads the files in the directory and returns their contents' do
90
+ expect(ChefAttrdoc.attrs_contents(['spec', 'fixtures']))
91
+ .to eq([["file1.rb", "foo\n"], ["file3.rb", "baz\n"]])
92
+ end
214
93
  end
215
94
 
216
- it "uses isolated comment blocks" do
217
- ca = ChefAttrdoc::AttributesFile.new(<<-INPUT)
218
- # foo bar
219
- foo = bar
220
-
221
- # comment we want to keep
222
- # still good
95
+ describe '#process_attributes' do
96
+ it 'reads the files in the directory and processes them' do
97
+ allow(ChefAttrdoc).to receive(:attrs_contents).with('foodir')
98
+ .and_return([["file1.rb", "foo\n"], ["file3.rb", "baz\n"]])
223
99
 
224
- # foo bar
225
- foo = bar
226
- INPUT
227
- expect(ca.to_s).to eq(<<-OUTPUT)
228
- foo bar
100
+ allow_any_instance_of(ChefAttrdoc::AttributesFile).to receive(:to_s)
101
+ .and_return("qux\n")
102
+ expect(ChefAttrdoc.process_attributes('foodir'))
103
+ .to eq(<<-OUTPUT)
104
+ ## file1.rb
229
105
 
230
- ```ruby
231
- foo = bar
232
- ```
106
+ qux
233
107
 
234
- comment we want to keep
235
- still good
236
-
237
- foo bar
238
-
239
- ```ruby
240
- foo = bar
241
- ```
108
+ ## file3.rb
242
109
 
110
+ qux
243
111
  OUTPUT
112
+ end
244
113
  end
245
114
  end
@@ -0,0 +1,13 @@
1
+ chef_attrdoc example README
2
+ ===========================
3
+
4
+ This is just an example
5
+
6
+ Attributes
7
+ ==========
8
+ nothing here now
9
+
10
+
11
+ License
12
+ =======
13
+ This is usually important.
@@ -0,0 +1,17 @@
1
+ # Copyright 1970, nobody
2
+
3
+ # this is the attribute
4
+ default['some']['attribute'] = 'foo'
5
+
6
+ default['this']['will']['be'] = 'ignored'
7
+
8
+ # NOTE code blocks without a comment are ignored as are those beginning
9
+ # NOTE with 'NOTE', 'XXX', 'TODO' or foodcritic comments
10
+
11
+ # a longer block of code
12
+ case something
13
+ when 'foo'
14
+ default['some']['foo'] = 'baz'
15
+ else
16
+ default['some']['foo'] = 'qux'
17
+ end
@@ -0,0 +1 @@
1
+ foo
@@ -0,0 +1 @@
1
+ bar
@@ -0,0 +1 @@
1
+ baz
@@ -0,0 +1,45 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # Copyright 2014, Ionuț Arțăriși <ionut@artarisi.eu>
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ require 'chef_attrdoc'
19
+
20
+ describe 'This is the example from chef_attrdoc\'s README.md' do
21
+ it 'has the a fixed output' do
22
+ output = `ruby -Ilib bin/chef_attrdoc spec/fixtures/cookbook-example/ -s`
23
+ expect(output).to eq(<<-OUTPUT)
24
+ ## default.rb
25
+
26
+ this is the attribute
27
+
28
+ ```ruby
29
+ default['some']['attribute'] = 'foo'
30
+ ```
31
+
32
+ a longer block of code
33
+
34
+ ```ruby
35
+ case something
36
+ when 'foo'
37
+ default['some']['foo'] = 'baz'
38
+ else
39
+ default['some']['foo'] = 'qux'
40
+ end
41
+ ```
42
+
43
+ OUTPUT
44
+ end
45
+ end
metadata CHANGED
@@ -1,16 +1,48 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chef_attrdoc
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.2
5
- prerelease:
4
+ version: 1.0.0.pre
5
+ prerelease: 6
6
6
  platform: ruby
7
7
  authors:
8
8
  - Ionuț Arțăriși
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-06-26 00:00:00.000000000 Z
13
- dependencies: []
12
+ date: 2014-08-20 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rake
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rspec
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
14
46
  description: Generate README.md docs from Chef cookbook attributes files
15
47
  email:
16
48
  - ionut@artarisi.eu
@@ -20,6 +52,9 @@ extensions: []
20
52
  extra_rdoc_files: []
21
53
  files:
22
54
  - .rspec
55
+ - .travis.yml
56
+ - Gemfile
57
+ - Gemfile.lock
23
58
  - LICENSE
24
59
  - README.md
25
60
  - Rakefile
@@ -27,7 +62,14 @@ files:
27
62
  - chef_attrdoc.gemspec
28
63
  - lib/chef_attrdoc.rb
29
64
  - lib/chef_attrdoc/version.rb
65
+ - spec/attributes_file_spec.rb
30
66
  - spec/chef_attrdoc_spec.rb
67
+ - spec/fixtures/cookbook-example/README.md
68
+ - spec/fixtures/cookbook-example/attributes/default.rb
69
+ - spec/fixtures/file1.rb
70
+ - spec/fixtures/file2
71
+ - spec/fixtures/file3.rb
72
+ - spec/readme_example_spec.rb
31
73
  - spec/spec_helper.rb
32
74
  homepage: https://github.com/mapleoin/chef_attrdoc
33
75
  licenses:
@@ -45,9 +87,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
45
87
  required_rubygems_version: !ruby/object:Gem::Requirement
46
88
  none: false
47
89
  requirements:
48
- - - ! '>='
90
+ - - ! '>'
49
91
  - !ruby/object:Gem::Version
50
- version: '0'
92
+ version: 1.3.1
51
93
  requirements: []
52
94
  rubyforge_project:
53
95
  rubygems_version: 1.8.23
@@ -55,6 +97,13 @@ signing_key:
55
97
  specification_version: 3
56
98
  summary: Generate README.md docs from Chef cookbook attributes files
57
99
  test_files:
100
+ - spec/attributes_file_spec.rb
58
101
  - spec/chef_attrdoc_spec.rb
102
+ - spec/fixtures/cookbook-example/README.md
103
+ - spec/fixtures/cookbook-example/attributes/default.rb
104
+ - spec/fixtures/file1.rb
105
+ - spec/fixtures/file2
106
+ - spec/fixtures/file3.rb
107
+ - spec/readme_example_spec.rb
59
108
  - spec/spec_helper.rb
60
109
  has_rdoc: