Repository navigation
Expand file tree
/
Copy pathgist_pull
More file actions
executable file
·121 lines (106 loc) · 3.29 KB
/
Copy pathgist_pull
File metadata and controls
executable file
·121 lines (106 loc) · 3.29 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
#!/bin/bash
# Pull all the gists for a given user
user="${1:?No github user defined}"
base_uri="https://api.github.com/users/${user}/gists"
gist_path="${2:-${HOME}/git/gists}"
gist_manifest="${gist_path}/manifest.json"
# Get the top level PID and setup a trap so that we can call die() within subshells
trap "exit 1" TERM
_self_pid="${$}"
export _self_pid
# shellcheck disable=SC2059
die() {
[ -t 0 ] && _diefmt='\e[31;1m====>%s\e[0m\n'
printf "${_diefmt:-====>%s\n}" "${0}:(${LINENO}): ${*}" >&2
# Send a TERM signal to the top level PID, this is trapped and exit 1 is forced
kill -s TERM "${_self_pid}"
}
requires() {
local cmd err_count
err_count=0
for cmd in "${@}"; do
if ! command -v "${cmd}" >/dev/null 2>&1; then
err "${cmd} is required but was not found in PATH"
(( ++err_count ))
fi
done
(( err_count > 0 )) && exit 1
return 0
}
# A function to prompt/read an interactive y/n response
# Stops reading after one character, meaning only 'y' or 'Y' will return 0
# Any other character, or an optional timeout (-t|--timeout) will return 1
# Provenance: https://gist.github.com/rawiriblundell/7e8a26d8076ce09b6daa315389f822cd
confirm() {
local confirm_args
case "${1}" in
(-t|--timeout)
confirm_args=( -t "${2}" )
set -- "${@:3}"
;;
esac
read "${confirm_args[@]}" -rn 1 -p "${*:-Continue} [y/N]? "
printf -- '%s\n' ""
case "${REPLY}" in
([yY]) return 0 ;;
(*) return 1 ;;
esac
}
get_url() {
case "${1}" in
(--save) CURL_OPTS=( -O ); shift 1 ;;
esac
curl "${CURL_OPTS[@]}" -s "${1:?No URL defined}"
}
generate_insitu_ids() {
readarray -t insitu_ids < <(
find . -maxdepth 1 -type d -name "[a-z0-9]*" -printf '%P\n'
)
}
generate_diff_ids() {
readarray -t diff_ids < <(
printf -- '%s\n' "${gist_id_list[@]}" "${insitu_ids[@]}" | sort | uniq -u
)
}
main() {
requires curl jq mkdir cd
# Ensure our gist_path exists
mkdir -p "${gist_path}" || die "Could not create ${gist_path}"
# Make our API call and save its output
get_url "${base_uri}" > "${gist_manifest}"
# Parse the saved output, plucking out all our gist id's
readarray -t gist_id_list < <(jq -r '.[].id' "${gist_manifest}")
(
cd "${gist_path}" || die "Could not enter ${gist_path}..."
generate_insitu_ids
generate_diff_ids
for gist_id in "${gist_id_list[@]}"; do
printf -- '%s\n' "Syncing ${gist_id}..."
gist_uri="https://gist.github.com/${gist_id}.git"
[[ ! -d "${gist_id}" ]] && git clone "${gist_uri}"
(
cd "${gist_id}" || die "Could not enter ${gist_path}/${gist_id}"
# Get the matching filename from the gist_manifest file
gist_filename=$(
jq -r --arg gist_id "${gist_id}" '
.[] |
select(.id==$gist_id) |
.files[].filename' "${gist_manifest}"
)
ln_target="${gist_path}/${gist_id}/${gist_filename}"
ln_link="${gist_path}/${gist_filename}"
ln -s "${ln_target}" "${ln_link}" >/dev/null 2>&1
)
done
if (( "${#diff_ids[@]}" >= 1 )); then
for old_id in "${diff_ids[@]}"; do
printf -- '%s\n' "Contents of ${old_id}"
ls "${old_id}/"
if confirm "${old_id} appears to be abandoned. Delete?"; then
rm -rf "${old_id}"
fi
done
fi
)
}
main "${@}"