/[osn-commons]/trunk/srcproc/addlicense
ViewVC logotype

Contents of /trunk/srcproc/addlicense

Parent Directory Parent Directory | Revision Log Revision Log


Revision 60 - (show annotations)
Tue Sep 10 14:47:23 2024 UTC (6 months, 3 weeks ago) by rakinar2
File size: 11298 byte(s)
feat: add addlicense script

1 #!/bin/sh
2 #
3 # addlicense -- a script to insert license comments automatically
4 #
5 # This script is part of OSN Commons. Copyright (C) 2024 OSN Developers.
6 #
7 # OSN Commons is free software: you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
11 #
12 # OSN Commons is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with OSN Commons. If not, see <https://www.gnu.org/licenses/>.
19 #
20
21 me=$0
22 canonical_name=$(echo $me | rev | cut -d'/' -f1 | rev)
23
24 if [ $(echo $me | cut -c1) = "/" ]; then
25 me=$canonical_name
26 fi
27
28 version="1.0.0"
29
30 usage() {
31 echo "Usage: $me [options...] [[directory...] | [-]]"
32 echo "Automatically insert license comments to the project's "
33 echo "source files."
34 echo ""
35 echo "Options:"
36 echo " -e, --exclude Add an exclusion pattern"
37 echo " -i, --include Add an inclusion pattern"
38 echo " -E, --exclude-file Exclude a file path"
39 echo " -I, --include-file Include a file path"
40 echo " -h, --help Show this help and exit"
41 echo " -v, --version Show version info and exit"
42 echo " -f, --file Specify a file containing the license"
43 echo " notice to insert"
44 echo ""
45 echo "Bug reports and general questions should be sent to "
46 echo "<[email protected]>."
47 exit 0
48 }
49
50 show_version() {
51 echo "$canonical_name (OSN Commons) v$version"
52 echo ""
53 echo "Copyright (C) 2024 OSN Developers."
54 echo "License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>."
55 echo "This is free software: you are free to change and redistribute it."
56 echo "There is NO WARRANTY, to the extent permitted by law."
57 echo ""
58 echo "Written by Ar Rakin."
59 exit 0
60 }
61
62 trim_string() {
63 echo "$1" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//'
64 }
65
66 targets=""
67 exclpats=""
68 inclpats=""
69 exclfiles=""
70 inclfiles=""
71 license_notice_file=""
72 license_notice="/*
73 * This program is free software: you can redistribute it and/or modify
74 * it under the terms of the GNU General Public License as published by
75 * the Free Software Foundation, either version 3 of the License, or
76 * (at your option) any later version.
77 *
78 * This program is distributed in the hope that it will be useful,
79 * but WITHOUT ANY WARRANTY; without even the implied warranty of
80 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
81 * GNU General Public License for more details.
82 *
83 * You should have received a copy of the GNU General Public License
84 * along with this program. If not, see <https://www.gnu.org/licenses/>.
85 */"
86 stdin_read=""
87
88 while [ $# -gt 0 ]; do
89 case "$1" in
90 -h | --help)
91 usage
92 ;;
93
94 -v | --version)
95 show_version
96 ;;
97
98 -e | --exclude)
99 if [ -z "$2" ]; then
100 echo "$me: option requires an argument -- '$1'" >&2
101 echo "Try '$me --help' for more detailed information." >&2
102 exit 2
103 fi
104
105 if [ "$2" != "$(echo "$2" | tr -d ':')" ]; then
106 echo "$me: exclusion patterns must not contain colons (':')" >&2
107 exit 2
108 fi
109
110 if [ -z "$exclpats" ]; then
111 exclpats="$2"
112 else
113 exclpats="$exclpats:$2"
114 fi
115
116 shift
117 ;;
118
119 -i | --include)
120 if [ -z "$2" ]; then
121 echo "$me: option requires an argument -- '$1'" >&2
122 echo "Try '$me --help' for more detailed information." >&2
123 exit 2
124 fi
125
126 if [ "$2" != "$(echo "$2" | tr -d ':')" ]; then
127 echo "$me: inclusion patterns must not contain colons (':')" >&2
128 exit 2
129 fi
130
131 if [ -z "$inclpats" ]; then
132 inclpats="$2"
133 else
134 inclpats="$inclpats:$2"
135 fi
136
137 shift
138 ;;
139
140 -E | --exclude-file)
141 if [ -z "$2" ]; then
142 echo "$me: option requires an argument -- '$1'" >&2
143 echo "Try '$me --help' for more detailed information." >&2
144 exit 2
145 fi
146
147 if [ "$2" != "$(echo "$2" | tr -d ':')" ]; then
148 echo "$me: file paths must not contain colons (':')" >&2
149 exit 2
150 fi
151
152 if [ ! -f "$2" ]; then
153 echo "$me: $2: No such file or directory" >&2
154 exit 2
155 fi
156
157 file=$(readlink -f "$2")
158
159 if [ $? -ne 0 ]; then
160 echo "$me: $2: Ignoring" >&2
161 else
162 if [ -z "$exclfiles" ]; then
163 exclfiles="$file"
164 else
165 exclfiles="$exclfiles:$file"
166 fi
167 fi
168
169 shift
170 ;;
171
172 -I | --include-file)
173 if [ -z "$2" ]; then
174 echo "$me: option requires an argument -- '$1'" >&2
175 echo "Try '$me --help' for more detailed information." >&2
176 exit 2
177 fi
178
179 if [ "$2" != "$(echo "$2" | tr -d ':')" ]; then
180 echo "$me: file paths must not contain colons (':')" >&2
181 exit 2
182 fi
183
184 if [ ! -f "$2" ]; then
185 echo "$me: $2: No such file or directory" >&2
186 exit 2
187 fi
188
189 file=$(readlink -f "$2")
190
191 if [ $? -ne 0 ]; then
192 echo "$me: $2: Ignoring" >&2
193 else
194 if [ -z "$inclfiles" ]; then
195 inclfiles="$file"
196 else
197 inclfiles="$inclfiles:$file"
198 fi
199 fi
200
201 shift
202 ;;
203
204 -f | --file)
205 if [ -z "$2" ]; then
206 echo "$me: option requires an argument -- '$1'" >&2
207 echo "Try '$me --help' for more detailed information." >&2
208 exit 2
209 fi
210
211 if [ "$2" = "-" ]; then
212 if [ -t 0 ]; then
213 echo "$me: nothing to read from standard input" >&2
214 exit 2
215 fi
216
217 if [ ! -z "$stdin_read" ] && [ "$stdin_read" != "notice" ]; then
218 echo "$me: multiple options are being directed to standard input" >&2
219 exit 2
220 fi
221
222 license_notice="$(cat)"
223 stdin_read="notice"
224 else
225 if [ ! -f "$2" ]; then
226 echo "$me: $2: No such file or directory" >&2
227 exit 2
228 fi
229
230 license_notice_file="$2"
231 license_notice=$(cat $2)
232 fi
233
234 shift
235 ;;
236
237 -)
238 if [ -t 0 ]; then
239 echo "$me: nothing to read from standard input" >&2
240 exit 2
241 fi
242
243 if [ ! -z "$stdin_read" ] && [ "$stdin_read" != "targets" ]; then
244 echo "$me: multiple options are being directed to standard input" >&2
245 exit 2
246 fi
247
248 while IFS='' read -r line; do
249 if [ "$line" != "$(echo "$line" | tr -d ':')" ] || [ -z "$line" ]; then
250 echo "$me: target paths must not contain colons (':')" >&2
251 exit 2
252 fi
253
254 if [ -z "$targets" ]; then
255 targets="$line"
256 else
257 targets="$targets:$line"
258 fi
259 done
260
261 stdin_read="targets"
262 ;;
263
264 -*)
265 echo "$me: Invalid option -- '$1'" >&2
266 echo "Try '$me --help' for more detailed information." >&2
267 exit 2
268 ;;
269
270 *)
271 if [ "$1" != "$(echo "$1" | tr -d ':')" ] || [ -z "$1" ]; then
272 echo "$me: target paths must not contain colons (':')" >&2
273 exit 2
274 fi
275
276 if [ -z "$targets" ]; then
277 targets="$1"
278 else
279 targets="$targets:$1"
280 fi
281 ;;
282 esac
283
284 shift
285 done
286
287 if [ -z "$targets" ]; then
288 echo "$me: No target operands specified" >&2
289 echo "Try '$me --help' for more detailed information" >&2
290 exit 2
291 fi
292
293 success=0
294
295 insert_license() {
296 set -e
297 local file=$1
298 local tmpfile=$(mktemp)
299
300 echo "$license_notice" >$tmpfile
301 echo "" >>$tmpfile
302 cat $file >>$tmpfile
303 mv $tmpfile $file
304 set +e
305 }
306
307 process_files() {
308 echo "$targets" | while IFS=':' read -r target; do
309 local stat_out=$(stat "$target" 2>&1)
310
311 if [ $? -ne 0 ]; then
312 echo "$me: $(echo $stat_out | cut -c 7-)" >&2
313 continue
314 fi
315
316 echo "$me: scanning: $target"
317 local find_cmd="find '$target' -type f ! -path \"*/*~\" \
318 ! -path \"*/.git/*\" ! -path \"*/.svn/*\" \
319 ! -path \"*/.hg/*\" ! -path \"*/CVS/*\" \
320 ! -path \"*/.bzr/*\" ! -path \"$me\""
321
322 if [ ! -z "$exclpats" ]; then
323 local ifs="$IFS"
324
325 IFS=":"
326
327 for exclpat in $exclpats; do
328 find_cmd="$find_cmd ! -path \"$exclpat\""
329 done
330
331 IFS="$ifs"
332 fi
333
334 if [ ! -z "$inclpats" ]; then
335 local ifs="$IFS"
336
337 IFS=":"
338
339 for inclpat in $inclpats; do
340 find_cmd="$find_cmd -path \"$inclpat\""
341 done
342
343 IFS="$ifs"
344 fi
345
346 local files=$(eval $find_cmd)
347
348 if [ -z "$files" ]; then
349 echo "$me: no files found" >&2
350 continue
351 fi
352
353 local r_license_notice_file
354
355 if [ ! -z "$license_notice_file" ]; then
356 r_license_notice_file=$(readlink -f "$license_notice_file")
357 fi
358
359 for file in $files; do
360 local rpath=$(readlink -f "$file")
361
362 if [ ! -z "$license_notice_file" ] && [ "$rpath" = "$r_license_notice_file" ]; then
363 continue
364 fi
365
366 if [ ! -z "$exclfiles" ]; then
367 local ifs="$IFS"
368
369 IFS=":"
370
371 for exclfile in $exclfiles; do
372 if [ "$rpath" = "$exclfile" ]; then
373 continue 2
374 fi
375 done
376
377 IFS="$ifs"
378 fi
379
380 if [ ! -z "$inclfiles" ]; then
381 local ifs="$IFS"
382
383 IFS=":"
384
385 for inclfile in $inclfiles; do
386 if [ "$rpath" = "$inclfile" ]; then
387 break
388 fi
389 done
390
391 if [ "$rpath" != "$inclfile" ]; then
392 continue
393 fi
394
395 IFS="$ifs"
396 fi
397
398 if file "$file" | grep -Eq 'binary|ELF|executable|data'; then
399 echo "$me: skipping binary file: $file"
400 continue
401 fi
402
403 local license_notice_size=$(echo "$license_notice" | wc -c)
404 local part=$(sed ':a; /^$/d; $!{N; ba}; s/^[[:space:]]*//' $file | head -c $license_notice_size)
405
406 if [ "$license_notice" = "$part" ]; then
407 echo "$me: license notice already present in: $file"
408 success=1
409 continue
410 fi
411
412 echo "$me: inserting license comment to: $file"
413 insert_license $file
414 done
415
416 success=1
417 done
418 }
419
420 process_files
421
422 if [ $success -ne 1 ]; then
423 exit 1
424 fi

Properties

Name Value
svn:executable *

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26