Skip to content

Commit 70dc069

Browse files
authored
Merge pull request #7 from mattlqx/cookstyle
add cookstyle hook
2 parents 2d182c9 + 550d3f9 commit 70dc069

8 files changed

Lines changed: 94 additions & 57 deletions

File tree

.pre-commit-hooks.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@
2828
)$
2929
exclude: .*/test/.*\.rb$
3030
verbose: true
31+
- id: cookstyle
32+
name: Enforce Chef style guide with cookstyle
33+
description: Enforce Chef style guide with cookstyle
34+
entry: bin/cookstyle-wrapper.rb
35+
language: script
36+
pass_filenames: true
37+
types: ['file']
38+
verbose: true
3139
- id: chef-cookbook-version
3240
name: Ensure Chef cookbook version bump
3341
description: Ensure Chef cookbook versions are bumped when contents are changed

.rubocop.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
AllCops:
2-
TargetRubyVersion: 2.3
2+
TargetRubyVersion: 2.5
33

44
Metrics/LineLength:
55
Severity: refactor
@@ -20,7 +20,7 @@ Metrics/BlockLength:
2020
Metrics/MethodLength:
2121
Enabled: false
2222

23-
Layout/IndentHeredoc:
23+
Layout/HeredocIndentation:
2424
Enabled: false
2525

2626
Naming/HeredocDelimiterNaming:
@@ -29,7 +29,7 @@ Naming/HeredocDelimiterNaming:
2929
Style/DateTime:
3030
Enabled: false
3131

32-
Naming/UncommunicativeMethodParamName:
32+
Naming/MethodParameterName:
3333
Enabled: false
3434

3535
Layout/ClosingHeredocIndentation:

Gemfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22

33
source 'https://rubygems.org'
44

5-
gem 'rubocop', '0.57.2'
5+
gem 'rubocop', '0.77.0'

Gemfile.lock

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,26 @@ GEM
22
remote: https://rubygems.org/
33
specs:
44
ast (2.4.0)
5-
jaro_winkler (1.5.1)
6-
parallel (1.12.1)
7-
parser (2.5.1.0)
5+
jaro_winkler (1.5.4)
6+
parallel (1.19.1)
7+
parser (2.7.0.2)
88
ast (~> 2.4.0)
9-
powerpack (0.1.2)
109
rainbow (3.0.0)
11-
rubocop (0.57.2)
10+
rubocop (0.77.0)
1211
jaro_winkler (~> 1.5.1)
1312
parallel (~> 1.10)
14-
parser (>= 2.5)
15-
powerpack (~> 0.1)
13+
parser (>= 2.6)
1614
rainbow (>= 2.2.2, < 4.0)
1715
ruby-progressbar (~> 1.7)
18-
unicode-display_width (~> 1.0, >= 1.0.1)
19-
ruby-progressbar (1.9.0)
20-
unicode-display_width (1.4.0)
16+
unicode-display_width (>= 1.4.0, < 1.7)
17+
ruby-progressbar (1.10.1)
18+
unicode-display_width (1.6.0)
2119

2220
PLATFORMS
2321
ruby
2422

2523
DEPENDENCIES
26-
rubocop (= 0.57.2)
24+
rubocop (= 0.77.0)
2725

2826
BUNDLED WITH
29-
1.16.2
27+
1.17.2

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,17 @@ Hooks require that `bundle` be already available on your system.
88

99
To lint Ruby changes in your repo, use the `rubocop` hook. The root of your repo must have a `Gemfile` that includes the desired version of rubocop. It will be installed via Bundler prior to linting. Rubocop will only be run against changed files for each commit.
1010

11-
To lint Chef changes in your repo, use the `foodcritic` hook. The root of your repo must have a `Gemfile` that includes the desired version of foodcritic. It will be installed via Bundler prior to linting. Foodcritic will only be run against cookbooks with changes to Chef code; this does not include the libraries directory of a cookbook.
11+
To lint Chef changes in your repo, use the `foodcritic` or `cookstyle` hook. The root of your repo must have a `Gemfile` that includes the desired version of foodcritic or cookstyle. It will be installed via Bundler prior to linting. Foodcritic will only be run against cookbooks with changes to Chef code; this does not include the libraries directory of a cookbook. Cookstyle will be run against cookbooks and it's at the tools discretion of what actually gets checked. You may specify `--fix` as an argument for cookstyle for it to auto-fix any issues that it can.
1212

1313
To check Chef cookbook version bumps, use the `chef-cookbook-version` hook. Each changed cookbook will have its `metadata.rb` or `metadata.json` checked to determine if its version has been increased. If not, it will automatically be fixed with the patch-level incremented.
1414

1515
To unit test Ruby changes in your repo, use the `rspec` hook. Each path in your repo with a `spec` directory should have a `Gemfile` that includes your desired version of rspec (or a derivative library). It will be installed via Bundler prior to testing. Rspec will only be run against the closest directory in a changed file's path with a spec dir.
1616

1717
- repo: https://github.com/mattlqx/pre-commit-ruby
18-
rev: v1.2.6
18+
rev: v1.3.0
1919
hooks:
2020
- id: rubocop
2121
- id: foodcritic
22+
- id: cookstyle
2223
- id: rspec
2324
- id: chef-cookbook-version

