-
Notifications
You must be signed in to change notification settings - Fork 0
/
pk
executable file
·163 lines (138 loc) · 2.97 KB
/
pk
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
#!/bin/sh
# Copyright 2015-2021 Yury Gribov
#
# Use of this source code is governed by MIT license that can be
# found in the LICENSE.txt file.
# Packs files to archive OUT. Format is determined from extension of OUT.
# For details run without arguments.
set -eu
error() {
echo >&2 "$(basename $0): error: $@"
exit 1
}
warn() {
echo >&2 "$(basename $0): warning: $@"
}
check_prog() {
for p; do
if ! which "$p" > /dev/null 2>&1; then
error "your system is missing program '$p'" \
"which is required to pack this type of file"
fi
done
}
isemptydir() {
#test $(ls -A "$1" | wc -l) = 0
test -d "$1" && test $(find "$1" -maxdepth 0 -empty)
}
strip_ext() {
# Handle things like glibc-2.20.tar.bz2
noext="${1%.*}"
noext="${noext%.tar}"
echo "$noext"
}
print_help_and_exit() {
cat <<EOF
Syntax: $me OUT [FILE]..
Puts FILEs to archive OUT; type of archive is based on extension OUT
(e.g. tar+bzip2 for .tar.bz2 or .tbz2). Default FILE is inferred from OUT
by removing extension.
Supported archives: .tar*, .zip, .7z, .rar.
Example:
$ pk my.tar.gz 1.txt 2.txt
$ upk my.tar.gz
$ ls my/
1.txt 2.txt
EOF
exit 1
}
me=$(basename $0)
curdir="$PWD"
case "${1:-h}" in
-h | --help)
print_help_and_exit
;;
esac
TMP=$me.$$.tmp
mkdir -p $TMP
trap "rm -rf $TMP" EXIT INT TERM
if ! isemptydir $TMP; then
error "cowardly refusing to clear original contents of $TMP"
fi
if test $# = 0; then
error 'no inputs'
elif test $# = 1; then
src=$(echo "$1" | sed 's/\.tar\.[^.]*$\|\.[^.]*$//')
set -- "$1" "$src"
fi
dst="$1"
shift
base_dst=$(basename "$dst")
root=$(strip_ext "$base_dst")
# Detect situations where it makes sense to unnest subfolder
# e.g. glibc-2.20/glibc-2.20
if test $# -eq 1 -a $(basename "$1") = $root; then
test -e $1 || error "File (or directory) $1 does not exist"
cp -r "$1" "$TMP"
else
mkdir -p "$TMP/$root"
for src; do
test -e $src || error "File (or directory) $src does not exist"
cp -r "$src" "$TMP/$root"
done
fi
cd $TMP
# Pack
case "$dst" in
# We ignore archives with non-trivial meta-info
# (.deb, .rpm, .jar, etc.).
*.a)
check_prog ar
ar rcs "$base_dst" "$root"
;;
*.ar)
check_prog ar
ar rc "$base_dst" "$root"
;;
*.rar)
check_prog rar
rar a "$base_dst" "$root"
;;
*.tar)
check_prog tar
tar cf "$base_dst" "$root"
;;
*.tar.gz | *.tgz)
check_prog tar gzip
tar czf "$base_dst" "$root"
;;
*.tar.bz2 | *.tbz2)
check_prog tar bzip2
tar cjf "$base_dst" "$root"
;;
*.tar.lz | *.tlz)
check_prog tar lzip
tar --lzip cf "$base_dst" "$root"
;;
*.tar.xz | *.txz)
check_prog tar xz
tar cJf "$base_dst" "$root"
;;
*.zip)
check_prog zip
zip -r "$base_dst" "$root"
;;
*.7z)
check_prog 7zr
7zr a "$base_dst" "$root"
;;
*.lz | *.lzip | *.lzma)
check_prog lzip
lzip -o "$base_dst" "$root"
;;
*)
error "unsupported file format: $dst"
;;
esac
cd "$curdir"
mv "$TMP/$base_dst" "$dst"