Replace check-copyright-headers.sh with check-copyright-headers.sh.
[arvados-dev.git] / git / hooks / check-copyright-headers.rb
1 #!/usr/bin/env ruby
2
3 # Copyright (C) The Arvados Authors. All rights reserved.
4 #
5 # SPDX-License-Identifier: AGPL-3.0
6
7 # This script can be installed as a git update hook.
8
9 # It can also be installed as a gitolite 'hooklet' in the
10 # hooks/common/update.secondary.d/ directory.
11
12 # NOTE: this script runs under the same assumptions as the 'update' hook, so
13 # the starting directory must be maintained and arguments must be passed on.
14
15 $refname = ARGV[0]
16 $oldrev  = ARGV[1]
17 $newrev  = ARGV[2]
18 $user    = ENV['USER']
19
20 puts "Enforcing copyright headers..."
21 puts "(#{$refname}) (#{$oldrev[0,6]}) (#{$newrev[0,6]})"
22
23 def load_licenseignore
24   $licenseignore = `git show #{$newrev}:.licenseignore`.split("\n")
25 end
26
27 def check_file(filename, header, broken)
28   ignore = false
29   $licenseignore.each do |li|
30     if filename =~ /#{li}/
31       ignore = true
32     end
33   end
34   return broken if ignore
35
36   if header !~ /SPDX-License-Identifier:/
37     if not broken
38       puts "\nERROR\n"
39     end
40     puts "missing or invalid copyright header in file #{filename}"
41     broken = true
42   end
43   return broken
44 end
45
46 # enforce copyright headers
47 def check_copyright_headers
48   if ($newrev[0,6] ==  '000000')
49     # A branch is being deleted. Do not check old commits for DCO signoff!
50     all_revs    = []
51   elsif ($oldrev[0,6] ==  '000000')
52     if $refname != 'refs/heads/master'
53       # A new branch was pushed. Check all new commits in this branch.
54       puts "git rev-list --objects master..#{$newrev} | git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)'| sed -n 's/^blob //p'"
55       blob_revs  = `git rev-list --objects master..#{$newrev} | git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)'| sed -n 's/^blob //p'`.split("\n")
56       commit_revs  = `git rev-list --objects master..#{$newrev} | git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)'| sed -n 's/^commit //p'`.split("\n")
57       all_revs = blob_revs + commit_revs
58     else
59       # When does this happen?
60       puts "UNEXPECTED ERROR"
61       exit 1
62     end
63   else
64     blob_revs = `git rev-list --objects #{$oldrev}..#{$newrev} --not --branches='*' | git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)'| sed -n 's/^blob //p'`.split("\n")
65     commit_revs  = `git rev-list --objects #{$oldrev}..#{$newrev} | git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)'| sed -n 's/^commit //p'`.split("\n")
66     all_revs = blob_revs + commit_revs
67   end
68
69   broken = false
70
71   all_revs.each do |rev|
72     ignore = false
73     tmp = rev.split(' ')
74     if tmp[2].nil?
75       # git object of type 'commit'
76        # This could be a new file that was added in this commit
77       # If this wasn't a bare repo, we could run the following to get the list of new files in this commit:
78       #    new_files = `git show #{tmp[0]} --name-only --diff-filter=A --pretty=""`.split("\n")
79       # Instead, we just look at all the files touched in the commit and check the diff to see
80       # see if it is a new file. This could prove brittle...
81       files = `git show #{tmp[0]} --name-only --pretty=""`.split("\n")
82       files.each do |f|
83         filename = f
84         commit = `git show #{tmp[0]} -- #{f}`
85         if commit =~ /^new file mode \d{6}\nindex 000000/
86           /^.*?@@\n(.*)$/m.match(commit)
87           header = `echo "#{$1}" | head -n20 | egrep -A3 -B1 'Copyright.*All rights reserved.'`
88           broken = check_file(filename, header, broken)
89         end
90       end
91     else
92       # git object of type 'blob'
93       filename = tmp[2]
94       header = `git show #{tmp[0]} | head -n20 | egrep -A3 -B1 'Copyright.*All rights reserved.'`
95       broken = check_file(filename, header, broken)
96     end
97   end
98
99   if broken
100     puts
101     puts "[POLICY] all files must contain copyright headers, for more information see"
102     puts
103     puts "          https://arvados.org/projects/arvados/wiki/Coding_Standards#Copyright-headers"
104     puts
105     puts "Enforcing copyright headers: FAIL"
106     exit 1
107
108   end
109   puts "Enforcing copyright headers: PASS"
110 end
111
112 load_licenseignore
113 check_copyright_headers