Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions config/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,15 @@ PreCommit:
flags: ['-IEHnw']
keywords: ['FContext','FDescribe','FIt','FMeasure','FSpecify','FWhen']

GolangciLint:
enabled: false
description: 'Analyze with golangci-lint'
required_executable: 'golangci-lint'
install_command: 'go get github.com/golangci/golangci-lint/cmd/golangci-lint'
flags: ['--out-format=line-number', '--print-issued-lines=false']
command: ['golangci-lint', 'run']
include: '**/*.go'

GoLint:
enabled: false
description: 'Analyze with golint'
Expand Down Expand Up @@ -1253,6 +1262,14 @@ PrePush:
required_executable: 'git-lfs'
install_command: 'brew install git-lfs'

GolangciLint:
enabled: false
description: 'Analyze with golangci-lint'
required_executable: 'golangci-lint'
install_command: 'go get github.com/golangci/golangci-lint/cmd/golangci-lint'
flags: ['--out-format=line-number', '--print-issued-lines=false']
command: ['golangci-lint', 'run']

Minitest:
enabled: false
description: 'Run Minitest test suite'
Expand Down
21 changes: 21 additions & 0 deletions lib/overcommit/hook/pre_commit/golangci_lint.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# frozen_string_literal: true

module Overcommit::Hook::PreCommit
# Runs `golangci-lint run` against any modified packages
#
# @see https://github.com/golangci/golangci-lint
class GolangciLint < Base
def run
packages = applicable_files.map { |f| File.dirname(f) }.uniq
result = execute(command, args: packages)
return :pass if result.success?
return [:fail, result.stderr] unless result.stderr.empty?

extract_messages(
result.stdout.split("\n"),
/^(?<file>(?:\w:)?[^:]+):(?<line>\d+)/,
nil
)
end
end
end
16 changes: 16 additions & 0 deletions lib/overcommit/hook/pre_push/golangci_lint.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# frozen_string_literal: true

module Overcommit::Hook::PrePush
# Runs golangci-lint
#
# @see https://github.com/golangci/golangci-lint
class GolangciLint < Base
def run
result = execute(command)
return :pass if result.success?

output = result.stdout + result.stderr
[:fail, output]
end
end
end
98 changes: 98 additions & 0 deletions spec/overcommit/hook/pre_commit/golangci_lint_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# frozen_string_literal: true

require 'spec_helper'

describe Overcommit::Hook::PreCommit::GolangciLint do
let(:config) { Overcommit::ConfigurationLoader.default_configuration }
let(:context) { double('context') }
subject { described_class.new(config, context) }

let(:files) do
%w[
pkg1/file1.go
pkg1/file2.go
pkg2/file1.go
file1.go
]
end
let(:packages) { %w[pkg1 pkg2 .] }
before do
subject.stub(:applicable_files).and_return(files)
end

context 'when golangci-lint exits successfully' do
let(:result) { double('result') }

before do
result.stub(success?: true, stderr: '', stdout: '')
subject.stub(:execute).and_return(result)
end

it 'passes packages to golangci-lint' do
expect(subject).to receive(:execute).with(subject.command, args: packages)
subject.run
end

it 'passes' do
expect(subject).to pass
end
end

context 'when golangci-lint exits unsucessfully' do
let(:result) { double('result') }

before do
result.stub(:success?).and_return(false)
subject.stub(:execute).and_return(result)
end

context 'when golangci-lint returns an error' do
let(:error_message) do
'pkg1/file1.go:8:6: exported type `Test` should have comment or be unexported (golint)'
end

before do
result.stub(:stdout).and_return(error_message)
result.stub(:stderr).and_return('')
end

it 'passes packages to golangci-lint' do
expect(subject).to receive(:execute).with(subject.command, args: packages)
subject.run
end

it 'fails' do
expect(subject).to fail_hook
end

it 'returns valid message' do
message = subject.run.last
expect(message.file).to eq 'pkg1/file1.go'
expect(message.line).to eq 8
expect(message.content).to eq error_message
end
end

context 'when a generic error message is written to stderr' do
let(:error_message) { 'golangci-lint: command not found' }
before do
result.stub(:stdout).and_return('')
result.stub(:stderr).and_return(error_message)
end

it 'passes packages to golangci-lint' do
expect(subject).to receive(:execute).with(subject.command, args: packages)
subject.run
end

it 'fails' do
expect(subject).to fail_hook
end

it 'returns valid message' do
message = subject.run.last
expect(message).to eq error_message
end
end
end
end
68 changes: 68 additions & 0 deletions spec/overcommit/hook/pre_push/golangci_lint_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# frozen_string_literal: true

require 'spec_helper'

describe Overcommit::Hook::PrePush::GolangciLint do
let(:config) { Overcommit::ConfigurationLoader.default_configuration }
let(:context) { double('context') }
subject { described_class.new(config, context) }

context 'when golangci-lint exits successfully' do
let(:result) { double('result') }

before do
result.stub(success?: true, stderr: '', stdout: '')
subject.stub(:execute).and_return(result)
end

it 'passes' do
expect(subject).to pass
end
end

context 'when golangci-lint exits unsucessfully' do
let(:result) { double('result') }

before do
result.stub(:success?).and_return(false)
subject.stub(:execute).and_return(result)
end

context 'when golangci-lint returns an error' do
let(:error_message) do
'pkg1/file1.go:8:6: exported type `Test` should have comment or be unexported (golint)'
end

before do
result.stub(:stdout).and_return(error_message)
result.stub(:stderr).and_return('')
end

it 'fails' do
expect(subject).to fail_hook
end

it 'returns valid message' do
message = subject.run.last
expect(message).to eq error_message
end
end

context 'when a generic error message is written to stderr' do
let(:error_message) { 'golangci-lint: command not found' }
before do
result.stub(:stdout).and_return('')
result.stub(:stderr).and_return(error_message)
end

it 'fails' do
expect(subject).to fail_hook
end

it 'returns valid message' do
message = subject.run.last
expect(message).to eq error_message
end
end
end
end