-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path.bashrc_devops
195 lines (152 loc) · 5.56 KB
/
.bashrc_devops
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
#----- header -----
[ "${0##*/}" != "${BASH_SOURCE##*/}" ] || { >&2 echo -e "ERROR\tfile must be sourced ($0)"; return 2; }
# prevent multiple-inclusion
__link=`readlink -f "$BASH_SOURCE"`
declare -n __tag=SOURCE_${__link//[^a-zA-Z0-9_]/}
[ ${__tag:-0} -eq 0 ] || return 0
__tag=1
#------------------
if is_exec git; then
#--- BEGIN git ---
#source ${BASH_SOURCE%_*}_3rdparty git-credential-manager
#alt: git config --global credential.helper=<full path>
alias gsb='\git status --short --branch'
alias git.render="\git diff | sed -E 's/^[+ ]([^+]|$)/\1/; /^\-([^\-]+|$)/ d'"
#undo unhelpful whitespace changes
# git diff --ignore-space-change --numstat | awk '$1 == 0 && $2 == 0 { print $NF }' | xargs git checkout HEAD --
function __GIT() {
${DEBUG:+runv GIT_TRACE=2} \git ${NOOP:+'--no-commit' '--no-ff'} "$@"
}
function __prompt.git() {
[ -n "$GIT_PROMPT" ] || return 0
local _branch _upstream _stat{us,} _delta
local -i _mod _del _add _unk _ign _tot
#TODO
# short-circuit on not a git repo
# set branch,upstream via git branch --show-current or git branch -vv --color | awk '{ print $2, $3, $4 }'
# then get rid of '--branch' below
eval $(
set -e -o pipefail
awk '
NR==1 {
sub(/\(no branch\)/, ""); gsub(/[\[\],]/, "")
i=2
printf "_branch='%s' _status='%s' _delta=%d ", $i, $(i+1), $(i+2)
next
}
$1 ~ /M/ { mod++ }
$1 ~ /D/ { del++ }
$1 ~ /A/ { add++ }
$1 ~ /\?/ { unk++ }
$1 ~ /!/ { ign++ }
END { printf "_mod=%d _del=%d _add=%d _unk=%d _ign=%d _tot=%d", mod, del, add, unk, ign, NR-1 }
' < <( git --no-pager status --untracked-files=all --ignore-submodules --porcelain --branch 2>/dev/null )
) && [ -n "$_branch" ] || return 0
_upstream=${_branch#*...*/}
_branch=${_branch%...*}
[ "$_upstream" != "$_branch" ] || unset _upstream
# TODO handle both ahead AND behind?
case "$_status" in
ahead) _status="[${FGRN}${_status}${RS} $_delta]"
;;
behind) _status="[${FRED}${_status}${RS} $_delta]"
;;
up-to-date|*)
# _status=`echo -e '\u2713'`
unset _status _delta
esac
for v in _mod _del _add _unk _ign _tot; do
[ ${!v} -ne 0 ] || unset $v
done
_stat=( ${_mod+M$_mod} ${_del+D$_del} ${_add+A$_add} ${_unk+U$_unk} ${_ign+I$_ign} )
echo -ne "\n${UL}Git:${RS} ${HC}$_branch${_upstream:+...$_upstream}${RS} ${_status:+$_status} ${_stat:+${FRED}${_stat[@]}${RS}}"
}
__prompts+=( __prompt.git )
function git.current() { __GIT branch | awk '$1 == "*" { print $2; exit; }'; }
function git.bulk_add() {
[ $# -gt 0 ] || set -- M A D R
while (( $# )); do
__GIT add `git status --short | awk -v code=$1 '$1 ~ code { print $2 }'`
shift
done
}
function git.mirror() {
local BRANCH interactive
local OPTIND opt
while getopts 'i' opt; do
case "$opt" in
i) interactive=1 ;;
:) log.error "missing argument (-$OPTARG)"; return 2 ;;
\?) log.error "invalid option (-$OPTARG)" ; return 2 ;;
esac
done
shift $((OPTIND - 1))
#TODO spit out 'git remotes' and prompt for src and dst with read()
local src=${1:?source} dest=${2:?dest}; shift 2
__GIT fetch --prune --prune-tags --force --multiple "$src" "$dest" || return
echo
# alt: uses local as intermediary and will DESTROY any updates present in $dst
# git clone --mirror $src_url
# (cd $src; git remote add $dst $dst_url; git push $dst --mirror; )
local -a flags=( ${VERBOSE:+ '--progresss'} )
[ -n "${VERBOSE+X}" ] || flags+=( '--quiet' )
echo '----------'
echo "process BRANCHES ..."
echo
for br in ${@:-`__GIT branch --list --remote "$src/${BRANCH:-*}"`}; do
if [ ${interactive:-0} -eq 1 ]; then
read -t 8 -n 1 -p "Copy '$br' (y/N): " || return
[ -z "${REPLY}" ] || echo
[ "${REPLY^^}" = 'Y' ] || continue
else
echo "<< $br >>"
fi
__GIT push "${flags[@]}" "$dest" "${br}:refs/heads/${br#*/}"
echo
done
echo '----------'
echo "process TAGS ..."
echo
__GIT fetch "${flags[@]}" "$src" --tags
__GIT push "$dest" --tags
}
#--- END git ---
fi
# patterns to strip whitespace from code
#sed -i 's/[ \t]\+$//' dangling EOL
#sed -i 's| {8}|\t|g' spaces to tab
#sed -i 's| \{1,7\}\t|\t|g' remove prepended spaces before tabs
is_exec -q python && {
#TODO convert to function that can process args and fallback to STDIN
alias yaml2json="python -c 'import sys, yaml, json; json.dump(yaml.safe_load(sys.stdin), sys.stdout, indent=4)'"
alias json2yaml="python -c 'import sys, yaml, json; yaml.dump(json.load(sys.stdin), sys.stdout, indent=2)'"
}
#ref: https://github.com/mikefarah/yq
is_exec -q yq && {
alias yaml2json='yq eval -j'
alias json2yaml='yq eval -P'
}
is_exec -q docker && {
alias docker.stats='docker ps -q | xargs docker stats --no-stream'
}
# assumes delimited input with HEADER line and multi-row DATA
# ref: https://stackoverflow.com/questions/38860529/create-json-using-jq-from-pipe-separated-keys-and-values-in-bash
function csv2json() {
local DELIM
local output=$(
__JQR --null-input --arg delim "${DELIM:-,}" '
( input | split($delim) ) as $keys |
( inputs | split($delim) ) as $vals |
[ [$keys, $vals] | transpose[] | {(.[0]): .[1]} ] | add // empty
'
) || return
# alt:
# [ [$keys, $vals] | transpose[] | {key: .[0], value: .[1]} ] | from_entries'
__JQ --slurp 'map(.)' <<< "$output"
}
alias tsv2json="DELIM=$'\t' csv2json"
for f in "${BASH_SOURCE/bashrc/functions}"; do
[ -f "$f" ] || continue
source "$f" || { log.error "RC=$? during $f"; return; }
done
# vim: expandtab:ts=4:sw=4