Skip to content

Commit a5fcece

Browse files
ascandellasds
authored andcommitted
Add licence header enforcement
1 parent 999038d commit a5fcece

File tree

4 files changed

+105
-0
lines changed

4 files changed

+105
-0
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
## master
44

55
* Add [`YAMLLint`](https://github.com/adrienverge/yamllint) pre-commit hook
6+
* Add `LicenceHeader` pre-commit enforcement to ensure open source projects
7+
contain proper licence comments.
68

79
## 0.36.0
810

config/default.yml

+5
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,11 @@ PreCommit:
367367
install_command: 'gem install json'
368368
include: '**/*.json'
369369

370+
LicenceHeader:
371+
enabled: false
372+
licence_file: 'LICENSE.txt'
373+
description: 'Check source files for licence headers'
374+
370375
LocalPathsInGemfile:
371376
enabled: false
372377
description: 'Check for local paths in Gemfile'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
module Overcommit::Hook::PreCommit
2+
# Checks for licence headers in source files
3+
class LicenceHeader < Base
4+
def run
5+
begin
6+
licence_contents = licence_lines
7+
rescue Errno::ENOENT
8+
return :fail, "Unable to load licence file #{licence_file}"
9+
end
10+
11+
messages = applicable_files.map do |file|
12+
check_file(file, licence_contents)
13+
end.compact
14+
15+
return :fail, messages.join("\n") if messages.any?
16+
17+
:pass
18+
end
19+
20+
def check_file(file, licence_contents)
21+
File.readlines(file).each_with_index do |l, i|
22+
if i >= licence_contents.length
23+
break
24+
end
25+
26+
l.chomp!
27+
unless l.end_with?(licence_contents[i])
28+
message = "#{file} missing header contents from line #{i} of "\
29+
"#{licence_file}: #{licence_contents[i]}"
30+
return message
31+
end
32+
end
33+
end
34+
35+
def licence_file
36+
config['licence_file']
37+
end
38+
39+
def licence_lines
40+
@licence_regex ||= begin
41+
file_root = Overcommit::Utils.convert_glob_to_absolute(licence_file)
42+
File.read(file_root).split("\n")
43+
end
44+
end
45+
end
46+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
require 'spec_helper'
2+
3+
describe Overcommit::Hook::PreCommit::LicenceHeader do
4+
let(:config) { Overcommit::ConfigurationLoader.default_configuration }
5+
let(:context) { double('context') }
6+
subject { described_class.new(config, context) }
7+
8+
around do |example|
9+
repo do
10+
example.run
11+
end
12+
end
13+
14+
context 'when license file is missing' do
15+
it { should fail_hook }
16+
end
17+
18+
context 'when license file exists' do
19+
let(:license_contents) { <<-LICENSE }
20+
Look at me
21+
I'm a license
22+
LICENSE
23+
24+
let(:file) { 'some-file.txt' }
25+
26+
before do
27+
File.open('LICENSE.txt', 'w') { |f| f.write(license_contents) }
28+
subject.stub(:applicable_files).and_return([file])
29+
end
30+
31+
context 'when all files contain the license header' do
32+
before do
33+
File.open(file, 'w') do |f|
34+
license_contents.split("\n").each do |line|
35+
f.puts("// #{line}")
36+
end
37+
f.write('And some text')
38+
end
39+
end
40+
41+
it { should pass }
42+
end
43+
44+
context 'when a file is missing a licence header' do
45+
before do
46+
File.open(file, 'w') { |f| f.write('Some text without a license') }
47+
end
48+
49+
it { should fail_hook }
50+
end
51+
end
52+
end

0 commit comments

Comments
 (0)