Merge branch '2411-check-copyright'
[arvados.git] / build / check-copyright-notices
1 #!/bin/bash
2 # Copyright (C) The Arvados Authors. All rights reserved.
3 #
4 # SPDX-License-Identifier: AGPL-3.0
5
6 set -e
7
8 fix=false
9 while [[ "${@}" != "" ]]
10 do
11     arg=${1}
12     shift
13     case ${arg} in
14         --help)
15             cat <<EOF
16 Usage: $0 [--fix] [-- git-ls-args...]
17
18 Options:
19
20 --fix   Insert missing copyright notices where possible.
21
22 Git arguments:
23
24 Arguments after "--" are passed to \`git ls-files\`; this can be used to
25 restrict the set of files to check.
26
27 EOF
28             exit 2
29             ;;
30         --fix)
31             fix=true
32             ;;
33         --)
34             break
35             ;;
36         *)
37             echo >&2 "Unrecognized argument '${arg}'. Try $0 --help"
38             exit 2
39             ;;
40     esac
41 done
42
43 fixer() {
44     want="${want}" perl -pi~ - "${1}" <<'EOF'
45 BEGIN { undef $/ }
46 s{^((\#\!.*?\n|\n*---\n.*?\n\.\.\.\n|<\?xml.*?>\n)\n?)?}{${2}$ENV{want}\n\n}ms
47 EOF
48 }
49
50 IFS=$'\n' read -a ignores -r -d $'\000' <.licenseignore || true
51 result=0
52 git ls-files -z ${@} | \
53     while read -rd $'\000' fnm
54     do
55         grepAfter=2
56         grepBefore=0
57         cs=
58         cc=
59         ce=
60         fixer=
61         if [[ ! -f ${fnm} ]] || [[ -L ${fnm} ]] || [[ ! -s ${fnm} ]]
62         then
63             continue
64         fi
65
66         ignore=
67         for pattern in "${ignores[@]}"
68         do
69             if [[ ${fnm} == ${pattern} ]]
70             then
71                 ignore=1
72             fi
73         done
74         if [[ ${ignore} = 1 ]]; then continue; fi
75
76         case ${fnm} in
77             Makefile | */Makefile \
78                 | *.dockerfile | */Dockerfile.* | */Dockerfile | *.dockerignore \
79                 | */MANIFEST.in | */fuse.conf | */gitolite.rc \
80                 | *.pl | *.pm | *.PL \
81                 | *.rb | *.rb.example | *.rake | *.ru \
82                 | *.gemspec | */Gemfile | */Rakefile \
83                 | services/login-sync/bin/* \
84                 | sdk/cli/bin/* \
85                 | *.py \
86                 | sdk/python/bin/arv-* \
87                 | sdk/cwl/bin/* \
88                 | services/nodemanager/bin/* \
89                 | services/fuse/bin/* \
90                 | tools/crunchstat-summary/bin/* \
91                 | crunch_scripts/* \
92                 | *.yaml | *.yml | *.yml.example | *.cwl \
93                 | *.sh | *.service \
94                 | */run | */run-service | */restart-dns-server \
95                 | */nodemanager/doc/*.cfg \
96                 | */nodemanager/tests/fake*.cfg.template \
97                 | */nginx.conf \
98                 | build/build.list)
99                 fixer=fixer
100                 cc="#"
101                 ;;
102             *.md)
103                 fixer=fixer
104                 cc="[//]: #"
105                 ;;
106             *.rst)
107                 fixer=fixer
108                 cc=".."
109                 ;;
110             *.erb)
111                 fixer=fixer
112                 cs="<%# "
113                 cc=""
114                 ce=" %>"
115                 ;;
116             *.liquid)
117                 fixer=fixer
118                 cs=$'{% comment %}\n'
119                 cc=""
120                 ce=$'\n{% endcomment %}'
121                 grepAfter=3
122                 grepBefore=1
123                 ;;
124             *.textile)
125                 fixer=fixer
126                 cs="###. "
127                 cc="...."
128                 ce=
129                 ;;
130             *.css)
131                 fixer=fixer
132                 cs="/* "
133                 cc=""
134                 ce=" */"
135                 ;;
136             *.coffee)
137                 fixer=fixer
138                 cs="### "
139                 cc=""
140                 ce=" ###"
141                 ;;
142             *.go | *.scss | *.java | *.js)
143                 fixer=fixer
144                 cc="//"
145                 ;;
146             *.sql)
147                 fixer=fixer
148                 cc="--"
149                 ;;
150             *.html | *.svg)
151                 fixer=fixer
152                 cs="<!-- "
153                 cc=""
154                 ce=" -->"
155                 ;;
156             *)
157                 cc="#"
158                 hashbang=$(head -n1 ${fnm})
159                 if [[ ${hashbang} = "#!/bin/sh" ]] ||  [[ ${hashbang} = "#!/bin/bash" ]]
160                 then
161                     fixer=fixer
162                 fi
163                 ;;
164         esac
165         wantGPL="${cs:-${cc}${cc:+ }}Copyright (C) The Arvados Authors. All rights reserved.
166 ${cc}
167 ${cc}${cc:+ }SPDX-License-Identifier: AGPL-3.0${ce}"
168         wantApache="${cs:-${cc}${cc:+ }}Copyright (C) The Arvados Authors. All rights reserved.
169 ${cc}
170 ${cc}${cc:+ }SPDX-License-Identifier: Apache-2.0${ce}"
171         wantBYSA="${cs:-${cc}${cc:+ }}Copyright (C) The Arvados Authors. All rights reserved.
172 ${cc}
173 ${cc}${cc:+ }SPDX-License-Identifier: CC-BY-SA-3.0${ce}"
174         found=$(head -n20 "$fnm" | egrep -A${grepAfter} -B${grepBefore} 'Copyright.*Arvados' || true)
175         case ${fnm} in
176             Makefile | build/* | lib/* | tools/* | apps/* | services/*)
177                 want=${wantGPL}
178                 ;;
179             crunch_scripts/* | backports/* | docker/* | sdk/*)
180                 want=${wantApache}
181                 ;;
182             README.md | doc/*)
183                 want=${wantBYSA}
184                 ;;
185             *)
186                 want=
187                 ;;
188         esac
189         case "$found" in
190             "$wantGPL")
191                 ;;
192             "$wantApache")
193                 ;;
194             "$wantBYSA")
195                 ;;
196             "")
197                 if [[ -z ${found} ]] && [[ -n ${want} ]] && [[ $fix = true ]] && [[ $fixer != "" ]]
198                 then
199                     ${fixer} ${fnm}
200                 else
201                     echo "missing copyright notice: $fnm"
202                     result=1
203                 fi
204                 ;;
205             *)
206                 echo "nonstandard copyright notice: $fnm '${found}'"
207                 result=1
208                 ;;
209         esac
210     done
211 exit $result