-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbash-functions
More file actions
438 lines (402 loc) · 12 KB
/
bash-functions
File metadata and controls
438 lines (402 loc) · 12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
# vim: syntax=sh tabstop=4 shiftwidth=4
function abort {
if [ ! -z "$1" ]; then
echo $@ >&2
fi
exit 1
}
function die {
abort "$@"
}
function waitforpid {
for pid in "$@"; do
while kill -0 "$pid" 2>/dev/null; do
sleep 0.5
done
done
}
function color {
if [ ! -z "$1" ] && [ -f "$1" ]; then
color < $1
else
printf '\x1b[41m\x1b[37m%q\x1b[0m' $(cat)
fi
}
function failcolor {
if [ "$1" = '-h' -o "$1" = '--help' ]; then
echo "Usage: ${FUNCNAME[0]} STRING"
echo "Print STDIN using \`color' if output does not match STRING"
return 1
fi
inputstring=$(cat)
if [ "$inputstring" != "$1" ]; then
color <<< "$inputstring"
else
printf '%q' "$inputstring"
fi
}
function findfunction {
if [ "$(type -t "$1")" != "function" ]; then
type "$1"
return 0
fi
shopt -s extdebug
declare -F "$1"
type "$1"
shopt -u extdebug
}
function codex_update {
local parsed_args codex_path codex_dir brew_prefix npm_prefix file_output
local detected_method requested_method method version dry_run installed action
local current_version target_version release_json
parsed_args="$(getopt -o hm:n --long help,method:,dry-run -- "$@")" || return 2
eval set -- "$parsed_args"
requested_method=""
dry_run=0
while true; do
case "$1" in
-h|--help)
echo "Usage: ${FUNCNAME[0]} [--dry-run] [--method brew|npm|install.sh] [VERSION]"
echo "Update Codex if installed, or install it if missing."
echo
echo "If Codex is already installed, the existing install method is preserved unless --method is given."
echo "If Codex is missing, the default install order is brew, then npm, then install.sh."
return 0
;;
-m|--method)
requested_method="$2"
shift 2
;;
-n|--dry-run)
dry_run=1
shift
;;
--)
shift
break
;;
*)
echo "Unexpected option parsing state: $1" >&2
return 2
;;
esac
done
version="${1:-latest}"
if [ $# -gt 1 ]; then
echo "Too many arguments." >&2
return 2
fi
case "$requested_method" in
""|brew|npm|install.sh)
;;
*)
echo "Unsupported method: $requested_method" >&2
echo "Expected one of: brew, npm, install.sh" >&2
return 2
;;
esac
codex_path="$(command -v codex 2>/dev/null || true)"
if [ -n "$codex_path" ]; then
installed=1
codex_dir="$(cd "$(dirname "$codex_path")" 2>/dev/null && pwd -P)"
else
installed=0
codex_dir=""
fi
detected_method="unknown"
if hash brew 2> /dev/null; then
brew_prefix="$(brew --prefix 2>/dev/null || true)"
if brew list --cask codex >/dev/null 2>&1; then
if [ -z "$codex_path" ] || [[ "$codex_path" == "$brew_prefix/"* ]]; then
detected_method="brew"
fi
elif brew list --formula codex >/dev/null 2>&1 || brew list codex >/dev/null 2>&1; then
if [ -z "$codex_path" ] || [[ "$codex_path" == "$brew_prefix/"* ]]; then
detected_method="brew"
fi
fi
fi
if [ "$detected_method" = "unknown" ] && hash npm 2> /dev/null; then
npm_prefix="$(npm prefix -g 2>/dev/null || true)"
if [ -n "$npm_prefix" ] && [ -f "$npm_prefix/lib/node_modules/@openai/codex/package.json" ]; then
if [ -z "$codex_path" ] || [ "$codex_dir" = "$npm_prefix/bin" ]; then
detected_method="npm"
fi
fi
fi
if [ "$detected_method" = "unknown" ] && [ -n "$codex_path" ] && [ -f "$codex_path" ]; then
file_output="$(file "$codex_path" 2>/dev/null || true)"
if [[ "$file_output" == *ELF* || "$file_output" == *Mach-O* ]]; then
if [ -x "$codex_dir/rg" ] || [ "$codex_dir" = "$HOME/.local/bin" ]; then
detected_method="install.sh"
fi
fi
fi
if [ "$installed" -eq 1 ]; then
if [ "$detected_method" = "unknown" ]; then
echo "Codex is installed, but the install method could not be determined." >&2
echo "Checked for Homebrew, npm, and the official install.sh binary install." >&2
return 1
fi
if [ -n "$requested_method" ] && [ "$requested_method" != "$detected_method" ]; then
method="$requested_method"
action="install"
else
method="$detected_method"
action="update"
fi
else
action="install"
if [ -n "$requested_method" ]; then
method="$requested_method"
elif hash brew 2> /dev/null; then
method="brew"
elif hash npm 2> /dev/null; then
method="npm"
else
method="install.sh"
fi
fi
if [ "$installed" -eq 1 ] && [ "$action" = "update" ]; then
current_version="$(codex --version 2>/dev/null | sed -n 's/^codex-cli[[:space:]]\+//p' | head -n 1)"
if [ -n "$current_version" ]; then
if [ "$version" = "latest" ]; then
release_json="$(curl -fsSL https://api.github.com/repos/openai/codex/releases/latest 2>/dev/null || true)"
target_version="$(printf '%s\n' "$release_json" | sed -n 's/.*"tag_name":[[:space:]]*"rust-v\([^"]*\)".*/\1/p' | head -n 1)"
else
target_version="$version"
target_version="${target_version#rust-v}"
target_version="${target_version#v}"
fi
if [ -n "$target_version" ] && [ "$current_version" = "$target_version" ]; then
echo "Codex is already at $current_version; nothing to do."
return 0
fi
fi
fi
case "$method" in
brew)
if ! hash brew 2> /dev/null; then
echo "Homebrew is not available." >&2
return 1
fi
if [ "$action" = "install" ]; then
echo "Installing Codex via Homebrew cask"
if [ "$installed" -eq 1 ] && [ -n "$requested_method" ] && [ "$requested_method" != "$detected_method" ]; then
echo "Existing Codex install detected via $detected_method; switching to Homebrew will not remove the old install."
fi
[ "$dry_run" -eq 1 ] || brew install --cask codex
else
echo "Updating Codex via Homebrew"
[ "$dry_run" -eq 1 ] || brew upgrade --cask codex
fi
;;
npm)
if ! hash npm 2> /dev/null; then
echo "npm is not available." >&2
return 1
fi
if [ "$action" = "install" ]; then
echo "Installing Codex via npm"
if [ "$installed" -eq 1 ] && [ -n "$requested_method" ] && [ "$requested_method" != "$detected_method" ]; then
echo "Existing Codex install detected via $detected_method; switching to npm will not remove the old install."
fi
else
echo "Updating Codex via npm"
fi
[ "$dry_run" -eq 1 ] || npm install -g "@openai/codex@$version"
;;
install.sh)
if ! hash curl 2> /dev/null && ! hash wget 2> /dev/null; then
echo "curl or wget is required for install.sh." >&2
return 1
fi
if [ "$action" = "install" ]; then
echo "Installing Codex via install.sh"
if [ "$installed" -eq 1 ] && [ -n "$requested_method" ] && [ "$requested_method" != "$detected_method" ]; then
echo "Existing Codex install detected via $detected_method; switching to install.sh will not remove the old install."
fi
else
echo "Updating Codex via install.sh"
fi
[ "$dry_run" -eq 1 ] || curl -fsSL https://github.com/openai/codex/releases/latest/download/install.sh | sh -s -- "$version"
;;
esac
}
alias codex-update='codex_update'
alias codex-install='codex_update'
function mise_update {
local parsed_args mise_path install_path version dry_run current_version requested_version
parsed_args="$(getopt -o hn --long help,dry-run -- "$@")" || return 2
eval set -- "$parsed_args"
dry_run=0
while true; do
case "$1" in
-h|--help)
echo "Usage: ${FUNCNAME[0]} [--dry-run] [VERSION]"
echo "Update Mise if installed, or install it if missing."
echo
echo "Uses the standalone https://mise.run installer and never edits shell rc files."
echo "If VERSION is given, the standalone installer receives MISE_VERSION and updates use 'mise self-update VERSION'."
return 0
;;
-n|--dry-run)
dry_run=1
shift
;;
--)
shift
break
;;
*)
echo "Unexpected option parsing state: $1" >&2
return 2
;;
esac
done
version="${1:-latest}"
if [ $# -gt 1 ]; then
echo "Too many arguments." >&2
return 2
fi
mise_path="$(command -v mise 2>/dev/null || true)"
if [ -n "$mise_path" ]; then
current_version="$(mise --version 2>/dev/null | sed -n 's/^mise[[:space:]]\+//p' | head -n 1)"
if [ "$version" != "latest" ]; then
requested_version="${version#v}"
if [ -n "$current_version" ] && [ "$current_version" = "$requested_version" ]; then
echo "Mise is already at $current_version; nothing to do."
return 0
fi
fi
echo "Updating Mise via self-update"
if [ "$dry_run" -eq 1 ]; then
if [ "$version" = "latest" ]; then
echo "DRY RUN: mise self-update --yes"
else
echo "DRY RUN: mise self-update --yes ${version#v}"
fi
return 0
fi
if [ "$version" = "latest" ]; then
mise self-update --yes
else
mise self-update --yes "${version#v}"
fi
return $?
fi
if ! hash curl 2> /dev/null && ! hash wget 2> /dev/null; then
echo "curl or wget is required to install Mise." >&2
return 1
fi
install_path="${MISE_INSTALL_PATH:-$HOME/.local/bin/mise}"
echo "Installing Mise via https://mise.run"
echo "Install path: $install_path"
if [ "$dry_run" -eq 1 ]; then
if [ "$version" = "latest" ]; then
echo "DRY RUN: install latest Mise with MISE_INSTALL_PATH=$install_path"
else
echo "DRY RUN: install Mise $version with MISE_INSTALL_PATH=$install_path"
fi
return 0
fi
if hash curl 2> /dev/null; then
if [ "$version" = "latest" ]; then
curl https://mise.run | env MISE_INSTALL_PATH="$install_path" sh
else
curl https://mise.run | env MISE_INSTALL_PATH="$install_path" MISE_VERSION="v${version#v}" sh
fi
else
if [ "$version" = "latest" ]; then
wget -qO- https://mise.run | env MISE_INSTALL_PATH="$install_path" sh
else
wget -qO- https://mise.run | env MISE_INSTALL_PATH="$install_path" MISE_VERSION="v${version#v}" sh
fi
fi
}
alias mise-update='mise_update'
alias mise-install='mise_update'
#enable bash completion for this
complete -c wcat
function wcat {
if [ "$1" = "-h" ] || [ "$1" = "--help" ] || [ -z "$1" ]; then
echo "Usage: $FUNCNAME [-l|-v] COMMAND [VIMOPTS]"
echo "Print contents of file matching COMMAND"
echo
echo " -l Use less instead of cat"
echo ' -v Use vim instead of cat; append VIMOPTS to vim invocation'
echo " -h This help"
return 0
elif [ "$1" = "-l" ]; then
cmdname=less
shift
elif [ "$1" = "-v" ]; then
cmdname=vim
shift
else
cmdname=cat
fi
if [ "$(type -t "$1")" != "file" ]; then
type "$1"
return 1
elif ! which "$1" &> /dev/null; then
echo "'$1' not found, exiting"
return 1
else
command="$1"
shift
"$cmdname" "$(which "$command")" $@
fi
}
# need to write waitforfile at some point
function cheat {
if [ "$#" -eq 2 ] && [[ ! $2 = --* ]]; then
command cheat "$1" | egrep --color=auto "$2"
else
command cheat "$@"
fi
}
if hash busctl 2> /dev/null; then
function shutdown {
if [ "$1" = "--help" ]; then
/sbin/shutdown --help
echo " -w Display time of a pending shutdown (helpers addition)"
elif [ "$1" = "-w" ]; then
awk -f - <<'ENDAWK'
BEGIN {
"busctl get-property org.freedesktop.login1 /org/freedesktop/login1 org.freedesktop.login1.Manager ScheduledShutdown" | getline result
split(result,results)
results[3]/=1000000
if (results[3] != 0)
print "Shutdown scheduled for " strftime("%a %Y-%m-%d %T %Z",results[3],0) ", use 'shutdown -c' to cancel."
}
ENDAWK
else
/sbin/shutdown $@
fi
}
fi
if hash mkvinfo 2> /dev/null; then
function mkvinf () {
local args=( "$@" )
if [ "$1" = "-h" -o "$1" = "--help" ]; then
printf 'Usage: mkvinf MKVFILE... [ELEMENT]\n'
printf 'Print information about ELEMENT in MKVFILES, or all elements if ELEMENT is not provided.'
printf '\n\nCommon elements:\n\taudio\n\tresolution\n\tsubtitles\n\tvideo\n'
return 1
fi
if [ -n "$2" ] && [ ! -f "${args[-1]}" ]; then
local fieldname="${args[-1]}"
unset 'args[-1]'
fi
for i in "${args[@]}"; do
if [ -n "$fieldname" ] && [ "$fieldname" != "resolution" ]; then
mkvmerge --identify -F json "$1" | jq -C '.tracks | .[] | select(.type=="'"$fieldname"'")'
elif [ "$fieldname" = "resolution" ]; then
mkvmerge --identify -F json "$1" | jq -C '.tracks | .[] | select(.type=="video") | .properties | .display_dimensions'
else
mkvmerge --identify -F json "$1" | jq -C '.'
fi
done
}
fi