3 # Copyright (C) The Arvados Authors. All rights reserved.
5 # SPDX-License-Identifier: AGPL-3.0
7 # This script can be installed as a git update hook.
9 # It can also be installed as a gitolite 'hooklet' in the
10 # hooks/common/update.secondary.d/ directory.
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.
20 puts "Enforcing copyright headers..."
21 puts "(#{$refname}) (#{$oldrev[0,6]}) (#{$newrev[0,6]})"
23 def load_licenseignore
24 $licenseignore = `git show #{$newrev}:.licenseignore`.split("\n")
27 def check_file(filename, header, broken)
29 $licenseignore.each do |li|
30 if filename =~ /#{li}/
34 return broken if ignore
36 if header !~ /SPDX-License-Identifier:/
40 puts "missing or invalid copyright header in file #{filename}"
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!
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
59 # When does this happen?
60 puts "UNEXPECTED ERROR"
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
71 all_revs.each do |rev|
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")
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)
92 # git object of type 'blob'
94 header = `git show #{tmp[0]} | head -n20 | egrep -A3 -B1 'Copyright.*All rights reserved.'`
95 broken = check_file(filename, header, broken)
101 puts "[POLICY] all files must contain copyright headers, for more information see"
103 puts " https://arvados.org/projects/arvados/wiki/Coding_Standards#Copyright-headers"
105 puts "Enforcing copyright headers: FAIL"
109 puts "Enforcing copyright headers: PASS"
113 check_copyright_headers