epatch.eclass 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  1. # Copyright 1999-2017 Gentoo Foundation
  2. # Distributed under the terms of the GNU General Public License v2
  3. # @ECLASS: epatch.eclass
  4. # @MAINTAINER:
  5. # base-system@gentoo.org
  6. # @BLURB: easy patch application functions
  7. # @DESCRIPTION:
  8. # An eclass providing epatch and epatch_user functions to easily apply
  9. # patches to ebuilds. Mostly superseded by eapply* in EAPI 6.
  10. if [[ -z ${_EPATCH_ECLASS} ]]; then
  11. inherit estack
  12. # @VARIABLE: EPATCH_SOURCE
  13. # @DESCRIPTION:
  14. # Default directory to search for patches.
  15. EPATCH_SOURCE="${WORKDIR}/patch"
  16. # @VARIABLE: EPATCH_SUFFIX
  17. # @DESCRIPTION:
  18. # Default extension for patches (do not prefix the period yourself).
  19. EPATCH_SUFFIX="patch.bz2"
  20. # @VARIABLE: EPATCH_OPTS
  21. # @DESCRIPTION:
  22. # Options to pass to patch. Meant for ebuild/package-specific tweaking
  23. # such as forcing the patch level (-p#) or fuzz (-F#) factor. Note that
  24. # for single patch tweaking, you can also pass flags directly to epatch.
  25. EPATCH_OPTS=""
  26. # @VARIABLE: EPATCH_COMMON_OPTS
  27. # @DESCRIPTION:
  28. # Common options to pass to `patch`. You probably should never need to
  29. # change these. If you do, please discuss it with base-system first to
  30. # be sure.
  31. # @CODE
  32. # -g0 - keep RCS, ClearCase, Perforce and SCCS happy #24571
  33. # --no-backup-if-mismatch - do not leave .orig files behind
  34. # -E - automatically remove empty files
  35. # @CODE
  36. EPATCH_COMMON_OPTS="-g0 -E --no-backup-if-mismatch"
  37. # @VARIABLE: EPATCH_EXCLUDE
  38. # @DESCRIPTION:
  39. # List of patches not to apply. Note this is only file names,
  40. # and not the full path. Globs accepted.
  41. EPATCH_EXCLUDE=""
  42. # @VARIABLE: EPATCH_SINGLE_MSG
  43. # @DESCRIPTION:
  44. # Change the printed message for a single patch.
  45. EPATCH_SINGLE_MSG=""
  46. # @VARIABLE: EPATCH_MULTI_MSG
  47. # @DESCRIPTION:
  48. # Change the printed message for multiple patches.
  49. EPATCH_MULTI_MSG="Applying various patches (bugfixes/updates) ..."
  50. # @VARIABLE: EPATCH_FORCE
  51. # @DESCRIPTION:
  52. # Only require patches to match EPATCH_SUFFIX rather than the extended
  53. # arch naming style.
  54. EPATCH_FORCE="no"
  55. # @VARIABLE: EPATCH_USER_EXCLUDE
  56. # @DEFAULT_UNSET
  57. # @DESCRIPTION:
  58. # List of patches not to apply. Note this is only file names,
  59. # and not the full path. Globs accepted.
  60. # @FUNCTION: epatch
  61. # @USAGE: [options] [patches] [dirs of patches]
  62. # @DESCRIPTION:
  63. # epatch is designed to greatly simplify the application of patches. It can
  64. # process patch files directly, or directories of patches. The patches may be
  65. # compressed (bzip/gzip/etc...) or plain text. You generally need not specify
  66. # the -p option as epatch will automatically attempt -p0 to -p4 until things
  67. # apply successfully.
  68. #
  69. # If you do not specify any patches/dirs, then epatch will default to the
  70. # directory specified by EPATCH_SOURCE.
  71. #
  72. # Any options specified that start with a dash will be passed down to patch
  73. # for this specific invocation. As soon as an arg w/out a dash is found, then
  74. # arg processing stops.
  75. #
  76. # When processing directories, epatch will apply all patches that match:
  77. # @CODE
  78. # if ${EPATCH_FORCE} != "yes"
  79. # ??_${ARCH}_foo.${EPATCH_SUFFIX}
  80. # else
  81. # *.${EPATCH_SUFFIX}
  82. # @CODE
  83. # The leading ?? are typically numbers used to force consistent patch ordering.
  84. # The arch field is used to apply patches only for the host architecture with
  85. # the special value of "all" means apply for everyone. Note that using values
  86. # other than "all" is highly discouraged -- you should apply patches all the
  87. # time and let architecture details be detected at configure/compile time.
  88. #
  89. # If EPATCH_SUFFIX is empty, then no period before it is implied when searching
  90. # for patches to apply.
  91. #
  92. # Refer to the other EPATCH_xxx variables for more customization of behavior.
  93. epatch() {
  94. _epatch_draw_line() {
  95. # create a line of same length as input string
  96. [[ -z $1 ]] && set "$(printf "%65s" '')"
  97. echo "${1//?/=}"
  98. }
  99. unset P4CONFIG P4PORT P4USER # keep perforce at bay #56402
  100. # First process options. We localize the EPATCH_OPTS setting
  101. # from above so that we can pass it on in the loop below with
  102. # any additional values the user has specified.
  103. local EPATCH_OPTS=( ${EPATCH_OPTS[*]} )
  104. while [[ $# -gt 0 ]] ; do
  105. case $1 in
  106. -*) EPATCH_OPTS+=( "$1" ) ;;
  107. *) break ;;
  108. esac
  109. shift
  110. done
  111. # Let the rest of the code process one user arg at a time --
  112. # each arg may expand into multiple patches, and each arg may
  113. # need to start off with the default global EPATCH_xxx values
  114. if [[ $# -gt 1 ]] ; then
  115. local m
  116. for m in "$@" ; do
  117. epatch "${m}"
  118. done
  119. return 0
  120. fi
  121. local SINGLE_PATCH="no"
  122. # no args means process ${EPATCH_SOURCE}
  123. [[ $# -eq 0 ]] && set -- "${EPATCH_SOURCE}"
  124. if [[ -f $1 ]] ; then
  125. SINGLE_PATCH="yes"
  126. set -- "$1"
  127. # Use the suffix from the single patch (localize it); the code
  128. # below will find the suffix for us
  129. local EPATCH_SUFFIX=$1
  130. elif [[ -d $1 ]] ; then
  131. # We have to force sorting to C so that the wildcard expansion is consistent #471666.
  132. evar_push_set LC_COLLATE C
  133. # Some people like to make dirs of patches w/out suffixes (vim).
  134. set -- "$1"/*${EPATCH_SUFFIX:+."${EPATCH_SUFFIX}"}
  135. evar_pop
  136. elif [[ -f ${EPATCH_SOURCE}/$1 ]] ; then
  137. # Re-use EPATCH_SOURCE as a search dir
  138. epatch "${EPATCH_SOURCE}/$1"
  139. return $?
  140. else
  141. # sanity check ... if it isn't a dir or file, wtf man ?
  142. [[ $# -ne 0 ]] && EPATCH_SOURCE=$1
  143. echo
  144. eerror "Cannot find \$EPATCH_SOURCE! Value for \$EPATCH_SOURCE is:"
  145. eerror
  146. eerror " ${EPATCH_SOURCE}"
  147. eerror " ( ${EPATCH_SOURCE##*/} )"
  148. echo
  149. die "Cannot find \$EPATCH_SOURCE!"
  150. fi
  151. # Now that we know we're actually going to apply something, merge
  152. # all of the patch options back in to a single variable for below.
  153. EPATCH_OPTS="${EPATCH_COMMON_OPTS} ${EPATCH_OPTS[*]}"
  154. local PIPE_CMD
  155. case ${EPATCH_SUFFIX##*\.} in
  156. xz) PIPE_CMD="xz -dc" ;;
  157. lzma) PIPE_CMD="lzma -dc" ;;
  158. bz2) PIPE_CMD="bzip2 -dc" ;;
  159. gz|Z|z) PIPE_CMD="gzip -dc" ;;
  160. ZIP|zip) PIPE_CMD="unzip -p" ;;
  161. *) ;;
  162. esac
  163. [[ ${SINGLE_PATCH} == "no" ]] && einfo "${EPATCH_MULTI_MSG}"
  164. local x
  165. for x in "$@" ; do
  166. # If the patch dir given contains subdirs, or our EPATCH_SUFFIX
  167. # didn't match anything, ignore continue on
  168. [[ ! -f ${x} ]] && continue
  169. local patchname=${x##*/}
  170. # Apply single patches, or forced sets of patches, or
  171. # patches with ARCH dependant names.
  172. # ???_arch_foo.patch
  173. # Else, skip this input altogether
  174. local a=${patchname#*_} # strip the ???_
  175. a=${a%%_*} # strip the _foo.patch
  176. if ! [[ ${SINGLE_PATCH} == "yes" || \
  177. ${EPATCH_FORCE} == "yes" || \
  178. ${a} == all || \
  179. ${a} == ${ARCH} ]]
  180. then
  181. continue
  182. fi
  183. # Let people filter things dynamically
  184. if [[ -n ${EPATCH_EXCLUDE}${EPATCH_USER_EXCLUDE} ]] ; then
  185. # let people use globs in the exclude
  186. eshopts_push -o noglob
  187. local ex
  188. for ex in ${EPATCH_EXCLUDE} ; do
  189. if [[ ${patchname} == ${ex} ]] ; then
  190. einfo " Skipping ${patchname} due to EPATCH_EXCLUDE ..."
  191. eshopts_pop
  192. continue 2
  193. fi
  194. done
  195. for ex in ${EPATCH_USER_EXCLUDE} ; do
  196. if [[ ${patchname} == ${ex} ]] ; then
  197. einfo " Skipping ${patchname} due to EPATCH_USER_EXCLUDE ..."
  198. eshopts_pop
  199. continue 2
  200. fi
  201. done
  202. eshopts_pop
  203. fi
  204. if [[ ${SINGLE_PATCH} == "yes" ]] ; then
  205. if [[ -n ${EPATCH_SINGLE_MSG} ]] ; then
  206. einfo "${EPATCH_SINGLE_MSG}"
  207. else
  208. einfo "Applying ${patchname} ..."
  209. fi
  210. else
  211. einfo " ${patchname} ..."
  212. fi
  213. # Handle aliased patch command #404447 #461568
  214. local patch="patch"
  215. eval $(alias patch 2>/dev/null | sed 's:^alias ::')
  216. # most of the time, there will only be one run per unique name,
  217. # but if there are more, make sure we get unique log filenames
  218. local STDERR_TARGET="${T}/${patchname}.out"
  219. if [[ -e ${STDERR_TARGET} ]] ; then
  220. STDERR_TARGET="${T}/${patchname}-$$.out"
  221. fi
  222. printf "***** %s *****\nPWD: %s\nPATCH TOOL: %s -> %s\nVERSION INFO:\n%s\n\n" \
  223. "${patchname}" \
  224. "${PWD}" \
  225. "${patch}" \
  226. "$(type -P "${patch}")" \
  227. "$(${patch} --version)" \
  228. > "${STDERR_TARGET}"
  229. # Decompress the patch if need be
  230. local count=0
  231. local PATCH_TARGET
  232. if [[ -n ${PIPE_CMD} ]] ; then
  233. PATCH_TARGET="${T}/$$.patch"
  234. echo "PIPE_COMMAND: ${PIPE_CMD} ${x} > ${PATCH_TARGET}" >> "${STDERR_TARGET}"
  235. if ! (${PIPE_CMD} "${x}" > "${PATCH_TARGET}") >> "${STDERR_TARGET}" 2>&1 ; then
  236. echo
  237. eerror "Could not extract patch!"
  238. #die "Could not extract patch!"
  239. count=5
  240. break
  241. fi
  242. else
  243. PATCH_TARGET=${x}
  244. fi
  245. # Check for absolute paths in patches. If sandbox is disabled,
  246. # people could (accidently) patch files in the root filesystem.
  247. # Or trigger other unpleasantries #237667. So disallow -p0 on
  248. # such patches.
  249. local abs_paths=$(egrep -n '^[-+]{3} /' "${PATCH_TARGET}" | awk '$2 != "/dev/null" { print }')
  250. if [[ -n ${abs_paths} ]] ; then
  251. count=1
  252. printf "NOTE: skipping -p0 due to absolute paths in patch:\n%s\n" "${abs_paths}" >> "${STDERR_TARGET}"
  253. fi
  254. # Similar reason, but with relative paths.
  255. local rel_paths=$(egrep -n '^[-+]{3} [^ ]*[.][.]/' "${PATCH_TARGET}")
  256. if [[ -n ${rel_paths} ]] ; then
  257. echo
  258. eerror "Rejected Patch: ${patchname} !"
  259. eerror " ( ${PATCH_TARGET} )"
  260. eerror
  261. eerror "Your patch uses relative paths '../':"
  262. eerror "${rel_paths}"
  263. echo
  264. die "you need to fix the relative paths in patch"
  265. fi
  266. # Dynamically detect the correct -p# ... i'm lazy, so shoot me :/
  267. local patch_cmd
  268. while [[ ${count} -lt 5 ]] ; do
  269. patch_cmd="${patch} -p${count} ${EPATCH_OPTS}"
  270. # Generate some useful debug info ...
  271. (
  272. _epatch_draw_line "***** ${patchname} *****"
  273. echo
  274. echo "PATCH COMMAND: ${patch_cmd} --dry-run -f < '${PATCH_TARGET}'"
  275. echo
  276. _epatch_draw_line "***** ${patchname} *****"
  277. ${patch_cmd} --dry-run -f < "${PATCH_TARGET}" 2>&1
  278. ret=$?
  279. echo
  280. echo "patch program exited with status ${ret}"
  281. exit ${ret}
  282. ) >> "${STDERR_TARGET}"
  283. if [ $? -eq 0 ] ; then
  284. (
  285. _epatch_draw_line "***** ${patchname} *****"
  286. echo
  287. echo "ACTUALLY APPLYING ${patchname} ..."
  288. echo "PATCH COMMAND: ${patch_cmd} < '${PATCH_TARGET}'"
  289. echo
  290. _epatch_draw_line "***** ${patchname} *****"
  291. ${patch_cmd} < "${PATCH_TARGET}" 2>&1
  292. ret=$?
  293. echo
  294. echo "patch program exited with status ${ret}"
  295. exit ${ret}
  296. ) >> "${STDERR_TARGET}"
  297. if [ $? -ne 0 ] ; then
  298. echo
  299. eerror "A dry-run of patch command succeeded, but actually"
  300. eerror "applying the patch failed!"
  301. #die "Real world sux compared to the dreamworld!"
  302. count=5
  303. fi
  304. break
  305. fi
  306. : $(( count++ ))
  307. done
  308. (( EPATCH_N_APPLIED_PATCHES++ ))
  309. # if we had to decompress the patch, delete the temp one
  310. if [[ -n ${PIPE_CMD} ]] ; then
  311. rm -f "${PATCH_TARGET}"
  312. fi
  313. if [[ ${count} -ge 5 ]] ; then
  314. echo
  315. eerror "Failed Patch: ${patchname} !"
  316. eerror " ( ${PATCH_TARGET} )"
  317. eerror
  318. eerror "Include in your bugreport the contents of:"
  319. eerror
  320. eerror " ${STDERR_TARGET}"
  321. echo
  322. die "Failed Patch: ${patchname}!"
  323. fi
  324. # if everything worked, delete the full debug patch log
  325. rm -f "${STDERR_TARGET}"
  326. # then log away the exact stuff for people to review later
  327. cat <<-EOF >> "${T}/epatch.log"
  328. PATCH: ${x}
  329. CMD: ${patch_cmd}
  330. PWD: ${PWD}
  331. EOF
  332. eend 0
  333. done
  334. [[ ${SINGLE_PATCH} == "no" ]] && einfo "Done with patching"
  335. : # everything worked
  336. }
  337. case ${EAPI:-0} in
  338. 0|1|2|3|4|5)
  339. # @VARIABLE: EPATCH_USER_SOURCE
  340. # @DESCRIPTION:
  341. # Location for user patches, see the epatch_user function.
  342. # Should be set by the user. Don't set this in ebuilds.
  343. : ${EPATCH_USER_SOURCE:=${PORTAGE_CONFIGROOT%/}/etc/portage/patches}
  344. # @FUNCTION: epatch_user
  345. # @USAGE:
  346. # @DESCRIPTION:
  347. # Applies user-provided patches to the source tree. The patches are
  348. # taken from /etc/portage/patches/<CATEGORY>/<P-PR|P|PN>[:SLOT]/, where the first
  349. # of these three directories to exist will be the one to use, ignoring
  350. # any more general directories which might exist as well. They must end
  351. # in ".patch" to be applied.
  352. #
  353. # User patches are intended for quick testing of patches without ebuild
  354. # modifications, as well as for permanent customizations a user might
  355. # desire. Obviously, there can be no official support for arbitrarily
  356. # patched ebuilds. So whenever a build log in a bug report mentions that
  357. # user patches were applied, the user should be asked to reproduce the
  358. # problem without these.
  359. #
  360. # Not all ebuilds do call this function, so placing patches in the
  361. # stated directory might or might not work, depending on the package and
  362. # the eclasses it inherits and uses. It is safe to call the function
  363. # repeatedly, so it is always possible to add a call at the ebuild
  364. # level. The first call is the time when the patches will be
  365. # applied.
  366. #
  367. # Ideally, this function should be called after gentoo-specific patches
  368. # have been applied, so that their code can be modified as well, but
  369. # before calls to e.g. eautoreconf, as the user patches might affect
  370. # autotool input files as well.
  371. epatch_user() {
  372. [[ $# -ne 0 ]] && die "epatch_user takes no options"
  373. # Allow multiple calls to this function; ignore all but the first
  374. local applied="${T}/epatch_user.log"
  375. [[ -e ${applied} ]] && return 2
  376. # don't clobber any EPATCH vars that the parent might want
  377. local EPATCH_SOURCE check
  378. for check in ${CATEGORY}/{${P}-${PR},${P},${PN}}{,:${SLOT%/*}}; do
  379. EPATCH_SOURCE=${EPATCH_USER_SOURCE}/${CTARGET}/${check}
  380. [[ -r ${EPATCH_SOURCE} ]] || EPATCH_SOURCE=${EPATCH_USER_SOURCE}/${CHOST}/${check}
  381. [[ -r ${EPATCH_SOURCE} ]] || EPATCH_SOURCE=${EPATCH_USER_SOURCE}/${check}
  382. if [[ -d ${EPATCH_SOURCE} ]] ; then
  383. local old_n_applied_patches=${EPATCH_N_APPLIED_PATCHES:-0}
  384. EPATCH_SOURCE=${EPATCH_SOURCE} \
  385. EPATCH_SUFFIX="patch" \
  386. EPATCH_FORCE="yes" \
  387. EPATCH_MULTI_MSG="Applying user patches from ${EPATCH_SOURCE} ..." \
  388. epatch
  389. echo "${EPATCH_SOURCE}" > "${applied}"
  390. if [[ ${old_n_applied_patches} -lt ${EPATCH_N_APPLIED_PATCHES} ]]; then
  391. has epatch_user_death_notice ${EBUILD_DEATH_HOOKS} || \
  392. EBUILD_DEATH_HOOKS+=" epatch_user_death_notice"
  393. fi
  394. return 0
  395. fi
  396. done
  397. echo "none" > "${applied}"
  398. return 1
  399. }
  400. # @FUNCTION: epatch_user_death_notice
  401. # @INTERNAL
  402. # @DESCRIPTION:
  403. # Include an explicit notice in the die message itself that user patches were
  404. # applied to this build.
  405. epatch_user_death_notice() {
  406. ewarn "!!! User patches were applied to this build!"
  407. }
  408. esac
  409. _EPATCH_ECLASS=1
  410. fi #_EPATCH_ECLASS