about summary refs log tree commit diff stats
path: root/licensor
diff options
context:
space:
mode:
authorCase Duckworth2022-06-30 17:28:12 -0500
committerCase Duckworth2022-06-30 17:28:22 -0500
commit4308699484e91053b471f64fdf29149087d8cd75 (patch)
tree8fb16136763edb0b509339f4fbaf3dd88c9e2a5d /licensor
parentUpdate README (diff)
downloadlicensor-4308699484e91053b471f64fdf29149087d8cd75.tar.gz
licensor-4308699484e91053b471f64fdf29149087d8cd75.zip
Update to version 1.0
Diffstat (limited to 'licensor')
-rwxr-xr-xlicensor251
1 files changed, 251 insertions, 0 deletions
diff --git a/licensor b/licensor new file mode 100755 index 0000000..47da938 --- /dev/null +++ b/licensor
@@ -0,0 +1,251 @@
1#!/bin/sh
2
3# Constants
4PRGN="${0##*/}"
5LICENSOR_CACHE="${XDG_CACHE_HOME:-$HOME/.cache/licensor"
6# Configuration
7: "${LICENSE_REPO_VERSION:=3.17}"
8: "${LICENSE_REPO_URL:=https://github.com/spdx/license-list-data/archive/refs/tags/v$LICENSE_REPO_VERSION.tar.gz}"
9: "${LICENSE_REPO_PATH:=license-list-data-$LICENSE_REPO_VERSION/template}"
10: "${LICENSOR_LICENSE:=MIT}"
11: "${LICENSOR_OUTPUT_FILE:=COPYING}"
12
13usage() {
14 cat <<EOF
15$PRGN: drop a lil ol license in yr project
16USAGE: $PRGN [-h|-m|-M]
17 $PRGN [FLAGS] [OPTIONS] [LICENSE]
18
19FLAGS:
20 -h Display this help and exit.
21 -l List available licenses and exit.
22 -L List available licenses, disregarding cache.
23 This flag will re-download the license repo.
24 -f Overwrite existing license.
25 -q Be quiet (don't log anything).
26
27OPTIONS:
28 -y YEARS Set copyright date(s) to YEARS.
29 Default: \$(date +%Y).
30 -a AUTHORS Set copyright holder(s) to AUTHOR.
31 Default: use the first of
32 - git config --get user.name
33 - getent password \$USER
34 - \$USER
35 -e EMAILS Set AUTHOR's EMAIL address.
36 Default: \$(git config --get user.email),
37 or stay blank.
38 -o FILE Output the fetched license to FILE.
39 Default: \$PWD/$LICENSOR_OUTPUT_FILE.
40
41PARAMETERS:
42 LICENSE The license to use.
43 Default: $LICENSOR_LICENSE.
44EOF
45 exit ${1:-0}
46}
47
48main() {
49 _force=false
50 _quiet=false
51 _fold=1
52 _optional=0
53 __width=70
54 __output="$LICENSOR_OUTPUT_FILE"
55 __year="$(date +%Y)"
56 __author="$(guess_author)"
57 __email="$(guess_email)"
58 __copyright="Copyright (C) $__year $__author <$__email>"
59
60 while getopts hlLs:fzZpPqy:a:e:o:w:c: opt; do
61 case "$opt" in
62 # commands
63 h) usage ;;
64 l) list_licenses && exit || exit $? ;;
65 L) list_licenses -f && exit || exit $? ;;
66 s) search_licenses "$OPTARG" ;;
67 # flags
68 f) _force=true ;;
69 z) _fold=1 ;;
70 Z) _fold=0 ;;
71 p) _optional=1 ;;
72 P) _optional=0 ;;
73 q) _quiet=true ;;
74 # options
75 y) __year="$OPTARG" ;;
76 a) __author="$OPTARG" ;;
77 e) __email="$OPTARG" ;;
78 o) __output="$OPTARG" ;;
79 w) __width="$OPTARG" ;;
80 c) __copyright="$OPTARG" ;;
81 *) usage 1 ;;
82 esac
83 done
84 shift $((OPTIND - 1))
85 __license="${1:-$LICENSOR_LICENSE}"
86
87 if [ -e "$__output" ] && ! $_force; then
88 log "File exists: $__output"
89 exit 3
90 fi
91
92 if [ "x$__output" = x- ]; then
93 __output=/dev/stdout
94 fi
95
96 license_file="$(get_license "$__license")" || exit $?
97 license_convert <"$LICENSOR_CACHE/$license_file.template.txt" \
98 "$__copyright" "$_optional" "$_fold" "$__width" >"$__output"
99 [ "$__output" != /dev/stdout ] && log "$__license license written to $__output."
100}
101
102get_licenses() {
103 # Get licenses from cache, or download them
104 if ! [ -d "$LICENSOR_CACHE" ] || [ "x$1" = "x-f" ]; then
105 log "Downlading licenses from $LICENSE_REPO_URL..."
106 mkdir -p "$LICENSOR_CACHE"
107 tmpfile="/tmp/licenses.tar.gz"
108 if ! [ -f "$tmpfile" ]; then
109 curl -o "$tmpfile" -L "$LICENSE_REPO_URL" >/dev/null 2>&1 ||
110 return 1
111 fi
112 log "Extracting licenses to $LICENSOR_CACHE..."
113 if tar -C "$LICENSOR_CACHE" \
114 -xvf "$tmpfile" --strip-components=2 \
115 "$LICENSE_REPO_PATH" >/dev/null 2>&1; then
116 rm "$tmpfile"
117 else
118 return 1
119 fi
120 fi
121}
122
123get_license() {
124 list_licenses | grep -iE '^'"$1"'$' || {
125 log "Can't find license \"$1\"."
126 exit 1
127 }
128}
129
130list_licenses() {
131 get_licenses "$1" || exit 1
132
133 find "$LICENSOR_CACHE" -iname '*.template.txt' |
134 sort |
135 xargs basename -s .template.txt
136}
137
138search_licenses() {
139 list_licenses | grep -iE "$1"
140 exit $?
141}
142
143guess_author() {
144 author="$(git config --get user.name)"
145 [ -z "$author" ] &&
146 author="$(getent passwd "$USER" | awk -F: '{sub(/,+/,"",$5);print $5}')"
147 [ -z "$author" ] &&
148 author="$USER"
149 put "$author"
150}
151guess_email() {
152 email="$(git config --get user.email)"
153 put "$email"
154}
155
156put() { printf '%s\n' "$*"; }
157log() { $_quiet || put "$PRGN: $*" >&2; }
158
159license_convert() {
160 copyright="$1" # "Copyright (C) 2022 Case Duckworth <acdw@acdw.net>"
161 show_optional="${2:-0}" # 0
162 fold_output="${3:-1}" # 1
163 fold_width="${4:-70}" # 70
164 awk '
165BEGIN {
166 foldOutput = '"$fold_output"'
167 foldWidth = '"$fold_width"'
168 showOptional = '"$show_optional"'
169 copyright = "'"$copyright"'"
170}
171{ buf = buf "\n" $0 }
172END {
173 split(buf, b, "")
174 c = 1
175 out = ""
176 optstr = ""
177 opt = 0
178 while (c <= length(b)) {
179 if (b[c] == "<" && b[c + 1] == "<") {
180 tok = ""
181 c += 2
182 closed = 0
183 while (! closed) {
184 tok = tok b[c++]
185 if (b[c] == ">" && b[c + 1] == ">") {
186 closed++
187 c += 2
188 }
189 }
190 if (tok ~ /^beginOptional/) {
191 opt = 1
192 } else if (tok == "endOptional") {
193 if (showOptional) {
194 out = out optstr
195 }
196 opt = 0
197 optstr = ""
198 } else if (tok ~ /^var/) {
199 split(tok, ta, ";")
200 name = ""
201 original = ""
202 for (a in ta) {
203 if (ta[a] ~ "^name") {
204 match(ta[a], /=".*/)
205 name = substr(ta[a], RSTART + 2, RLENGTH - 3)
206 } else if (ta[a] ~ "^original") {
207 match(ta[a], /=".*/)
208 original = substr(ta[a], RSTART + 2, RLENGTH - 3)
209 } else if (ta[a] ~ "^match") {
210 # currently not used
211 }
212 }
213 if (name == "copyright") {
214 out = out copyright
215 } else {
216 out = out original
217 }
218 }
219 continue
220 }
221 if (opt) {
222 optstr = optstr b[c++]
223 } else {
224 out = out b[c++]
225 }
226 }
227 # "Fold" the output
228 if (foldOutput) {
229 split(out, oa, "\n")
230 out = ""
231 for (l in oa) {
232 split(oa[l], la, FS)
233 lc = 0
234 for (w in la) {
235 lc += length(la[w]) + 1
236 if (lc >= foldWidth) {
237 out = out "\n" la[w] " "
238 lc = length(la[w]) + 1
239 } else {
240 out = out la[w] " "
241 }
242 }
243 out = out "\n"
244 }
245 }
246 print out
247}
248'
249}
250
251main "$@"