rename(unitproc/bkt-replace_apostrophes):Was replace_contractions
[BK-2020-03.git] / user / get_gpgkey_from_gitlog.sh
1 #!/usr/bin/env bash
2 # Desc: A script that outputs a list of GPG signatures from git log output
3 # Usage: get_gpgkey_from_gitlog.sh [dir]
4 # Input: arg1: directory
5 # Output: stdout: newline-delimited list of 40-char GPG fingerprints
6 # Version: 0.1.0
7
8 declare -g buffer;
9 declare -Ag appRollCall # Associative array for storing app status
10 declare -Ag fileRollCall # Associative array for storing file status
11 declare -Ag dirRollCall # Associative array for storing dir status
12
13 yell() { echo "$0: $*" >&2; } # print script path and all args to stderr
14 die() { yell "$*"; exit 111; } # same as yell() but non-zero exit status
15 try() { "$@" || die "cannot $*"; } # runs args as command, reports args if command fails
16 checkapp() {
17 # Desc: If arg is a command, save result in assoc array 'appRollCall'
18 # Usage: checkapp arg1 arg2 arg3 ...
19 # Version: 0.1.1
20 # Input: global assoc. array 'appRollCall'
21 # Output: adds/updates key(value) to global assoc array 'appRollCall'
22 # Depends: bash 5.0.3
23 local returnState
24
25 #===Process Args===
26 for arg in "$@"; do
27 if command -v "$arg" 1>/dev/null 2>&1; then # Check if arg is a valid command
28 appRollCall[$arg]="true";
29 if ! [ "$returnState" = "false" ]; then returnState="true"; fi;
30 else
31 appRollCall[$arg]="false"; returnState="false";
32 fi;
33 done;
34
35 #===Determine function return code===
36 if [ "$returnState" = "true" ]; then
37 return 0;
38 else
39 return 1;
40 fi;
41 } # Check that app exists
42 checkfile() {
43 # Desc: If arg is a file path, save result in assoc array 'fileRollCall'
44 # Usage: checkfile arg1 arg2 arg3 ...
45 # Version: 0.1.2
46 # Input: global assoc. array 'fileRollCall'
47 # Output: adds/updates key(value) to global assoc array 'fileRollCall';
48 # Output: returns 0 if app found, 1 otherwise
49 # Depends: bash 5.0.3
50 local returnState
51
52 #===Process Args===
53 for arg in "$@"; do
54 if [ -f "$arg" ]; then
55 fileRollCall["$arg"]="true";
56 if ! [ "$returnState" = "false" ]; then returnState="true"; fi;
57 elif [ -z "$arg" ]; then
58 fileRollCall["(no name)"]="false"; returnState="false";
59 else
60 fileRollCall["$arg"]="false"; returnState="false";
61 fi;
62 done;
63
64 #===Determine function return code===
65 if [ "$returnState" = "true" ]; then
66 return 0;
67 else
68 return 1;
69 fi;
70 } # Check that file exists
71 checkdir() {
72 # Desc: If arg is a dir path, save result in assoc array 'dirRollCall'
73 # Usage: checkdir arg1 arg2 arg3 ...
74 # Version 0.1.2
75 # Input: global assoc. array 'dirRollCall'
76 # Output: adds/updates key(value) to global assoc array 'dirRollCall';
77 # Output: returns 0 if all args are dirs; 1 otherwise
78 # Depends: Bash 5.0.3
79 local returnState
80
81 #===Process Args===
82 for arg in "$@"; do
83 if [ -z "$arg" ]; then
84 dirRollCall["(Unspecified Dirname(s))"]="false"; returnState="false";
85 elif [ -d "$arg" ]; then
86 dirRollCall["$arg"]="true";
87 if ! [ "$returnState" = "false" ]; then returnState="true"; fi
88 else
89 dirRollCall["$arg"]="false"; returnState="false";
90 fi
91 done
92
93 #===Determine function return code===
94 if [ "$returnState" = "true" ]; then
95 return 0;
96 else
97 return 1;
98 fi
99 } # Check that dir exists
100 displayMissing() {
101 # Desc: Displays missing apps, files, and dirs
102 # Usage: displayMissing
103 # Version 1.0.0
104 # Input: associative arrays: appRollCall, fileRollCall, dirRollCall
105 # Output: stderr: messages indicating missing apps, file, or dirs
106 # Output: returns exit code 0 if nothing missing; 1 otherwise
107 # Depends: bash 5, checkAppFileDir()
108 local missingApps value appMissing missingFiles fileMissing
109 local missingDirs dirMissing
110
111 #==BEGIN Display errors==
112 #===BEGIN Display Missing Apps===
113 missingApps="Missing apps :";
114 #for key in "${!appRollCall[@]}"; do echo "DEBUG:$key => ${appRollCall[$key]}"; done
115 for key in "${!appRollCall[@]}"; do
116 value="${appRollCall[$key]}";
117 if [ "$value" = "false" ]; then
118 #echo "DEBUG:Missing apps: $key => $value";
119 missingApps="$missingApps""$key ";
120 appMissing="true";
121 fi;
122 done;
123 if [ "$appMissing" = "true" ]; then # Only indicate if an app is missing.
124 echo "$missingApps" 1>&2;
125 fi;
126 unset value;
127 #===END Display Missing Apps===
128
129 #===BEGIN Display Missing Files===
130 missingFiles="Missing files:";
131 #for key in "${!fileRollCall[@]}"; do echo "DEBUG:$key => ${fileRollCall[$key]}"; done
132 for key in "${!fileRollCall[@]}"; do
133 value="${fileRollCall[$key]}";
134 if [ "$value" = "false" ]; then
135 #echo "DEBUG:Missing files: $key => $value";
136 missingFiles="$missingFiles""$key ";
137 fileMissing="true";
138 fi;
139 done;
140 if [ "$fileMissing" = "true" ]; then # Only indicate if an app is missing.
141 echo "$missingFiles" 1>&2;
142 fi;
143 unset value;
144 #===END Display Missing Files===
145
146 #===BEGIN Display Missing Directories===
147 missingDirs="Missing dirs:";
148 #for key in "${!dirRollCall[@]}"; do echo "DEBUG:$key => ${dirRollCall[$key]}"; done
149 for key in "${!dirRollCall[@]}"; do
150 value="${dirRollCall[$key]}";
151 if [ "$value" = "false" ]; then
152 #echo "DEBUG:Missing dirs: $key => $value";
153 missingDirs="$missingDirs""$key ";
154 dirMissing="true";
155 fi;
156 done;
157 if [ "$dirMissing" = "true" ]; then # Only indicate if an dir is missing.
158 echo "$missingDirs" 1>&2;
159 fi;
160 unset value;
161 #===END Display Missing Directories===
162
163 #==END Display errors==
164 #==BEGIN Determine function return code===
165 if [ "$appMissing" == "true" ] || [ "$fileMissing" == "true" ] || [ "$dirMissing" == "true" ]; then
166 return 1;
167 else
168 return 0;
169 fi
170 #==END Determine function return code===
171 } # Display missing apps, files, dirs
172 check_depends() {
173 if checkapp git grep; then displayMissing; die "FATAL:Missing apps."; fi;
174 if ! ( echo "foo" | sort -u ); then die "FATAL:Incompatible version:sort"; fi;
175 return 0;
176 }; # check for available commands
177 check_args() {
178 # Desc: Check arguments
179 if [[ $# -ne 1 ]]; then die "FATAL:Incorrect number of arguments:$#"; fi;
180 if [[ ! -d $1 ]]; then die "Not a directory:$1"; fi;
181 return 0;
182 }; # check args
183 fill_buffer() {
184 # Input: arg1: git dir
185 # Output: var: $buffer: newline-delimited list of gpg fingerprints
186 pushd "$1" 1>/dev/random || die "FATAL:Failed to change directory:$1";
187 buffer="$(try git log --show-signature 2>&1)";
188 #yell "DEBUG:Buffer has $(wc -l < <(printf "%s" "$buffer")) lines.";
189 buffer="$(try grep -E -- "^gpg:" < <( printf "%s" "$buffer" ) )";
190 #yell "DEBUG:Buffer has $(wc -l < <(printf "%s" "$buffer")) lines.";
191 buffer="$(try grep -Eo "([0-9A-F]){40}" < <( printf "%s" "$buffer" ) )";
192 #yell "DEBUG:Buffer has $(wc -l < <(printf "%s" "$buffer")) lines.";
193 buffer="$(try sort -u < <( printf "%s" "$buffer" ))";
194 #yell "DEBUG:Buffer has $(wc -l < <(printf "%s" "$buffer")) lines.";
195 popd 1>/dev/random || die "FATAL:Failed to popd.";
196 }; # fill buffer with git gpg lines
197 main() {
198 check_args "$@";
199 fill_buffer "$1";
200 printf "%s\n" "$buffer";
201 return 0;
202 };
203
204 main "$@";
205
206 # git log --show-signature 2>&1 | grep -E -- "^gpg:" | grep -Eo "([0-9A-F]){40}" | sort -u