cookbook-development 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in cookbook-development.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Rally Dev Pair
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,34 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'cookbook/development/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'cookbook-development'
8
+ spec.version = Cookbook::Development::VERSION
9
+ spec.authors = ['Rally Software Development Corp']
10
+ spec.email = ['rallysoftware-cookbooks@rallydev.com']
11
+ spec.description = %q{Rally Software Development Corp cookbook development}
12
+ spec.summary = %q{Rally Software Development Corp cookbook development}
13
+ spec.homepage = ''
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_dependency 'berkshelf', '~> 2.0'
22
+ spec.add_dependency 'bundler', '~> 1.3'
23
+ spec.add_dependency 'chef', '~> 11.6'
24
+ spec.add_dependency 'chefspec', '~> 3.0'
25
+ spec.add_dependency 'foodcritic', '~> 3.0'
26
+ # Workaround for json dependency for chef and berkshelf. Chef
27
+ # wants <= 1.7.7 and berkshelf >= 1.5 but bundler tries to grab 1.8.0
28
+ # which violates chef's requirement. Seems like a bundler bug.
29
+ spec.add_dependency 'json', '1.7.7'
30
+ spec.add_dependency 'kitchen-vagrant', '~> 0.11'
31
+ spec.add_dependency 'rake', '~> 10.0'
32
+ spec.add_dependency 'test-kitchen'
33
+ spec.add_dependency 'version', '~> 1.0'
34
+ end
@@ -0,0 +1,7 @@
1
+ require 'cookbook/development/version'
2
+
3
+ module Cookbook
4
+ module Development
5
+ # Your code goes here...
6
+ end
7
+ end
@@ -0,0 +1,145 @@
1
+ # Ideas and code for releasing a cookbook heavily borrowed from bundler https://github.com/bundler/bundler
2
+ module CookbookDevelopment
3
+ class ReleaseTasks < Rake::TaskLib
4
+ attr_reader :project_dir
5
+ attr_reader :chef_dir
6
+ attr_reader :knife_cfg
7
+ attr_reader :vendor_dir
8
+ attr_reader :cookbooks_dir
9
+ attr_reader :berks_file
10
+
11
+ def initialize
12
+ @project_dir = Dir.pwd
13
+ @chef_dir = File.join(project_dir, 'test', '.chef')
14
+ @knife_cfg = File.join(chef_dir, 'knife.rb')
15
+ @vendor_dir = File.join(project_dir, 'vendor')
16
+ @cookbooks_dir = File.join(vendor_dir, 'cookbooks')
17
+ @berks_file = File.join(project_dir, 'Berksfile')
18
+
19
+ yield(self) if block_given?
20
+ define
21
+ end
22
+
23
+ def define
24
+ desc 'Does a berks upload --except :test'
25
+ task :upload do |task|
26
+ Berkshelf::Berksfile.from_file(berks_file).upload(:path => cookbooks_dir, :except => :test)
27
+ end
28
+
29
+ desc 'Runs the full test suite and then does a berks upload'
30
+ task :release do
31
+ release_cookbook
32
+ end
33
+
34
+ end
35
+
36
+ def release_cookbook(skip_test = false)
37
+ start_time = Time.now
38
+ release_version = version
39
+ release_tag = version_tag(release_version)
40
+
41
+ raise "Tag #{release_tag} has already been created." if already_tagged?(release_tag)
42
+ raise 'You have uncommitted changes.' unless clean? && committed?
43
+ raise 'You have unpushed commits.' if unpushed?
44
+
45
+ Rake::Task[:test].invoke unless ENV['test'] == 'false'
46
+
47
+ tag_version(release_version, release_tag) do
48
+ berks_upload
49
+ Rake::Task['version:bump:patch'].invoke
50
+ git_pull
51
+ git_push
52
+ end
53
+
54
+ elapsed = Time.now - start_time
55
+ puts elapsed
56
+ end
57
+
58
+ def berks_upload
59
+ puts 'Running berks upload...'
60
+ Rake::Task[:upload].invoke
61
+ end
62
+
63
+ def git_pull
64
+ cmd = 'git pull --rebase'
65
+ out, code = sh_with_code(cmd)
66
+ raise "Couldn't git pull. `#{cmd}' failed with the following output:\n\n#{out}\n" unless code == 0
67
+ end
68
+
69
+ def git_push
70
+ puts 'Pushing git changes...'
71
+ perform_git_push 'origin --tags :'
72
+ puts 'Pushed git commits and tags.'
73
+ end
74
+
75
+ def perform_git_push(options = '')
76
+ cmd = "git push #{options}"
77
+ out, code = sh_with_code(cmd)
78
+ raise "Couldn't git push. `#{cmd}' failed with the following output:\n\n#{out}\n" unless code == 0
79
+ end
80
+
81
+ def clean?
82
+ sh_with_code('git diff --exit-code')[1] == 0
83
+ end
84
+
85
+ def committed?
86
+ sh_with_code('git diff-index --quiet --cached HEAD')[1] == 0
87
+ end
88
+
89
+ def unpushed?
90
+ sh_with_code('git cherry')[0] != ''
91
+ end
92
+
93
+ def sh(cmd, &block)
94
+ out, code = sh_with_code(cmd, &block)
95
+ code == 0 ? out : raise(out.empty? ? "Running `#{cmd}' failed. Run this command directly for more detailed output." : out)
96
+ end
97
+
98
+ def already_tagged?(tag)
99
+ sh('git tag').split(/\n/).include?(tag)
100
+ end
101
+
102
+ def version_tag(version)
103
+ "v#{version}"
104
+ end
105
+
106
+ def version
107
+ version_file = VersionFile::VERSION_FILE
108
+ alt_version_file = VersionFile::ALT_VERSION_FILE
109
+
110
+ if File.exist?(version_file)
111
+ Version.current(version_file)
112
+ elsif File.exist?(alt_version_file)
113
+ Version.current(alt_version_file)
114
+ else
115
+ raise <<-MSG
116
+ The versioning/release process relies on having a VERSION file in the root of
117
+ your cookbook as well as the version attribute in metadata.rb reading
118
+ from said VERSION file. Until https://github.com/opscode/test-kitchen/pull/212
119
+ is resolved we need to put the cookbooks in a place that test-kitchen
120
+ will copy to the VM. That place is in recipes/VERSION. Neither #{version_file}
121
+ nor #{alt_version_file} were found in your cookbook.
122
+ MSG
123
+ end
124
+ end
125
+
126
+ def tag_version(release, tag)
127
+ sh "git tag -a -m \"Version #{release}\" #{tag}"
128
+ puts "Tagged #{tag}."
129
+ yield if block_given?
130
+ rescue Exception => e
131
+ puts "Untagging #{tag} due to error."
132
+ sh_with_code "git tag -d #{tag}"
133
+ raise e
134
+ end
135
+
136
+ def sh_with_code(cmd, &block)
137
+ cmd << " 2>&1"
138
+ outbuf = `#{cmd}`
139
+ if $? == 0
140
+ block.call(outbuf) if block
141
+ end
142
+ [outbuf, $?]
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,99 @@
1
+ require 'rspec/core/rake_task'
2
+ require 'kitchen/rake_tasks'
3
+ require 'foodcritic'
4
+ require 'berkshelf'
5
+
6
+ module CookbookDevelopment
7
+ class TestTasks < Rake::TaskLib
8
+ attr_reader :project_dir
9
+ attr_reader :chef_dir
10
+ attr_reader :knife_cfg
11
+ attr_reader :vendor_dir
12
+ attr_reader :cookbooks_dir
13
+ attr_reader :berks_file
14
+
15
+ def initialize
16
+ @project_dir = Dir.pwd
17
+ @chef_dir = File.join(project_dir, 'test', '.chef')
18
+ @knife_cfg = File.join(chef_dir, 'knife.rb')
19
+ @vendor_dir = File.join(project_dir, 'vendor')
20
+ @cookbooks_dir = File.join(vendor_dir, 'cookbooks')
21
+ @berks_file = File.join(project_dir, 'Berksfile')
22
+ @metadata_file = File.join(project_dir, 'metadata.rb')
23
+
24
+ yield(self) if block_given?
25
+ define
26
+ end
27
+
28
+ def define
29
+
30
+ kitchen_config = Kitchen::Config.new
31
+ Kitchen.logger = Kitchen.default_file_logger
32
+
33
+ namespace "kitchen" do
34
+ kitchen_config.instances.each do |instance|
35
+ desc "Run #{instance.name} test instance"
36
+ task instance.name do
37
+ instance.test(:passing)
38
+ end
39
+ end
40
+
41
+ desc "Run all test instances"
42
+ task "all" => kitchen_config.instances.map { |i| i.name }
43
+ end
44
+
45
+ desc 'Runs knife cookbook test'
46
+ task :knife_test => [knife_cfg, :berks_install] do |task|
47
+ cookbook_name = File.basename(project_dir)
48
+ IO.readlines(@metadata_file).each do |line|
49
+ cookbook_name = line.split[1] if line.split[0] == 'name'
50
+ end
51
+ Dir.chdir(File.join(project_dir, '..')) do
52
+ sh "bundle exec knife cookbook test #{cookbook_name} --config #{knife_cfg}"
53
+ end
54
+ end
55
+
56
+ desc 'Runs Foodcritic linting'
57
+ FoodCritic::Rake::LintTask.new do |task|
58
+ task.options = {:search_gems => true, :fail_tags => ['any'], :tags => ['~FC003', '~FC015'], :exclude_paths => ['vendor/cookbooks/**/*']}
59
+ end
60
+
61
+ desc 'Runs unit tests'
62
+ RSpec::Core::RakeTask.new(:unit) do |task|
63
+ task.pattern = FileList[File.join(project_dir, 'test', 'unit', '**/*_spec.rb')]
64
+ end
65
+ task :unit => :berks_install
66
+
67
+ desc 'Runs integration tests'
68
+ task :integration do
69
+ Rake::Task['kitchen:all'].invoke
70
+ end
71
+
72
+ desc 'Run all tests and linting'
73
+ task :test do
74
+ Rake::Task['knife_test'].invoke
75
+ Rake::Task['foodcritic'].invoke
76
+ Rake::Task['unit'].invoke
77
+ Rake::Task['integration'].invoke
78
+ end
79
+
80
+ task :berks_install do |task|
81
+ FileUtils.rm_rf vendor_dir
82
+ Berkshelf::Berksfile.from_file(berks_file).install(:path => cookbooks_dir)
83
+ end
84
+
85
+ directory chef_dir
86
+
87
+ file knife_cfg => chef_dir do |task|
88
+ File.open(task.name, 'w+') do |file|
89
+ file.write <<-EOF.gsub(/^\s+/, "")
90
+ cache_type 'BasicFile'
91
+ cache_options(:path => "\#{ENV['HOME']}/.chef/checksums")
92
+ cookbook_path '#{cookbooks_dir}'
93
+ EOF
94
+ end
95
+ end
96
+
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,118 @@
1
+ require 'version'
2
+ require 'rake/tasklib'
3
+
4
+ module CookbookDevelopment
5
+
6
+ class VersionFile
7
+ VERSION_FILE = File.join(Dir.pwd, 'VERSION')
8
+ ALT_VERSION_FILE = File.join(Dir.pwd, 'recipes', 'VERSION')
9
+
10
+ class << self
11
+ def in_dir(dir = Dir.pwd)
12
+ metadata_file = File.join(Dir.pwd, 'metadata.rb')
13
+
14
+ if File.exist? VERSION_FILE
15
+ VersionFile.new(VERSION_FILE)
16
+ elsif File.exist? ALT_VERSION_FILE
17
+ # The release process relies on having a VERSION file in the root of
18
+ # your cookbook as well as the version attribute in metadata.rb reading
19
+ # from said VERSION file. Until https://github.com/opscode/test-kitchen/pull/212
20
+ # is resolved we need to put the cookbooks in a place that test-kitchen
21
+ # will copy to the VM.
22
+ VersionFile.new(ALT_VERSION_FILE)
23
+ elsif File.exist? metadata_file
24
+ MetadataVersion.new(metadata_file)
25
+ else
26
+ raise 'I could not find a VERSION file or a metadata.rb'
27
+ end
28
+ end
29
+ end
30
+
31
+ attr_reader :version
32
+ attr_reader :path
33
+ def initialize(path)
34
+ @path = Pathname.new(path)
35
+ @version = @path.read
36
+ end
37
+
38
+ def bump(level)
39
+ @version.to_version.bump!(level).to_s
40
+ end
41
+
42
+ def bump!(level)
43
+ @version = bump(level)
44
+ save
45
+ @version
46
+ end
47
+
48
+ def to_s
49
+ @version
50
+ end
51
+
52
+ def save
53
+ @path.open('w') do |io|
54
+ io << self
55
+ end
56
+ end
57
+ end
58
+
59
+ class MetadataVersion < VersionFile
60
+ def initialize(path)
61
+ @path = Pathname.new(path)
62
+ @metadata = @path.read
63
+ @metadata =~ /version\s+'(\d+\.\d+\.\d+)'/
64
+ @version = $1
65
+ end
66
+
67
+ def to_s
68
+ @metadata.sub(/(^version\s+')(\d+\.\d+\.\d+)(')/, "\\1#{@version}\\3" )
69
+ end
70
+ end
71
+
72
+ class VersionTasks < Rake::TaskLib
73
+ def initialize
74
+ @version_file = VersionFile.in_dir(Dir.pwd)
75
+ yield(self) if block_given?
76
+ define
77
+ end
78
+
79
+ def define
80
+ namespace :version do
81
+ namespace :bump do
82
+ desc "Bump to #{@version_file.bump(:major)}"
83
+ task :major do
84
+ bump_version!(:major)
85
+ end
86
+
87
+ desc "Bump to #{@version_file.bump(:minor)}"
88
+ task :minor do
89
+ bump_version!(:minor)
90
+ end
91
+
92
+ desc "Bump to #{@version_file.bump(:revision)}"
93
+ task :patch do
94
+ bump_version!(:revision)
95
+ end
96
+ end
97
+ end
98
+ end
99
+
100
+ private
101
+
102
+ def bump_version!(level)
103
+ new_version = @version_file.bump!(level)
104
+ puts "Version bumped to #{new_version}"
105
+ git_commit(new_version)
106
+ end
107
+
108
+ def system(*args)
109
+ abort unless Kernel.system(*args)
110
+ end
111
+
112
+ def git_commit(version)
113
+ puts "Committing #{@version_file.path}..."
114
+ system("git add #{@version_file.path}")
115
+ system("git commit -m 'Version bump to #{version}'")
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,7 @@
1
+ require 'cookbook/development/rake/version_tasks'
2
+ require 'cookbook/development/rake/test_tasks'
3
+ require 'cookbook/development/rake/release_tasks'
4
+
5
+ CookbookDevelopment::TestTasks.new
6
+ CookbookDevelopment::VersionTasks.new
7
+ CookbookDevelopment::ReleaseTasks.new
@@ -0,0 +1,4 @@
1
+ require 'chefspec'
2
+ require 'chefspec/berkshelf'
3
+ require 'cookbook/development/test/unit/chefspec/helpers'
4
+ require 'cookbook/development/test/unit/chefspec/matchers'
@@ -0,0 +1 @@
1
+ require 'cookbook/development/test/unit/chefspec/helpers/stub_helpers'
@@ -0,0 +1,16 @@
1
+ module StubHelpers
2
+
3
+ def stub_include_recipe
4
+ # Don't worry about external cookbook dependencies
5
+ Chef::Cookbook::Metadata.any_instance.stub(:depends)
6
+
7
+ # Test each recipe in isolation, regardless of includes
8
+ @included_recipes = []
9
+ Chef::RunContext.any_instance.stub(:loaded_recipe?).and_return(false)
10
+ Chef::Recipe.any_instance.stub(:include_recipe) do |i|
11
+ Chef::RunContext.any_instance.stub(:loaded_recipe?).with(i).and_return(true)
12
+ @included_recipes << i
13
+ end
14
+ Chef::RunContext.any_instance.stub(:loaded_recipes).and_return(@included_recipes)
15
+ end
16
+ end
@@ -0,0 +1,2 @@
1
+ require 'cookbook/development/test/unit/chefspec/matchers/ark'
2
+ require 'cookbook/development/test/unit/chefspec/matchers/resource'
@@ -0,0 +1,14 @@
1
+ module ChefSpec::API
2
+
3
+ module ArkMatchers
4
+
5
+ def put_ark(resource_name)
6
+ ChefSpec::Matchers::ResourceMatcher.new(:ark, :put, resource_name)
7
+ end
8
+
9
+ def install_ark(resource_name)
10
+ ChefSpec::Matchers::ResourceMatcher.new(:ark, :install, resource_name)
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,32 @@
1
+ module ChefSpec
2
+ module Matchers
3
+
4
+ RSpec::Matchers.define :ready_resource_with_attribute do |resource_type, resource_name, attributes|
5
+ match do |chef_run|
6
+ found_resource = chef_run.find_resource(resource_type, resource_name)
7
+ found_resource.nil? == false && \
8
+ found_resource.action == [:nothing] && \
9
+ attributes.any? { |attribute, value| found_resource.send(attribute) == value }
10
+ end
11
+
12
+ failure_message_for_should do |chef_run|
13
+ "Expected #{resource_type}[#{resource_name}] with action [:nothing] && #{attributes} to be in Chef run. Other #{resource_type} resources:" \
14
+ "\n\n " + inspect_other_resources(chef_run, resource_type, attributes).join("\n ") + "\n "
15
+ end
16
+
17
+ failure_message_for_should_not do |chef_run|
18
+ "Should not have found execute[#{resource_name}] with action [:nothing] && #{attributes}"
19
+ end
20
+
21
+ def inspect_other_resources(chef_run, resource_type, attributes)
22
+ parameter, param_value = nil, nil
23
+ attributes.each_pair { |key, value| parameter, param_value = key, value }
24
+ resources = []
25
+ chef_run.find_resources(resource_type).each do |resource|
26
+ resources << "#{resource_type}[#{resource.name}] has:\n\t\taction: #{resource.action.inspect}\n\t\t#{parameter}: `#{resource.send(parameter).to_s}`"
27
+ end
28
+ resources
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,5 @@
1
+ module Cookbook
2
+ module Development
3
+ VERSION = "0.0.5"
4
+ end
5
+ end
@@ -0,0 +1,74 @@
1
+ #Etsy Foodcritic rules
2
+ @coreservices = ["httpd", "mysql", "memcached", "postgresql-server"]
3
+ @coreservicepackages = ["httpd", "Percona-Server-server-51", "memcached", "postgresql-server"]
4
+ @corecommands = ["yum -y", "yum install", "yum reinstall", "yum remove", "mkdir", "useradd", "usermod", "touch"]
5
+
6
+ rule "ETSY001", "Package or yum_package resource used with :upgrade action" do
7
+ tags %w{correctness recipe etsy}
8
+ recipe do |ast|
9
+ pres = find_resources(ast, :type => 'package').find_all do |cmd|
10
+ cmd_str = (resource_attribute(cmd, 'action') || resource_name(cmd)).to_s
11
+ cmd_str.include?('upgrade')
12
+ end
13
+ ypres = find_resources(ast, :type => 'yum_package').find_all do |cmd|
14
+ cmd_str = (resource_attribute(cmd, 'action') || resource_name(cmd)).to_s
15
+ cmd_str.include?('upgrade')
16
+ end
17
+ pres.concat(ypres).map{|cmd| match(cmd)}
18
+ end
19
+ end
20
+
21
+ #ETSY002 and ETSY003 removed as they were added to mainline foodcritic as FC040 and FC041
22
+
23
+ # This rule does not detect execute resources defined inside a conditional, as foodcritic rule FC023 (Prefer conditional attributes)
24
+ # already provides this. It's recommended to use both rules in conjunction. (foodcritic -t etsy,FC023)
25
+ rule "ETSY004", "Execute resource defined without conditional or action :nothing" do
26
+ tags %w{style recipe etsy}
27
+ recipe do |ast,filename|
28
+ pres = find_resources(ast, :type => 'execute').find_all do |cmd|
29
+ cmd_actions = (resource_attribute(cmd, 'action') || resource_name(cmd)).to_s
30
+ condition = cmd.xpath('//ident[@value="only_if" or @value="not_if" or @value="creates"][parent::fcall or parent::command or ancestor::if]')
31
+ (condition.empty? && !cmd_actions.include?("nothing"))
32
+ end.map{|cmd| match(cmd)}
33
+ end
34
+ end
35
+
36
+ rule "ETSY005", "Action :restart sent to a core service" do
37
+ tags %w{style recipe etsy}
38
+ recipe do |ast, filename|
39
+ find_resources(ast).select do |resource|
40
+ notifications(resource).any? do |notification|
41
+ @coreservices.include?(notification[:resource_name]) and
42
+ notification[:action] == :restart
43
+ end
44
+ end
45
+ end
46
+ end
47
+
48
+ rule "ETSY006", "Execute resource used to run chef-provided command" do
49
+ tags %w{style recipe etsy}
50
+ recipe do |ast|
51
+ find_resources(ast, :type => 'execute').find_all do |cmd|
52
+ cmd_str = (resource_attribute(cmd, 'command') || resource_name(cmd)).to_s
53
+ @corecommands.any? { |corecommand| cmd_str.include? corecommand }
54
+ end.map{|c| match(c)}
55
+ end
56
+ end
57
+
58
+
59
+ rule "ETSY007", "Package or yum_package resource used to install core package without specific version number" do
60
+ tags %w{style recipe etsy}
61
+ recipe do |ast,filename|
62
+ pres = find_resources(ast, :type => 'package').find_all do |cmd|
63
+ cmd_str = (resource_attribute(cmd, 'version') || resource_name(cmd)).to_s
64
+ cmd_action = (resource_attribute(cmd, 'action') || resource_name(cmd)).to_s
65
+ cmd_str == resource_name(cmd) && @coreservicepackages.any? { |svc| resource_name(cmd) == svc } && cmd_action.include?('install')
66
+ end
67
+ ypres = find_resources(ast, :type => 'yum_package').find_all do |cmd|
68
+ cmd_str = (resource_attribute(cmd, 'version') || resource_name(cmd)).to_s
69
+ cmd_action = (resource_attribute(cmd, 'action') || resource_name(cmd)).to_s
70
+ cmd_str == resource_name(cmd) && @coreservicepackages.any? { |svc| resource_name(cmd) == svc } && cmd_action.include?('install')
71
+ end
72
+ pres.concat(ypres).map{|cmd| match(cmd)}
73
+ end
74
+ end
@@ -0,0 +1,24 @@
1
+ # Borrowed from customink's foodcritic rules
2
+ # See https://github.com/customink-webops/foodcritic-rules/blob/master/rules.rb
3
+
4
+ rule 'RALY001', 'Prefer single-quoted strings' do
5
+ tags %w{style strings}
6
+ recipe do |ast, filename|
7
+
8
+ next if filename.end_with? '.erb'
9
+
10
+ lines = File.readlines(filename)
11
+
12
+ lines.collect.with_index do |line, index|
13
+ # Don't flag if there is a #{} or ' in the line
14
+ if line.match('"(.*)"') && !line.match('^\s+<.+?[class|plugin]="(.+?)".*?>\s*$') && !line.match('\A\s?#') && !line.match('\'(.*)"(.*)"(.*)\'') && !line.match('"(.*)(#{.+}|\'|\\\a|\\\b|\\\r|\\\n|\\\s|\\\t)(.*)"')
15
+ {
16
+ :filename => filename,
17
+ :matched => recipe,
18
+ :line => index + 1,
19
+ :column => 0
20
+ }
21
+ end
22
+ end.compact.flatten
23
+ end
24
+ end
metadata ADDED
@@ -0,0 +1,231 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cookbook-development
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.5
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Rally Software Development Corp
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-12-11 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: berkshelf
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '2.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '2.0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: bundler
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '1.3'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '1.3'
46
+ - !ruby/object:Gem::Dependency
47
+ name: chef
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: '11.6'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '11.6'
62
+ - !ruby/object:Gem::Dependency
63
+ name: chefspec
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: '3.0'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: '3.0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: foodcritic
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: '3.0'
86
+ type: :runtime
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: '3.0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: json
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - '='
100
+ - !ruby/object:Gem::Version
101
+ version: 1.7.7
102
+ type: :runtime
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - '='
108
+ - !ruby/object:Gem::Version
109
+ version: 1.7.7
110
+ - !ruby/object:Gem::Dependency
111
+ name: kitchen-vagrant
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ~>
116
+ - !ruby/object:Gem::Version
117
+ version: '0.11'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ~>
124
+ - !ruby/object:Gem::Version
125
+ version: '0.11'
126
+ - !ruby/object:Gem::Dependency
127
+ name: rake
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ~>
132
+ - !ruby/object:Gem::Version
133
+ version: '10.0'
134
+ type: :runtime
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ~>
140
+ - !ruby/object:Gem::Version
141
+ version: '10.0'
142
+ - !ruby/object:Gem::Dependency
143
+ name: test-kitchen
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ! '>='
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ type: :runtime
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ! '>='
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
158
+ - !ruby/object:Gem::Dependency
159
+ name: version
160
+ requirement: !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
163
+ - - ~>
164
+ - !ruby/object:Gem::Version
165
+ version: '1.0'
166
+ type: :runtime
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ none: false
170
+ requirements:
171
+ - - ~>
172
+ - !ruby/object:Gem::Version
173
+ version: '1.0'
174
+ description: Rally Software Development Corp cookbook development
175
+ email:
176
+ - rallysoftware-cookbooks@rallydev.com
177
+ executables: []
178
+ extensions: []
179
+ extra_rdoc_files: []
180
+ files:
181
+ - .gitignore
182
+ - Gemfile
183
+ - LICENSE.txt
184
+ - Rakefile
185
+ - cookbook-development.gemspec
186
+ - lib/cookbook/development.rb
187
+ - lib/cookbook/development/rake/release_tasks.rb
188
+ - lib/cookbook/development/rake/test_tasks.rb
189
+ - lib/cookbook/development/rake/version_tasks.rb
190
+ - lib/cookbook/development/rake_tasks.rb
191
+ - lib/cookbook/development/test/unit/chefspec.rb
192
+ - lib/cookbook/development/test/unit/chefspec/helpers.rb
193
+ - lib/cookbook/development/test/unit/chefspec/helpers/stub_helpers.rb
194
+ - lib/cookbook/development/test/unit/chefspec/matchers.rb
195
+ - lib/cookbook/development/test/unit/chefspec/matchers/ark.rb
196
+ - lib/cookbook/development/test/unit/chefspec/matchers/resource.rb
197
+ - lib/cookbook/development/version.rb
198
+ - lib/foodcritic/rules/etsy.rb
199
+ - lib/foodcritic/rules/rally.rb
200
+ homepage: ''
201
+ licenses:
202
+ - MIT
203
+ post_install_message:
204
+ rdoc_options: []
205
+ require_paths:
206
+ - lib
207
+ required_ruby_version: !ruby/object:Gem::Requirement
208
+ none: false
209
+ requirements:
210
+ - - ! '>='
211
+ - !ruby/object:Gem::Version
212
+ version: '0'
213
+ segments:
214
+ - 0
215
+ hash: -2590675334605747241
216
+ required_rubygems_version: !ruby/object:Gem::Requirement
217
+ none: false
218
+ requirements:
219
+ - - ! '>='
220
+ - !ruby/object:Gem::Version
221
+ version: '0'
222
+ segments:
223
+ - 0
224
+ hash: -2590675334605747241
225
+ requirements: []
226
+ rubyforge_project:
227
+ rubygems_version: 1.8.25
228
+ signing_key:
229
+ specification_version: 3
230
+ summary: Rally Software Development Corp cookbook development
231
+ test_files: []