1 |
for various reasons/limitations/bugs/whatever, i rewrote epatch. seems to |
2 |
work for me, but in case someone wants to check before i release: |
3 |
epatch() { |
4 |
_epatch_draw_line() { |
5 |
# create a line of same length as input string |
6 |
[[ -z $1 ]] && set "$(printf "%65s" '')" |
7 |
echo "${1//?/=}" |
8 |
} |
9 |
|
10 |
unset P4CONFIG P4PORT P4USER # keep perforce at bay #56402 |
11 |
|
12 |
# Let the rest of the code process one user arg at a time -- |
13 |
# each arg may expand into multiple patches, and each arg may |
14 |
# need to start off with the default global EPATCH_xxx values |
15 |
if [[ $# -gt 1 ]] ; then |
16 |
local m |
17 |
for m in "$@" ; do |
18 |
epatch "${m}" |
19 |
done |
20 |
return 0 |
21 |
fi |
22 |
|
23 |
local SINGLE_PATCH="no" |
24 |
# no args means process ${EPATCH_SOURCE} |
25 |
[[ $# -eq 0 ]] && set -- "${EPATCH_SOURCE}" |
26 |
|
27 |
if [[ -f $1 ]] ; then |
28 |
SINGLE_PATCH="yes" |
29 |
set -- "$1" |
30 |
# Use the suffix from the single patch (localize it); the code |
31 |
# below will find the suffix for us |
32 |
local EPATCH_SUFFIX=$1 |
33 |
|
34 |
elif [[ -d $1 ]] ; then |
35 |
# Some people like to make dirs of patches w/out suffixes (vim) |
36 |
set -- "$1"/*${EPATCH_SUFFIX:+."${EPATCH_SUFFIX}"} |
37 |
|
38 |
else |
39 |
# sanity check ... if it isn't a dir or file, wtf man ? |
40 |
[[ $# -ne 0 ]] && EPATCH_SOURCE=$1 |
41 |
echo |
42 |
eerror "Cannot find \$EPATCH_SOURCE! Value for \$EPATCH_SOURCE is:" |
43 |
eerror |
44 |
eerror " ${EPATCH_SOURCE}" |
45 |
eerror " ( ${EPATCH_SOURCE##*/} )" |
46 |
echo |
47 |
die "Cannot find \$EPATCH_SOURCE!" |
48 |
fi |
49 |
|
50 |
local PIPE_CMD |
51 |
case ${EPATCH_SUFFIX##*\.} in |
52 |
xz) PIPE_CMD="xz -dc" ;; |
53 |
lzma) PIPE_CMD="lzma -dc" ;; |
54 |
bz2) PIPE_CMD="bzip2 -dc" ;; |
55 |
gz|Z|z) PIPE_CMD="gzip -dc" ;; |
56 |
ZIP|zip) PIPE_CMD="unzip -p" ;; |
57 |
*) ;; |
58 |
esac |
59 |
|
60 |
[[ ${SINGLE_PATCH} == "no" ]] && einfo "${EPATCH_MULTI_MSG}" |
61 |
|
62 |
local x |
63 |
for x in "$@" ; do |
64 |
# If the patch dir given contains subdirs, or our EPATCH_SUFFIX |
65 |
# didn't match anything, ignore continue on |
66 |
[[ ! -f ${x} ]] && continue |
67 |
|
68 |
local patchname=${x##*/} |
69 |
|
70 |
# Apply single patches, or forced sets of patches, or |
71 |
# patches with ARCH dependant names. |
72 |
# ???_arch_foo.patch |
73 |
# Else, skip this input altogether |
74 |
local a=${patchname#*_} # strip the ???_ |
75 |
a=${a%%_*} # strip the _foo.patch |
76 |
if ! [[ ${SINGLE_PATCH} == "yes" || \ |
77 |
${EPATCH_FORCE} == "yes" || \ |
78 |
${a} == all || \ |
79 |
${a} == ${ARCH} ]] |
80 |
then |
81 |
continue |
82 |
fi |
83 |
|
84 |
# Let people filter things dynamically |
85 |
if [[ -n ${EPATCH_EXCLUDE} ]] ; then |
86 |
# let people use globs in the exclude |
87 |
eshopts_push -o noglob |
88 |
|
89 |
local ex |
90 |
for ex in ${EPATCH_EXCLUDE} ; do |
91 |
if [[ ${patchname} == ${ex} ]] ; then |
92 |
eshopts_pop |
93 |
continue |
94 |
fi |
95 |
done |
96 |
eshopts_pop |
97 |
fi |
98 |
|
99 |
if [[ ${SINGLE_PATCH} == "yes" ]] ; then |
100 |
if [[ -n ${EPATCH_SINGLE_MSG} ]] ; then |
101 |
einfo "${EPATCH_SINGLE_MSG}" |
102 |
else |
103 |
einfo "Applying ${patchname} ..." |
104 |
fi |
105 |
else |
106 |
einfo " ${patchname} ..." |
107 |
fi |
108 |
|
109 |
# most of the time, there will only be one run per unique name, |
110 |
# but if there are more, make sure we get unique log filenames |
111 |
local STDERR_TARGET="${T}/${patchname}.out" |
112 |
if [[ -e ${STDERR_TARGET} ]] ; then |
113 |
STDERR_TARGET="${T}/${patchname}-$$.out" |
114 |
fi |
115 |
|
116 |
printf "***** %s *****\n\n" "${patchname}" > "${STDERR_TARGET}" |
117 |
|
118 |
# Decompress the patch if need be |
119 |
local count=0 |
120 |
local PATCH_TARGET |
121 |
if [[ -n ${PIPE_CMD} ]] ; then |
122 |
PATCH_TARGET="${T}/$$.patch" |
123 |
echo "PIPE_COMMAND: ${PIPE_CMD} ${x} > ${PATCH_TARGET}" >> "${STDERR_TARGET}" |
124 |
|
125 |
if ! (${PIPE_CMD} "${x}" > "${PATCH_TARGET}") >> "${STDERR_TARGET}" 2>&1 ; then |
126 |
echo |
127 |
eerror "Could not extract patch!" |
128 |
#die "Could not extract patch!" |
129 |
count=5 |
130 |
break |
131 |
fi |
132 |
else |
133 |
PATCH_TARGET=${x} |
134 |
fi |
135 |
|
136 |
# Check for absolute paths in patches. If sandbox is disabled, |
137 |
# people could (accidently) patch files in the root filesystem. |
138 |
# Or trigger other unpleasantries #237667. So disallow -p0 on |
139 |
# such patches. |
140 |
local abs_paths=$(egrep -n '^[-+]{3} /' "${PATCH_TARGET}" | awk '$2 != "/dev/null" { print }') |
141 |
if [[ -n ${abs_paths} ]] ; then |
142 |
count=1 |
143 |
printf "NOTE: skipping -p0 due to absolute paths in patch:\n%s\n" "${abs_paths}" >> "${STDERR_TARGET}" |
144 |
fi |
145 |
|
146 |
# Dynamically detect the correct -p# ... i'm lazy, so shoot me :/ |
147 |
while [[ ${count} -lt 5 ]] ; do |
148 |
# Generate some useful debug info ... |
149 |
( |
150 |
_epatch_draw_line "***** ${patchname} *****" |
151 |
echo |
152 |
echo "PATCH COMMAND: patch -p${count} ${EPATCH_OPTS} < '${PATCH_TARGET}'" |
153 |
echo |
154 |
_epatch_draw_line "***** ${patchname} *****" |
155 |
) >> "${STDERR_TARGET}" |
156 |
|
157 |
if (patch -p${count} ${EPATCH_OPTS} --dry-run -f < "${PATCH_TARGET}") >> "${STDERR_TARGET}" 2>&1 ; |
158 |
then |
159 |
( |
160 |
_epatch_draw_line "***** ${patchname} *****" |
161 |
echo |
162 |
echo "ACTUALLY APPLYING ${patchname} ..." |
163 |
echo |
164 |
_epatch_draw_line "***** ${patchname} *****" |
165 |
patch -p${count} ${EPATCH_OPTS} < "${PATCH_TARGET}" 2>&1 |
166 |
) >> "${STDERR_TARGET}" |
167 |
|
168 |
if [ $? -ne 0 ] ; then |
169 |
echo |
170 |
eerror "A dry-run of patch command succeeded, but actually" |
171 |
eerror "applying the patch failed!" |
172 |
#die "Real world sux compared to the dreamworld!" |
173 |
count=5 |
174 |
fi |
175 |
break |
176 |
fi |
177 |
|
178 |
: $(( count++ )) |
179 |
done |
180 |
|
181 |
# if we had to decompress the patch, delete the temp one |
182 |
if [[ -n ${PIPE_CMD} ]] ; then |
183 |
rm -f "${PATCH_TARGET}" |
184 |
fi |
185 |
|
186 |
if [[ ${count} -ge 5 ]] ; then |
187 |
echo |
188 |
eerror "Failed Patch: ${patchname} !" |
189 |
eerror " ( ${PATCH_TARGET} )" |
190 |
eerror |
191 |
eerror "Include in your bugreport the contents of:" |
192 |
eerror |
193 |
eerror " ${STDERR_TARGET}" |
194 |
echo |
195 |
die "Failed Patch: ${patchname}!" |
196 |
fi |
197 |
|
198 |
# if everything worked, delete the patch log |
199 |
rm -f "${STDERR_TARGET}" |
200 |
eend 0 |
201 |
done |
202 |
|
203 |
[[ ${SINGLE_PATCH} == "no" ]] && einfo "Done with patching" |
204 |
: # everything worked |
205 |
} |
206 |
-mike |