bin/common.rb

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# frozen_string_literal: true
2+
3+
def metadata_walk(path)
4+
dir = File.directory?(path) ? path : File.dirname(path)
5+
if File.exist?(File.join(dir, 'metadata.rb')) || File.exist?(File.join(dir, 'metadata.json'))
6+
[dir, File.exist?(File.join(dir, 'metadata.json')) ? 'json' : 'rb']
7+
elsif ['.', '/'].include?(dir)
8+
false
9+
else
10+
metadata_walk(File.dirname(dir))
11+
end
12+
end
13+
14+
def bump_required?(file)
15+
%w[
16+
metadata.(rb|json)
17+
Berksfile
18+
Berksfile.lock
19+
Policyfile.rb
20+
Policyfile.lock.json
21+
recipes/.*
22+
attributes/.*
23+
libraries/.*
24+
files/.*
25+
templates/.*
26+
].each do |regex|
27+
break true if file.match?("#{regex}$")
28+
end == true
29+
end
30+
31+
def changed_cookbooks(bump_check: true)
32+
changed_cookbooks = []
33+
ARGV.each do |file|
34+
cookbook, type = metadata_walk(file)
35+
next if cookbook == false || changed_cookbooks.map(&:first).include?(cookbook) || file.include?('/test/')
36+
37+
next if bump_check && !bump_required?(file)
38+
39+
changed_cookbooks << [cookbook, type]
40+
end
41+
changed_cookbooks.sort!
42+
changed_cookbooks
43+
end

bin/cookbook-wrapper.rb

Lines changed: 4 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,7 @@
33

44
require 'fileutils'
55
require 'json'
6-
7-
def metadata_walk(path)
8-
dir = File.directory?(path) ? path : File.dirname(path)
9-
if File.exist?(File.join(dir, 'metadata.rb')) || File.exist?(File.join(dir, 'metadata.json'))
10-
[dir, File.exist?(File.join(dir, 'metadata.json')) ? 'json' : 'rb']
11-
elsif ['.', '/'].include?(dir)
12-
false
13-
else
14-
metadata_walk(File.dirname(dir))
15-
end
16-
end
17-
18-
def bump_required?(file)
19-
%w[
20-
metadata.(rb|json)
21-
Berksfile
22-
Berksfile.lock
23-
Policyfile.rb
24-
Policyfile.lock.json
25-
recipes/.*
26-
attributes/.*
27-
libraries/.*
28-
files/.*
29-
templates/.*
30-
].each do |regex|
31-
break true if file.match?("#{regex}$")
32-
end == true
33-
end
6+
require_relative 'common'
347

358
def higher?(old_version, new_version)
369
old_version = old_version.split('.')
@@ -63,7 +36,7 @@ def empty?
6336
@data.empty?
6437
end
6538

66-
def method_missing(sym, *args, &_block) # rubocop:disable Metrics/AbcSize, Style/MethodMissingSuper, Style/MissingRespondToMissing, Metrics/LineLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
39+
def method_missing(sym, *args, &_block) # rubocop:disable Metrics/AbcSize, Style/MethodMissingSuper, Style/MissingRespondToMissing, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
6740
return @data[sym] if args.empty?
6841

6942
if args.length > 1
@@ -81,14 +54,6 @@ def method_missing(sym, *args, &_block) # rubocop:disable Metrics/AbcSize, Style
8154

8255
# Check each changed file for a metadata file in its heirarchy
8356
success = true
84-
changed_cookbooks = []
85-
ARGV.each do |file|
86-
cookbook, type = metadata_walk(file)
87-
next if cookbook == false || changed_cookbooks.map(&:first).include?(cookbook)
88-
89-
changed_cookbooks << [cookbook, type] if bump_required?(file)
90-
end
91-
9257
exit(success) if changed_cookbooks.empty?
9358

9459
IO.popen('git fetch origin') { |_f| true }
@@ -100,10 +65,10 @@ def method_missing(sym, *args, &_block) # rubocop:disable Metrics/AbcSize, Style
10065
type = cb_data[1]
10166

10267
if type == 'rb'
103-
old_metadata = MetadataReader.new(file_from_git_history("#{cookbook}/metadata.rb"), "#{cookbook}/metadata.rb") # rubocop:disable Metrics/LineLength
68+
old_metadata = MetadataReader.new(file_from_git_history("#{cookbook}/metadata.rb"), "#{cookbook}/metadata.rb")
10469
new_metadata = MetadataReader.new(IO.read("#{cookbook}/metadata.rb"), "#{cookbook}/metadata.rb")
10570
else
106-
old_metadata = JSON.parse(file_from_git_history("#{cookbook}/metadata.json")) rescue {} # rubocop:disable Style/RescueModifier, Metrics/LineLength
71+
old_metadata = JSON.parse(file_from_git_history("#{cookbook}/metadata.json")) rescue {} # rubocop:disable Style/RescueModifier
10772
new_metadata = JSON.parse(IO.read("#{cookbook}/metadata.json"))
10873
end
10974

bin/cookstyle-wrapper.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/usr/bin/env ruby
2+
# frozen_string_literal: true
3+
4+
require_relative 'common'
5+
6+
# Check each changed file for a spec directory in its heirarchy
7+
fix = ''
8+
Array.new(ARGV).each do |arg|
9+
next unless arg == '--fix'
10+
11+
fix = '-a'
12+
ARGV.delete('--fix')
13+
break
14+
end
15+
16+
# Exit early if there are no paths to lint
17+
success = true
18+
exit(success) if changed_cookbooks(bump_check: false).empty?
19+
20+
# Install cookstyle and drop args that are paths
21+
system('bundle install >/dev/null') || exit(false)
22+
system("bundle exec cookstyle --color #{fix} #{changed_cookbooks.map(&:first).join(' ')}") || exit(false)

0 commit comments

Comments
 (0)