diff --git a/config/default.yml b/config/default.yml index d1c6ec30..2cba095b 100644 --- a/config/default.yml +++ b/config/default.yml @@ -213,6 +213,14 @@ PreCommit: install_command: 'gem install chamber' include: *chamber_settings_files + ChamberVerification: + enabled: false + description: 'Verify that all settings changes have been approved' + required_executable: 'chamber' + flags: ['sign', '--verify'] + install_command: 'gem install chamber' + include: *chamber_settings_files + CoffeeLint: enabled: false description: 'Analyze with coffeelint' diff --git a/lib/overcommit/hook/pre_commit/chamber_verification.rb b/lib/overcommit/hook/pre_commit/chamber_verification.rb new file mode 100644 index 00000000..457439ad --- /dev/null +++ b/lib/overcommit/hook/pre_commit/chamber_verification.rb @@ -0,0 +1,34 @@ +module Overcommit::Hook::PreCommit + # Runs `chamber sign --verify`. + # + # @see https://github.com/thekompanee/chamber/wiki/Git-Commit-Hooks#chamber-verification-pre-commit-hook + # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity + class ChamberVerification < Base + def run + approver_name = config.fetch('approver_name', 'your approver') + approver_email = config['approver_email'] ? " (#{config['approver_email']})" : nil + + result = execute(command) + + return :pass if result.stdout.empty? && result.stderr.empty? + return :pass if result.stderr =~ /no signature key was found/ + + output = [ + result.stdout.empty? ? nil : result.stdout, + result.stderr.empty? ? nil : result.stderr, + ]. + compact. + join("\n\n") + + output = "\n\n#{output}" unless output.empty? + + [ + :warn, + "One or more of your settings files does not match the signature.\n" \ + "Talk to #{approver_name}#{approver_email} about getting them " \ + "approved.#{output}", + ] + end + end + # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity +end diff --git a/spec/overcommit/hook/pre_commit/chamber_verification_spec.rb b/spec/overcommit/hook/pre_commit/chamber_verification_spec.rb new file mode 100644 index 00000000..1dee1de9 --- /dev/null +++ b/spec/overcommit/hook/pre_commit/chamber_verification_spec.rb @@ -0,0 +1,55 @@ +require 'spec_helper' + +describe Overcommit::Hook::PreCommit::ChamberVerification do + let(:config) { Overcommit::ConfigurationLoader.default_configuration } + let(:context) { double('context') } + subject { described_class.new(config, context) } + + before do + subject.stub(:applicable_files).and_return(['my_settings.yml']) + end + + context 'when chamber exits successfully' do + before do + result = double('result') + result.stub(:stdout).and_return('') + result.stub(:stderr).and_return('') + subject.stub(:execute).and_return(result) + end + + it { should pass } + end + + context 'when chamber exits unsuccessfully but because of missing keys' do + before do + result = double('result') + result.stub(:stdout).and_return('') + result.stub(:stderr).and_return('no signature key was found') + subject.stub(:execute).and_return(result) + end + + it { should pass } + end + + context 'when chamber exits unsucessfully via standard out' do + before do + result = double('result') + result.stub(:stdout).and_return('Some error message') + result.stub(:stderr).and_return('') + subject.stub(:execute).and_return(result) + end + + it { should warn } + end + + context 'when chamber exits unsucessfully via standard error' do + before do + result = double('result') + result.stub(:stdout).and_return('') + result.stub(:stderr).and_return('Some error message') + subject.stub(:execute).and_return(result) + end + + it { should warn } + end +end