-
Notifications
You must be signed in to change notification settings - Fork 0
/
archive
executable file
·65 lines (54 loc) · 1.57 KB
/
archive
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
#!/bin/bash
# TODO: Support `exclude` option
CONFIG=meta/install.conf.yaml
set -o noglob
# Match all source and target paths of the link segment
links=( $(
sed -n '/^- link:$/,$ p' "$CONFIG" \
| grep -Po "(?<=path: ).*|(?<=^ ).*(?=:$)" \
| sed "s/~/${HOME//\//\\/}/g"
) )
set +o noglob
# Assemble files that would be potentially overwritten by the `link` step
typeset -a to_archive
for (( i = 0; i < ${#links[@]}; i+=2 )); do
# Source and target of link
src="${links[$((i+1))]}"
tar="${links[$i]}"
# TODO: This assumes that the globbing can only be specified at the end
if [[ ${src##*\*} ]]; then
# `glob` set to false; just add the target
to_archive+=("$tar")
else
# `glob` set to true; add globbed path portion in target
# TODO: this breaks on files with spaces, but quotes must not be used for
# the globbing to take effect
for path in $src; do
# Keep the dirname as base
base="${src%%/*}/"
# Only the matched portion
file="${path#$base}"
# Skip `.` and `..` when globbing hidden files through `/.*`
[[ $file != '.' && $file != '..' ]] || continue
# Avoid potential double slashes (e.g. `//`)
to_archive+=("${tar%/}${file:+/$file}")
done
fi
done
tmpd="$(mktemp -d)"
for file in "${to_archive[@]}"; do
[[ ! -e "$file" ]] || mv "$file" "$tmpd"
done
if rmdir "$tmpd" 2>/dev/null; then
>&2 echo "Nothing to archive"
else
name="existing-$(date +"%Y%m%d_%H%M%S").tar.gz"
if tar czvf "$name" "$tmpd"; then
rm -rf "$tmpd"
>&2 echo "$name created"
else
errc=$?
>&2 echo "Archive could not be created. See $tmpd."
exit $errc
fi
fi