daptiv-foodcritic-rules 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. data/lib/foodcritic/rules/rules.rb +168 -0
  2. metadata +79 -0
@@ -0,0 +1,168 @@
1
+ #
2
+ # Author:: Seth Vargo <sethvargo@gmail.com>
3
+ # Foodcritic:: Rules
4
+ #
5
+ # Copyright 2012, Seth Vargo, CustomInk, LLC
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+
19
+
20
+ rule 'CINK001', 'Missing CHANGELOG in markdown format' do
21
+ tags %w{style changelog}
22
+ cookbook do |path|
23
+ filepath = File.join(path, 'CHANGELOG.md')
24
+ unless File.exists?(filepath)
25
+ [ file_match(filepath) ]
26
+ end
27
+ end
28
+ end
29
+
30
+ rule 'CINK002', 'Prefer single-quoted strings' do
31
+ tags %w{style strings}
32
+ cookbook do |path|
33
+ recipes = Dir["#{path}/**/*.rb"]
34
+ recipes.collect do |recipe|
35
+ lines = File.readlines(recipe)
36
+
37
+ lines.collect.with_index do |line, index|
38
+ # Don't flag if there is a #{} or ' in the line
39
+ if line.match('"(.*)"') && !line.match('\A\s?#') && !line.match('\'(.*)"(.*)"(.*)\'') && !line.match('"(.*)(#{.+}|\'|\\\a|\\\b|\\\r|\\\n|\\\s|\\\t)(.*)"')
40
+ {
41
+ :filename => recipe,
42
+ :matched => recipe,
43
+ :line => index + 1,
44
+ :column => 0
45
+ }
46
+ end
47
+ end.compact
48
+ end.flatten
49
+ end
50
+ end
51
+
52
+ # The message was changed from the original message.
53
+ rule 'CINK003', 'Don\'t hardcode user or group' do
54
+ tags %w{bug}
55
+ cookbook do |path|
56
+ recipes = Dir["#{path}/**/*.rb"]
57
+ recipes.collect do |recipe|
58
+ lines = File.readlines(recipe)
59
+
60
+ lines.collect.with_index do |line, index|
61
+ if line.match('(group|owner)\s+[\\\'\"](apache|www-data|http|www)[\\\'\"]')
62
+ {
63
+ :filename => recipe,
64
+ :matched => recipe,
65
+ :line => index+1,
66
+ :column => 0
67
+ }
68
+ end
69
+ end.compact
70
+ end.flatten
71
+ end
72
+ end
73
+
74
+ #++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
75
+
76
+ #Etsy Foodcritic rules
77
+ @coreservices = ["httpd", "mysql", "memcached", "postgresql-server"]
78
+ @coreservicepackages = ["httpd", "Percona-Server-server-51", "memcached", "postgresql-server"]
79
+ @corecommands = ["yum -y", "yum install", "yum reinstall", "yum remove", "mkdir", "useradd", "usermod", "touch"]
80
+
81
+ rule "ETSY001", "Package or yum_package resource used with :upgrade action" do
82
+ tags %w{correctness recipe etsy}
83
+ recipe do |ast|
84
+ pres = find_resources(ast, :type => 'package').find_all do |cmd|
85
+ cmd_str = (resource_attribute(cmd, 'action') || resource_name(cmd)).to_s
86
+ cmd_str.include?('upgrade')
87
+ end
88
+ ypres = find_resources(ast, :type => 'yum_package').find_all do |cmd|
89
+ cmd_str = (resource_attribute(cmd, 'action') || resource_name(cmd)).to_s
90
+ cmd_str.include?('upgrade')
91
+ end
92
+ pres.concat(ypres).map{|cmd| match(cmd)}
93
+ end
94
+ end
95
+
96
+ #ETSY002 and ETSY003 removed as they were added to mainline foodcritic as FC040 and FC041
97
+
98
+ # This rule does not detect execute resources defined inside a conditional, as foodcritic rule FC023 (Prefer conditional attributes)
99
+ # already provides this. It's recommended to use both rules in conjunction. (foodcritic -t etsy,FC023)
100
+ rule "ETSY004", "Execute resource defined without conditional or action :nothing" do
101
+ tags %w{style recipe etsy}
102
+ recipe do |ast,filename|
103
+ pres = find_resources(ast, :type => 'execute').find_all do |cmd|
104
+ cmd_actions = (resource_attribute(cmd, 'action') || resource_name(cmd)).to_s
105
+ condition = cmd.xpath('//ident[@value="only_if" or @value="not_if" or @value="creates"][parent::fcall or parent::command or ancestor::if]')
106
+ (condition.empty? && !cmd_actions.include?("nothing"))
107
+ end.map{|cmd| match(cmd)}
108
+ end
109
+ end
110
+
111
+ rule "ETSY005", "Action :restart sent to a core service" do
112
+ tags %w{style recipe etsy}
113
+ recipe do |ast, filename|
114
+ find_resources(ast).select do |resource|
115
+ notifications(resource).any? do |notification|
116
+ @coreservices.include?(notification[:resource_name]) and
117
+ notification[:action] == :restart
118
+ end
119
+ end
120
+ end
121
+ end
122
+
123
+ rule "ETSY006", "Execute resource used to run chef-provided command" do
124
+ tags %w{style recipe etsy}
125
+ recipe do |ast|
126
+ find_resources(ast, :type => 'execute').find_all do |cmd|
127
+ cmd_str = (resource_attribute(cmd, 'command') || resource_name(cmd)).to_s
128
+ @corecommands.any? { |corecommand| cmd_str.include? corecommand }
129
+ end.map{|c| match(c)}
130
+ end
131
+ end
132
+
133
+
134
+ rule "ETSY007", "Package or yum_package resource used to install core package without specific version number" do
135
+ tags %w{style recipe etsy}
136
+ recipe do |ast,filename|
137
+ pres = find_resources(ast, :type => 'package').find_all do |cmd|
138
+ cmd_str = (resource_attribute(cmd, 'version') || resource_name(cmd)).to_s
139
+ cmd_action = (resource_attribute(cmd, 'action') || resource_name(cmd)).to_s
140
+ cmd_str == resource_name(cmd) && @coreservicepackages.any? { |svc| resource_name(cmd) == svc } && cmd_action.include?('install')
141
+ end
142
+ ypres = find_resources(ast, :type => 'yum_package').find_all do |cmd|
143
+ cmd_str = (resource_attribute(cmd, 'version') || resource_name(cmd)).to_s
144
+ cmd_action = (resource_attribute(cmd, 'action') || resource_name(cmd)).to_s
145
+ cmd_str == resource_name(cmd) && @coreservicepackages.any? { |svc| resource_name(cmd) == svc } && cmd_action.include?('install')
146
+ end
147
+ pres.concat(ypres).map{|cmd| match(cmd)}
148
+ end
149
+ end
150
+
151
+ #######################################################################################################################
152
+ # Daptiv Rules
153
+
154
+ rule 'DAPTIV001', 'Missing .tailor file. All cookbooks should comply with style recommendations.' do
155
+ tags %w{style tailor}
156
+ cookbook do |path|
157
+ filepath = File.join(path, '.tailor')
158
+ unless File.exists?(filepath)
159
+ [ file_match(filepath) ]
160
+ end
161
+ end
162
+ end
163
+
164
+ rule 'DAPTIV002', 'Prefer include_attribute syntax to require_relative.' do
165
+ recipe do |ast|
166
+ ast.xpath('//command[ident/@value="require_relative"]')
167
+ end
168
+ end
metadata ADDED
@@ -0,0 +1,79 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: daptiv-foodcritic-rules
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Shawn Neal
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-10-07 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: foodcritic
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 2.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.2.0
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
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'
46
+ description: Daptiv Foodcritic 2.2 and greater rules for Chef 11 and greater
47
+ email:
48
+ - sneal@daptiv.com
49
+ executables: []
50
+ extensions: []
51
+ extra_rdoc_files: []
52
+ files:
53
+ - lib/foodcritic/rules/rules.rb
54
+ homepage: https://github.com/daptiv/foodcritic_rules
55
+ licenses:
56
+ - APACHE2
57
+ post_install_message:
58
+ rdoc_options: []
59
+ require_paths:
60
+ - lib
61
+ required_ruby_version: !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ! '>='
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ! '>='
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ requirements: []
74
+ rubyforge_project:
75
+ rubygems_version: 1.8.23
76
+ signing_key:
77
+ specification_version: 3
78
+ summary: Daptiv Foodcritic rules for Chef
79
+ test_files: []