This repository was archived by the owner on Apr 22, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathinstall.sh
More file actions
executable file
·723 lines (636 loc) · 17.7 KB
/
install.sh
File metadata and controls
executable file
·723 lines (636 loc) · 17.7 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
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
#!/usr/bin/env bash
### Install Bash Builder Usage:help
#
# ./install.sh [OPTIONS]
#
# Install the build utilities.
#
# OPTIONS
#
# --libs
# --libs=TARGET
# Also install the target version of the libraries.
# If target is not specified, install latest release version.
#
# --rc
# Install from the release candidates directory instead of release directory
#
###/doc
##bash-libs: safe.sh @ ab570026 (2.1.5)
### Safe mode Usage:bbuild
#
# Set global safe mode options
#
# * Script bails if a statement or command returns non-zero status
# * except when in a conditional statement
# * Accessing a variable that is not set is an error, causing non-zero status of the operation
# * Prevents globs
# * If a component of a pipe fails, the entire pipe statement returns non-zero
#
# Splitting over spaces
# ---------------------
#
# Using bash's defaults, array assignments split over any whitespace.
#
# Using safe mode, arrays only split over newlines, not over spaces.
#
# Return to default unsafe behaviour using `safe:space-split on`
#
# Reactivate safe recommendation using `safe:space-split off`
#
# Globs
# -------
#
# In safe mode, glob expansion like `ls .config/*` is turned off by default.
#
# You can turn glob expansion on with `safe:glob on`, and off with `safe:glob off`
#
###/doc
safe:space-split() {
case "$1" in
off)
export IFS=$'\t\n'
;;
on)
export IFS=$' \t\n'
;;
*)
out:fail "API error: bad use of safe:split - must be 'on' or 'off' not '$1'"
;;
esac
}
safe:glob() {
case "$1" in
off)
set -f
;;
on)
set +f
;;
*)
out:fail "API error: bad use of safe:glob - must be 'on' or 'off' not '$1'"
;;
esac
}
set -eufo pipefail
safe:space-split off
##bash-libs: tty.sh @ ab570026 (2.1.5)
tty:is_ssh() {
[[ -n "$SSH_TTY" ]] || [[ -n "$SSH_CLIENT" ]] || [[ "$SSH_CONNECTION" ]]
}
tty:is_pipe() {
[[ ! -t 1 ]]
}
##bash-libs: colours.sh @ ab570026 (2.1.5)
### Colours for terminal Usage:bbuild
# A series of shorthand colour flags for use in outputs, and functions to set your own flags.
#
# Not all terminals support all colours or modifiers.
#
# Example:
#
# echo "${CRED}Some red text ${CBBLU} some blue text. $CDEF Some text in the terminal's default colour")
#
# Preconfigured colours available:
#
# CRED, CBRED, HLRED -- red, bright red, highlight red
# CGRN, CBGRN, HLGRN -- green, bright green, highlight green
# CYEL, CBYEL, HLYEL -- yellow, bright yellow, highlight yellow
# CBLU, CBBLU, HLBLU -- blue, bright blue, highlight blue
# CPUR, CBPUR, HLPUR -- purple, bright purple, highlight purple
# CTEA, CBTEA, HLTEA -- teal, bright teal, highlight teal
# CBLA, CBBLA, HLBLA -- black, bright red, highlight red
# CWHI, CBWHI, HLWHI -- white, bright red, highlight red
#
# Modifiers available:
#
# CBON - activate bright
# CDON - activate dim
# ULON - activate underline
# RVON - activate reverse (switch foreground and background)
# SKON - activate strikethrough
#
# Resets available:
#
# CNORM -- turn off bright or dim, without affecting other modifiers
# ULOFF -- turn off highlighting
# RVOFF -- turn off inverse
# SKOFF -- turn off strikethrough
# HLOFF -- turn off highlight
#
# CDEF -- turn off all colours and modifiers(switches to the terminal default)
#
# Note that highlight and underline must be applied or re-applied after specifying a colour.
#
# If the session is detected as being in a pipe, colours will be turned off.
# You can override this by calling `colours:check --color=always` at the start of your script
#
###/doc
### colours:check ARGS ... Usage:bbuild
#
# Check the args to see if there's a `--color=always` or `--color=never`
# and reload the colours appropriately
#
# main() {
# colours:check "$@"
#
# echo "${CGRN}Green only in tty or if --colours=always !${CDEF}"
# }
#
# main "$@"
#
###/doc
colours:check() {
if [[ "$*" =~ --color=always ]]; then
COLOURS_ON=true
elif [[ "$*" =~ --color=never ]]; then
COLOURS_ON=false
fi
colours:define
return 0
}
### colours:set CODE Usage:bbuild
# Set an explicit colour code - e.g.
#
# echo "$(colours:set "33;2")Dim yellow text${CDEF}"
#
# See SGR Colours definitions
# <https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_(Select_Graphic_Rendition)_parameters>
###/doc
colours:set() {
# We use `echo -e` here rather than directly embedding a binary character
if [[ "$COLOURS_ON" = false ]]; then
return 0
else
echo -e "\033[${1}m"
fi
}
colours:define() {
# Shorthand colours
export CBLA="$(colours:set "30")"
export CRED="$(colours:set "31")"
export CGRN="$(colours:set "32")"
export CYEL="$(colours:set "33")"
export CBLU="$(colours:set "34")"
export CPUR="$(colours:set "35")"
export CTEA="$(colours:set "36")"
export CWHI="$(colours:set "37")"
export CBBLA="$(colours:set "1;30")"
export CBRED="$(colours:set "1;31")"
export CBGRN="$(colours:set "1;32")"
export CBYEL="$(colours:set "1;33")"
export CBBLU="$(colours:set "1;34")"
export CBPUR="$(colours:set "1;35")"
export CBTEA="$(colours:set "1;36")"
export CBWHI="$(colours:set "1;37")"
export HLBLA="$(colours:set "40")"
export HLRED="$(colours:set "41")"
export HLGRN="$(colours:set "42")"
export HLYEL="$(colours:set "43")"
export HLBLU="$(colours:set "44")"
export HLPUR="$(colours:set "45")"
export HLTEA="$(colours:set "46")"
export HLWHI="$(colours:set "47")"
# Modifiers
export CBON="$(colours:set "1")"
export CDON="$(colours:set "2")"
export ULON="$(colours:set "4")"
export RVON="$(colours:set "7")"
export SKON="$(colours:set "9")"
# Resets
export CBNRM="$(colours:set "22")"
export HLOFF="$(colours:set "49")"
export ULOFF="$(colours:set "24")"
export RVOFF="$(colours:set "27")"
export SKOFF="$(colours:set "29")"
export CDEF="$(colours:set "0")"
}
colours:auto() {
if tty:is_pipe ; then
COLOURS_ON=false
else
COLOURS_ON=true
fi
colours:define
return 0
}
colours:auto
##bash-libs: out.sh @ ab570026 (2.1.5)
### Console output handlers Usage:bbuild
#
# Write data to console stderr using colouring
#
###/doc
### out:info MESSAGE Usage:bbuild
# print a green informational message to stderr
###/doc
function out:info {
echo "$CGRN$*$CDEF" 1>&2
}
### out:warn MESSAGE Usage:bbuild
# print a yellow warning message to stderr
###/doc
function out:warn {
echo "${CBYEL}WARN: $CYEL$*$CDEF" 1>&2
}
### out:defer MESSAGE Usage:bbuild
# Store a message in the output buffer for later use
###/doc
function out:defer {
OUTPUT_BUFFER_defer[${#OUTPUT_BUFFER_defer[@]}]="$*"
}
# Internal
function out:buffer_initialize {
OUTPUT_BUFFER_defer=(:)
}
out:buffer_initialize
### out:flush HANDLER ... Usage:bbuild
#
# Pass the output buffer to the command defined by HANDLER
# and empty the buffer
#
# Examples:
#
# out:flush echo -e
#
# out:flush out:warn
#
# (escaped newlines are added in the buffer, so `-e` option is
# needed to process the escape sequences)
#
###/doc
function out:flush {
[[ -n "$*" ]] || out:fail "Did not provide a command for buffered output\n\n${OUTPUT_BUFFER_defer[*]}"
[[ "${#OUTPUT_BUFFER_defer[@]}" -gt 1 ]] || return 0
for buffer_line in "${OUTPUT_BUFFER_defer[@]:1}"; do
"$@" "$buffer_line"
done
out:buffer_initialize
}
### out:fail [CODE] MESSAGE Usage:bbuild
# print a red failure message to stderr and exit with CODE
# CODE must be a number
# if no code is specified, error code 127 is used
###/doc
function out:fail {
local ERCODE=127
local numpat='^[0-9]+$'
if [[ "$1" =~ $numpat ]]; then
ERCODE="$1"; shift || :
fi
echo "${CBRED}ERROR FAIL: $CRED$*$CDEF" 1>&2
exit $ERCODE
}
### out:error MESSAGE Usage:bbuild
# print a red error message to stderr
#
# unlike out:fail, does not cause script exit
###/doc
function out:error {
echo "${CBRED}ERROR: ${CRED}$*$CDEF" 1>&2
}
##bash-libs: syntax-extensions.sh @ ab570026 (2.1.5)
### Syntax Extensions Usage:syntax
#
# Syntax extensions for bash-builder.
#
# You will need to import this library if you use Bash Builder's extended syntax macros.
#
# You should not however use the functions directly, but the extended syntax instead.
#
##/doc
### syntax-extensions:use FUNCNAME ARGNAMES ... Usage:syntax
#
# Consume arguments into named global variables.
#
# If not enough argument values are found, the first named variable that failed to be assigned is printed as error
#
# ARGNAMES prefixed with '?' do not trigger an error
#
# Example:
#
# #%include out.sh
# #%include syntax-extensions.sh
#
# get_parameters() {
# . <(syntax-extensions:use get_parameters INFILE OUTFILE ?comment)
#
# [[ -f "$INFILE" ]] || out:fail "Input file '$INFILE' does not exist"
# [[ -f "$OUTFILE" ]] || out:fail "Output file '$OUTFILE' does not exist"
#
# [[ -z "$comment" ]] || echo "Note: $comment"
# }
#
# main() {
# get_parameters "$@"
#
# echo "$INFILE will be converted to $OUTFILE"
# }
#
# main "$@"
#
###/doc
syntax-extensions:use() {
local argname arglist undef_f dec_scope argidx argone failmsg pos_ok
dec_scope=""
[[ "${SYNTAXLIB_scope:-}" = local ]] || dec_scope=g
arglist=(:)
argone=\"\${1:-}\"
pos_ok=true
for argname in "$@"; do
[[ "$argname" != -- ]] || break
[[ "$argname" =~ ^(\?|\*)?[0-9a-zA-Z_]+$ ]] || out:fail "Internal: Not a valid argument name '$argname'"
arglist+=("$argname")
done
argidx=1
while [[ "$argidx" -lt "${#arglist[@]}" ]]; do
argname="${arglist[$argidx]}"
failmsg="\"Internal: could not get '$argname' in function arguments\""
posfailmsg="Internal: positional argument '$argname' encountered after optional argument(s)"
if [[ "$argname" =~ ^\? ]]; then
echo "$SYNTAXLIB_scope ${argname:1}=$argone; shift || :"
pos_ok=false
elif [[ "$argname" =~ ^\* ]]; then
[[ "$pos_ok" != false ]] || out:fail "$posfailmsg"
echo "[[ '${argname:1}' != \"$argone\" ]] || out:fail \"Internal: Local name [$argname] equals upstream [$argone]. Rename [$argname] (suggestion: [*p_${argname:1}])\""
echo "declare -n${dec_scope} ${argname:1}=$argone; shift || out:fail $failmsg"
else
[[ "$pos_ok" != false ]] || out:fail "$posfailmsg"
echo "$SYNTAXLIB_scope ${argname}=$argone; shift || out:fail $failmsg"
fi
argidx=$((argidx + 1))
done
}
### syntax-extensions:use:local FUNCNAME ARGNAMES ... Usage:syntax
#
# Enables syntax macro: function signatures
# e.g. $%function func(var1 var2) { ... }
#
# Build with bbuild to leverage this function's use:
#
# #%include out.sh
# #%include syntax-extensions.sh
#
# $%function person(name email) {
# echo "$name <$email>"
#
# # $1 and $2 have been consumed into $name and $email
# # The rest remains available in $* :
#
# echo "Additional notes: $*"
# }
#
# person "Jo Smith" "jsmith@example.com" Some details
#
###/doc
syntax-extensions:use:local() {
SYNTAXLIB_scope=local syntax-extensions:use "$@"
}
args:use:local() {
syntax-extensions:use:local "$@"
}
##bash-libs: autohelp.sh @ ab570026 (2.1.5)
### Autohelp Usage:bbuild
#
# Autohelp provides some simple facilities for defining help as comments in your code.
# It provides several functions for printing specially formatted comment sections.
#
# Write your help as documentation comments in your script
#
# To output a named section from your script, or a file, call the
# `autohelp:print` function and it will print the help documentation
# in the current script, or specified file, to stdout
#
# A help comment looks like this:
#
# ### <title> Usage:help
# #
# # <some content>
# #
# # end with "###/doc" on its own line (whitespaces before
# # and after are OK)
# #
# ###/doc
#
# It can then be printed from the same script by simply calling
#
# autohelp:print
#
# You can print a different section by specifying a different name
#
# autohelp:print section2
#
# > This would print a section defined in this way:
#
# ### Some title Usage:section2
# # <some content>
# ###/doc
#
# You can set a different comment character by setting the 'HELPCHAR' environment variable.
# Typically, you might want to print comments you set in a INI config file, for example
#
# HELPCHAR=";" autohelp:print help config-file.ini
#
# Which would then find comments defined like this in `config-file.ini`:
#
# ;;; Main config Usage:help
# ; Help comments in a config file
# ; may start with a different comment character
# ;;;/doc
#
#
#
# Example usage in a multi-function script:
#
# #!usr/bin/env bash
#
# ### Main help Usage:help
# # The main help
# ###/doc
#
# ### Feature One Usage:feature_1
# # Help text for the first feature
# ###/doc
#
# feature1() {
# autohelp:check:section feature_1 "$@"
# echo "Feature I"
# }
#
# ### Feature Two Usage:feature_2
# # Help text for the second feature
# ###/doc
#
# feature2() {
# autohelp:check:section feature_2 "$@"
# echo "Feature II"
# }
#
# main() {
# case "$1" in
# feature1|feature2)
# "$1" "$@" # Pass the global script arguments through
# ;;
# *)
# autohelp:check-no-null "$@" # Check if main help was asked for, if so, or if no args, exit with help
#
# # Main help not requested, return error
# echo "Unknown feature"
# exit 1
# ;;
# esac
# }
#
# main "$@"
#
###/doc
### autohelp:print [ SECTION [FILE] ] Usage:bbuild
# Print the specified section, in the specified file.
#
# If no file is specified, prints for current script file.
# If no section is specified, defaults to "help"
###/doc
HELPCHAR='#'
autohelp:print() {
local input_line
local section_string="${1:-}"; shift || :
local target_file="${1:-}"; shift || :
[[ -n "$section_string" ]] || section_string=help
[[ -n "$target_file" ]] || target_file="$0"
local sec_start='^\s*'"$HELPCHAR$HELPCHAR$HELPCHAR"'\s+(.+?)\s+Usage:'"$section_string"'\s*$'
local sec_end='^\s*'"$HELPCHAR$HELPCHAR$HELPCHAR"'\s*/doc\s*$'
local in_section=false
while read input_line; do
if [[ "$input_line" =~ $sec_start ]]; then
in_section=true
echo -e "\n${BASH_REMATCH[1]}\n======="
elif [[ "$in_section" = true ]]; then
if [[ "$input_line" =~ $sec_end ]]; then
in_section=false
else
echo "$input_line" | sed -r "s/^\s*$HELPCHAR/ /;s/^ (\S)/\1/"
fi
fi
done < "$target_file"
if [[ "$in_section" = true ]]; then
out:fail "Non-terminated help block."
fi
}
### autohelp:paged Usage:bbuild
#
# Display the help in the pager defined in the PAGER environment variable
#
###/doc
autohelp:paged() {
: ${PAGER=less}
autohelp:print "$@" | $PAGER
}
### autohelp:check-or-null ARGS ... Usage:bbuild
# Print help if arguments are empty, or if arguments contain a '--help' token
#
###/doc
autohelp:check-or-null() {
if [[ -z "$*" ]]; then
autohelp:print help "$0"
exit 0
else
autohelp:check:section "help" "$@"
fi
}
### autohelp:check-or-null:section SECTION ARGS ... Usage:bbuild
# Print help section SECTION if arguments are empty, or if arguments contain a '--help' token
#
###/doc
autohelp:check-or-null:section() {
. <(args:use:local section -- "$@") ;
if [[ -z "$*" ]]; then
autohelp:print "$section" "$0"
exit 0
else
autohelp:check:section "$section" "$@"
fi
}
### autohelp:check ARGS ... Usage:bbuild
#
# Automatically print "help" sections and exit, if "--help" is detected in arguments
#
###/doc
autohelp:check() {
autohelp:check:section "help" "$@"
}
### autohelp:check:section SECTION ARGS ... Usage:bbuild
# Automatically print documentation for named section and exit, if "--help" is detected in arguments
#
###/doc
autohelp:check:section() {
local section arg
section="${1:-}"; shift || out:fail "No help section specified"
for arg in "$@"; do
if [[ "$arg" =~ --help ]]; then
cols="$(tput cols)"
autohelp:print "$section" | fold -w "$cols" -s || autohelp:print "$section"
exit 0
fi
done
}
main() {
autohelp:check "$@"
bindir="$HOME/.local/bin"
libsdir="$HOME/.local/lib/bash-builder"
INSTALL_SOURCE=bin/
parse_args "$@"
if [[ "$UID" = 0 ]]; then
bindir="/usr/local/bin"
libsdir="/usr/local/lib/bash-builder"
fi
mkdir -p "$bindir"
mkdir -p "$libsdir"
cp "$INSTALL_SOURCE"/bbuild \
"$INSTALL_SOURCE"/bbrun \
"$INSTALL_SOURCE"/bashdoc \
"$INSTALL_SOURCE"/tarshc \
"$bindir/"
ensure_bbpath
out:info "Installed to '$bindir'."
install_libs
}
parse_args() {
local item
for item in "$@"; do
case "$item" in
--libs=*)
LIBS_TARGET="${item#*=}"
;;
--libs)
LIBS_TARGET=latest-release
;;
--rc)
INSTALL_SOURCE=bin-candidates/
;;
*)
out:fail "Unknown option '$item'"
;;
esac
done
}
install_libs() {
local reply
if [[ -z "${LIBS_TARGET:-}" ]]; then
out:warn "You may need to install additional bash-builder libraries separately."
return 0
fi
if [[ ! -e "bash-libs" ]]; then
git clone https://github.com/taikedz/bash-libs
fi
"bash-libs/install.sh" "${LIBS_TARGET:-}"
}
ensure_bbpath() {
bashrcpath="$HOME/.bashrc"
if [[ "$UID" = 0 ]]; then
bashrcpath="/etc/bash.bashrc"
fi
if ! grep '^export BBPATH=' -q "$bashrcpath" ; then
echo "export BBPATH=$libsdir" >> "$bashrcpath"
fi
}
main "$@"