Index: head/Mk/Scripts/check_leftovers.sh =================================================================== --- head/Mk/Scripts/check_leftovers.sh (revision 471987) +++ head/Mk/Scripts/check_leftovers.sh (revision 471988) @@ -1,171 +1,171 @@ #! /bin/sh # $FreeBSD$ # # MAINTAINER: portmgr@FreeBSD.org # # This script is used by poudriere and tinderbox(soon) as the source-of-truth for # what should be considered a leftover and what is whitelisted. # # !!!! This script's input/output format must remain backwards-compatible. # !!!! If you want to change it, create a new script and have the calling # !!!! scripts use the new one if available. # # Usage: env PORTSDIR=... check_leftovers.sh category/port # stdin: # - missing-file # + new-file # M modified-file reason... # # stdout: # same -/+/M format, but with files substituted, without approved # whitelisted files, and hides any directories already in plist. # # The PLIST_SUB feature can be disabled by setting PLIST_SUB_SED= # in environment. [ -n "${DEBUG_MK_SCRIPTS}" -o -n "${DEBUG_MK_SCRIPTS_CHECK_LEFTOVERS}" ] && set -x origin="$1" [ $# -eq 1 ] || { echo "Must supply ORIGIN as parameter" >&2; exit 1; } [ -n "${PORTSDIR}" ] || { echo "PORTSDIR must be set" >&2; exit 1; } portdir="${PORTSDIR}/${origin}" # PREFIX/LOCALBASE may be set in env or want default from port. if [ -n "${PREFIX}" ]; then PORT_FLAGS="${PORT_FLAGS} PREFIX=${PREFIX}" else PREFIX=$(make -C ${portdir} -VPREFIX) fi if [ -n "${LOCALBASE}" ]; then PORT_FLAGS="${PORT_FLAGS} LOCALBASE=${LOCALBASE}" else LOCALBASE=$(make -C ${portdir} -VLOCALBASE) fi if [ -z "${CCACHE_DIR}" ]; then CCACHE_DIR=$(make -C ${portdir} -VCCACHE_DIR) fi -homedirs=$(awk -F: -v users=$(make -C ${portdir} -V USERS|sed -e 's, ,|,g;/^$/d;s,^,^(,;s,$,)$,') 'users && $1 ~ users {print $9}' ${PORTSDIR}/UIDs|sort -u|sed -e "s|/usr/local|${PREFIX}|"|tr "\n" " ") +homedirs=$(awk -F: -v users="$(make -C ${portdir} -V USERS|sed -e 's, ,|,g;/^$/d;s,^,^(,;s,$,)$,')" 'users && $1 ~ users {print $9}' ${PORTSDIR}/UIDs|sort -u|sed -e "s|/usr/local|${PREFIX}|"|tr "\n" " ") plistsub_sed=$(make -C ${portdir} -VPLIST_SUB_SED | /bin/sh ${PORTSDIR}/Mk/Scripts/plist_sub_sed_sort.sh) tmpplist=$(make -C ${portdir} -VTMPPLIST) while read modtype path extra; do # Ignore everything from these files/directories case "${path}" in ${CCACHE_DIR}/*|\ /compat/linux/proc/*|\ /dev/*|\ /etc/make.conf.bak|\ /proc/*|\ /tmp/*|\ /var/db/pkg/*|\ /var/db/ports/*|\ /var/log/*|\ /var/mail/*|\ /var/run/*|\ /var/tmp/*) continue ;; # fc-cache - skip for now /var/db/fontconfig/*) continue ;; esac ignore_path=0 sub_path=$(echo "$path" | sed -e "s|^${PREFIX}/||" -e "${plistsub_sed}") orig_sub_path="${sub_path}" # If this is a directory, use @dir in output is_dir=0 if [ -d "${path}" ]; then is_dir=1 sub_path="@dir ${sub_path}" fi # Handle PORTDOCS/PORTEXAMPLES/etc case "${orig_sub_path}" in %%DOCSDIR%%*) sub_path="%%PORTDOCS%%${sub_path}" ;; %%EXAMPLESDIR%%*) sub_path="%%PORTEXAMPLES%%${sub_path}" ;; esac case $modtype in +) if [ ${is_dir} -eq 1 ]; then # home directory of users created case " ${homedirs} " in *\ ${path}\ *) continue ;; *\ ${path}/*\ *) continue ;; esac # Don't show dirs already in plist (due to parents) grep -qE \ "^@(unexec rmdir \"?(%D/|${PREFIX})?${path#${PREFIX}/}[ \"]|dir(rm|rmtry)? ${path#${PREFIX}/}\$)" \ ${tmpplist} && continue fi # Check absolute paths case "${path}" in # Leave qmail's queue dir alone to not cause lost mail # during upgrades, just as /var/mail is left alone. /var/qmail/queue/*|/var/qmail/queue) continue ;; esac # Check relative/plist paths case "${sub_path}" in # gconftool-2 --makefile-uninstall-rule is unpredictable etc/gconf/gconf.xml.defaults/%gconf-tree*.xml) ;; *) echo "+ ${sub_path}" ;; esac ;; -) # Skip removal of PREFIX and PREFIX/info from # bsd.port.mk for now. # Skip if it is PREFIX and non-LOCALBASE. See misc/kdehier4 # or mail/qmail for examples [ "${path}" = "${PREFIX}" -a "${LOCALBASE}" != "${PREFIX}" ] && ignore_path=1 # The removal of info may be a bug; it's part of BSD.local.dist. # See ports/74691 [ "${sub_path}" = "info" -a "${LOCALBASE}" != "${PREFIX}" ] && ignore_path=1 [ $ignore_path -eq 0 ] && echo "- ${sub_path}" ;; M) # Check relative/plist paths case "${sub_path}" in # gconftool-2 --makefile-uninstall-rule is unpredictable etc/gconf/gconf.xml.defaults/%gconf-tree*.xml) ;; # This is a cache file for gio modules could be modified # for any gio modules lib/gio/modules/giomodule.cache) ;; # removal of info files leaves entry uneasy to cleanup # in info/dir info/dir) ;; */info/dir) ;; # The is pear database cache %%PEARDIR%%/.depdb|%%PEARDIR%%/.filemap) ;; #ls-R files from texmf are often regenerated */ls-R) ;; # Octave packages database, blank lines can be inserted # between pre-install and post-deinstall share/octave/octave_packages) ;; # xmlcatmgr is constantly updating catalog.ports ignore # modification to that file share/xml/catalog.ports) ;; # Ignore ghc's doc index share/doc/ghc-%%GHC_VERSION%%/*) ;; # Ignore ghc's package conf lib/ghc-%%GHC_VERSION%%/package.conf.d/*) ;; # Ignore common system config files /etc/group|\ /etc/make.conf|\ /etc/master.passwd|\ /etc/passwd|\ /etc/pwd.db|\ /etc/shells|\ /etc/spwd.db) ;; *) echo "M ${sub_path#@dir } ${extra}" ;; esac ;; esac done exit 0 Index: head/Mk/Scripts/depends-list.sh =================================================================== --- head/Mk/Scripts/depends-list.sh (revision 471987) +++ head/Mk/Scripts/depends-list.sh (revision 471988) @@ -1,128 +1,132 @@ #!/bin/sh # MAINTAINER: portmgr@FreeBSD.org # $FreeBSD$ set -e . ${dp_SCRIPTSDIR}/functions.sh flavors=0 recursive=0 missing=0 requires_wrkdir=0 while getopts "fmrw" FLAG; do case "${FLAG}" in f) flavors=1 ;; m) missing=1 recursive=1 ;; r) recursive=1 ;; w) # Only list dependencies that have a WRKDIR. Used for # 'make clean-depends'. # Without -r recurse when WRKDIR exists; with -r # always recurse. requires_wrkdir=1 ;; *) echo "Unknown flag" >&2 exit 1 ;; esac done shift $((OPTIND-1)) validate_env PORTSDIR dp_PKGNAME if [ ${recursive} -eq 1 -o ${requires_wrkdir} -eq 1 ]; then validate_env dp_MAKE # Cache command executions to avoid looking them up again in every # sub-make. MAKE="${dp_MAKE}" export_ports_env >/dev/null fi [ -n "${DEBUG_MK_SCRIPTS}" -o -n "${DEBUG_MK_SCRIPTS_DEPENDS_LIST}" ] && set -x set -u if [ ${missing} -eq 1 ]; then existing=$(${dp_PKG_INFO} -aoq|paste -d ' ' -s -) fi check_dep() { local _dep wrkdir show_dep for _dep ; do unset FLAVOR myifs=${IFS} IFS=: set -- ${_dep} IFS=${myifs} case "${2}" in /*) d=${2} ;; *) d=${PORTSDIR}/${2} ;; esac case "${d}" in *@*/*) ;; # Ignore @ in the path which would not be a flavor *@*) export FLAVOR=${d##*@} d=${d%@*} ;; esac if [ ${flavors} -eq 1 -a -n "${FLAVOR:-}" ]; then port_display="${d}@${FLAVOR}" else port_display="${d}" fi case " ${checked} " in *\ ${d}\ *) continue ;; # Already checked esac checked="${checked} ${d}" # Check if the dependency actually exists or skip otherwise. if [ ! -d "${d}" ]; then echo "${dp_PKGNAME}: \"${port_display}\" non-existent -- dependency list incomplete" >&2 continue fi # If only looking for missing, show if missing if [ ${missing} -eq 1 ]; then case " ${existing} " in *\ ${d#${PORTSDIR}/}\ *) continue ;; # We have it, nothing to see esac fi # Grab any needed vars from the port. if [ ${requires_wrkdir} -eq 1 ]; then + # shellcheck disable=SC2046 + # We want word splitting here. set -- $(${dp_MAKE} -C ${d} -VWRKDIR -V_UNIFIED_DEPENDS) wrkdir="$1" shift elif [ ${recursive} -eq 1 ]; then + # shellcheck disable=SC2046 + # We want word splitting here. set -- $(${dp_MAKE} -C ${d} -V_UNIFIED_DEPENDS) fi # If a WRKDIR is required to show the dependency, check for it. show_dep=1 if [ ${requires_wrkdir} -eq 1 ] && ! [ -d "${wrkdir}" ]; then show_dep=0 fi [ ${show_dep} -eq 1 ] && echo "${port_display}" if [ ${recursive} -eq 1 -o ${requires_wrkdir} -eq 1 -a ${show_dep} -eq 1 ]; then # shellcheck disable=SC2068 # Do not add quotes, we want to split the string here. check_dep $@ fi done } checked= # shellcheck disable=SC2068 # Do not add quotes, we want to split the string here. check_dep $@ Index: head/Mk/Scripts/find-lib.sh =================================================================== --- head/Mk/Scripts/find-lib.sh (revision 471987) +++ head/Mk/Scripts/find-lib.sh (revision 471988) @@ -1,33 +1,33 @@ #!/bin/sh # MAINTAINER: portmgr@FreeBSD.org # $FreeBSD$ [ -n "${DEBUG_MK_SCRIPTS}" -o -n "${DEBUG_MK_SCRIPTS_FIND_LIB}" ] && set -x if [ -z "${LIB_DIRS}" -o -z "${LOCALBASE}" ]; then echo "LIB_DIRS, LOCALBASE required in environment." >&2 exit 1 fi if [ -f /usr/share/misc/magic.mime -o -f /usr/share/misc/magic.mime.mgc ]; then echo >&2 echo "Either /usr/share/misc/magic.mime or /usr/share/misc/magic.mime.mgc exist and must be removed." >&2 echo "These are legacy files from an older release and may safely be deleted." >&2 echo "Please see UPDATING 20150213 for more details." >&2 exit 1 fi if [ $# -ne 1 ]; then echo "$0: no argument provided." >&2 fi lib=$1 dirs="${LIB_DIRS} $(cat ${LOCALBASE}/libdata/ldconfig/* 2>/dev/null || :)" for libdir in ${dirs} ; do test -f ${libdir}/${lib} || continue libfile=${libdir}/${lib} - [ $(file -b -L --mime-type ${libfile}) = "application/x-sharedlib" ] || continue + [ "$(file -b -L --mime-type ${libfile})" = "application/x-sharedlib" ] || continue echo $libfile break done Index: head/Mk/Scripts/functions.sh =================================================================== --- head/Mk/Scripts/functions.sh (revision 471987) +++ head/Mk/Scripts/functions.sh (revision 471988) @@ -1,271 +1,271 @@ #!/bin/sh # $FreeBSD$ # This file for common functions used for port scripts. # # MAINTAINER: portmgr@FreeBSD.org # Expand TMPPLIST to absolute paths, splitting files and dirs into separate # descriptors. # Input: # fd:0 - plist to parse # Required params: # PREFIX # parse_comments: Whether to parse and include commented files. # Output: # fd:1 - list of files # fd:2 - stderr # fd:3 - list of directories parse_plist() { local cwd cwd_save commented_cwd comment line newcwd parse_comments \ PREFIX PREFIX="${1}" parse_comments="${2:-1}" cwd=${PREFIX} cwd_save= commented_cwd= while read -r line; do # Handle deactivated OPTIONS. Treat "@comment file" as being in # the plist so it does not show up as an orphan. PLIST_SUB uses # a @comment to deactive files. XXX: It would be better to # make all ports use @ignore instead of @comment. if [ ${parse_comments} -eq 1 -a -z "${line%%@comment *}" ]; then line="${line##*@comment }" # Remove @comment so it can be parsed as a file, # but later prepend it again to create a list of # all files commented and uncommented. comment="@comment " # Only consider comment @cwd for commented lines if [ -n "${commented_cwd}" ]; then [ -z "${cwd_save}" ] && cwd_save=${cwd} cwd=${commented_cwd} fi else comment= # On first uncommented line, forget about commented # @cwd if [ -n "${cwd_save}" ]; then cwd=${cwd_save} cwd_save= commented_cwd= fi fi # Strip (owner,group,perm) from keywords line="$(printf %s "$line" \ | sed -Ee 's/^@\([^)]*\)[[:space:]]+//' \ -e 's/^(@[[:alpha:]]+)\([^)]*\)[[:space:]]+/\1 /')" case $line in @dir*|'@unexec rmdir'*|'@unexec /bin/rmdir'*) line="$(printf %s "$line" \ | sed -Ee 's/\|\|.*//;s|[[:space:]]+[0-9]*[[:space:]]*>[&]?[[:space:]]*[^[:space:]]+||g' \ -e "/^@unexec[[:space:]]+(\/bin\/)?rmdir( -p)?/s|([^%])%D([^%])|\1${cwd}\2|g" \ -e '/^@unexec[[:space:]]+(\/bin\/)?rmdir( -p)?/s|"(.*)"[[:space:]]*|\1|g' \ -e 's/@unexec[[:space:]]+(\/bin\/)?rmdir( -p)?[[:space:]]+//' \ -e 's/@dir(rm|rmtry)?[[:space:]]+//' \ -e 's/[[:space:]]+$//')" case "$line" in /*) echo >&3 "${comment}${line%/}" ;; *) echo >&3 "${comment}${cwd}/${line%/}" ;; esac ;; # Handle [file] Keywords @info\ *|@shell\ *|@xmlcatmgr\ *) set -- $line shift case "$*" in /*) echo "${comment}$*" ;; *) echo "${comment}${cwd}/$*" ;; esac ;; @sample\ *) set -- $line shift sample_file=$1 target_file=${1%.sample} if [ $# -eq 2 ]; then target_file=$2 fi case "${sample_file}" in /*) ;; *) sample_file=${cwd}/${sample_file} ;; esac case "${target_file}" in /*) ;; *) target_file=${cwd}/${target_file} ;; esac # Ignore the actual file if it is in stagedir echo "@comment ${target_file}" echo "${comment}${sample_file}" ;; # Handle [dir] Keywords @fc\ *|@fcfontsdir\ *|@fontsdir\ *) set -- $line shift case "$*" in /*) echo >&3 "${comment}$*" ;; *) echo >&3 "${comment}${cwd}/$*" ;; esac ;; # order matters here - we must check @cwd first because # otherwise the @cwd* would also match it first, shadowing the # @cwd) line. @cwd|@cd) # Don't actually reset cwd for commented @cwd if [ -n "${comment}" ]; then commented_cwd=${PREFIX} else cwd=${PREFIX} fi ;; @cwd*|@cd*) set -- $line newcwd=$2 # Don't set cwd=/ as it causes // in plist and # won't match later. [ "${newcwd}" = "/" ] && newcwd= # Don't actually reset cwd for commented @cwd if [ -n "${comment}" ]; then commented_cwd=${newcwd} else cwd=${newcwd} fi unset newcwd ;; @*) ;; /*) echo "${comment}${line}" ;; *) echo "${comment}${cwd}/${line}" ;; esac done } validate_env() { local envfault for i ; do if ! (eval ": \${${i}?}" ) >/dev/null; then envfault="${envfault}${envfault:+" "}${i}" fi done if [ -n "${envfault}" ]; then echo "Environment variable ${envfault} undefined. Aborting." \ | fmt >&2 exit 1 fi } export_ports_env() { local export_vars make_cmd make_env var value uses if [ -n "${HAVE_PORTS_ENV:-}" ]; then return 0 fi validate_env MAKE PORTSDIR uses="python compiler:features objc" make_env="\ _PORTS_ENV_CHECK=1 \ PACKAGE_BUILDING=1 \ GNU_CONFIGURE=1 \ USE_JAVA=1 \ USE_LINUX=1 \ " make_cmd="${make_env}" export_vars="$(${MAKE} -f ${PORTSDIR}/Mk/bsd.port.mk \ -V PORTS_ENV_VARS ${make_env} USES="${uses}")" for var in ${export_vars}; do make_cmd="${make_cmd}${make_cmd:+ }-V ${var}=\${${var}:Q}" done # Bring in all the vars, but not empty ones. - eval $(${MAKE} -f ${PORTSDIR}/Mk/bsd.port.mk ${make_cmd} \ - USES="${uses}" | grep -v '=$' | sed -e 's,\\ $,,') + eval "$(${MAKE} -f ${PORTSDIR}/Mk/bsd.port.mk ${make_cmd} \ + USES="${uses}" | grep -v '=$' | sed -e 's,\\ $,,')" for var in ${export_vars}; do # Export and display non-empty ones. This is not redundant # with above since we're looping on all vars here; do not # export a var we didn't eval in. value="$(eval echo \$${var})" if [ -n "${value}" ]; then # shellcheck disable=SC2163 # We want to export the variable which name is in var. export ${var} echo "export ${var}=\"${value}\"" fi done export HAVE_PORTS_ENV=1 echo "export HAVE_PORTS_ENV=1" } distinfo_data() { local alg file alg=$1 file=$2 if [ \( -n "${dp_DISABLE_SIZE}" -a -n "${dp_NO_CHECKSUM}" \) -o ! -f "${dp_DISTINFO_FILE}" ]; then exit fi awk -v alg="$alg" -v file="${file}" \ '$1 == alg && $2 == "(" file ")" {print $4}' "${dp_DISTINFO_FILE}" } check_checksum_algorithms() { for alg in ${dp_CHECKSUM_ALGORITHMS}; do eval "alg_executable=\$dp_$alg" if [ -z "$alg_executable" ]; then ${dp_ECHO_MSG} "Checksum algorithm $alg: Couldn't find the executable." ${dp_ECHO_MSG} "Set $alg=/path/to/$alg in /etc/make.conf and try again." exit 1 elif [ ! -x "$alg_executable" ]; then ${dp_ECHO_MSG} "Checksum algorithm $alg: $alg_executable is not executable." ${dp_ECHO_MSG} "Fix modes, or change $alg=$alg_executable in /etc/make.conf and try again." exit 1 fi done } escape() { echo "$1" | sed -e 's/[&;()!#]/\\&/g' } unescape() { echo "$1" | sed -e 's/\\//g' } # Fetch vars from the Makefile and set them locally. # port_var_fetch ports-mgmt/pkg "" PKGNAME pkgname PKGBASE pkgbase ... # the 2nd variable is for passing any wanted make arguments, such as # DEPENDS_ARGS. port_var_fetch() { local origin="$1" local make_args="$2" local _makeflags _vars local _portvar _var _line _makeflags= _vars= shift 2 while [ $# -ge 2 ]; do _portvar="$1" _var="$2" _makeflags="${_makeflags}${_makeflags:+ }-V${_portvar}" _vars="${_vars}${_vars:+ }${_var}" shift 2 done set -- ${_vars} while read -r _line; do setvar "$1" "${_line}" shift done <<-EOF $(${dp_MAKE} -C "${origin}" ${make_args} ${_makeflags} || echo) EOF } Index: head/Mk/Scripts/smart_makepatch.sh =================================================================== --- head/Mk/Scripts/smart_makepatch.sh (revision 471987) +++ head/Mk/Scripts/smart_makepatch.sh (revision 471988) @@ -1,295 +1,295 @@ #!/bin/sh # MAINTAINER: portmgr@FreeBSD.org # $FreeBSD$ # This script regenerates patches. It conserves existing comments and # file names, even if the file name does not meet any current or # previous convention. It will keep multiple patches in the same file # rather than splitting them into individual files. # # If a generated patch was not present before, it will create a file # name where forward slashes are replaced with an underscore and # underscores are appended by another underscore. # # Limitations: # 1) If a file is modified by multiple patches, it will be regenerated # as a single patch. That means if two multi-patch files modified # the same source file, when regenerated, the source file's patch # will only appear in one of patch file. # 2) It's possible that trailing garbage at the end of a patch in a # multipatch file might corrupt the comment (or be interpreted as # a comment) of the following patch. (garbage in, garbage out) # # Reminder # Don't forget to disable post-patch targets before regenerating patches # if those targets modify source files (e.g. with sed). You may also # want to disable EXTRA_PATCHES as well if that is being used. [ -n "${DEBUG_MK_SCRIPTS}" -o -n "${DEBUG_MK_SCRIPTS_SMART_MAKEPATCH}" ] && set -x if [ -z "${PATCHDIR}" -o -z "${PATCH_WRKSRC}" -o -z "${WRKDIR}" ]; then echo "WRKDIR, PATCHDIR, and PATCH_WRKSRC required in environment." >&2 exit 1 fi WORKAREA=${WRKDIR}/.makepatch-tmp PATCHMAP=${WORKAREA}/pregen.map COMMENTS=${WORKAREA}/comments REGENNED=${WORKAREA}/regenerated DESTDIR=${WORKAREA}/staged SAVEDIR=${WORKAREA}/archived-patches case "${STRIP_COMPONENTS}" in [123456789]) ;; 1[0123456789]) ;; *) STRIP_COMPONENTS=0 esac strip_path() { local raw_name=$1 if [ "${STRIP_COMPONENTS}" = "0" ]; then echo ${raw_name} else echo ${raw_name} | awk -v sc=${STRIP_COMPONENTS} -F "/" \ '{ for (x = sc + 1; x <= NF; x++) { \ slash = (x>sc+1) ? "/" : ""; \ printf ("%s%s", slash, $x); \ }}' fi } std_patch_filename() { local sans_cwd local raw_name sans_cwd=$(echo $1 | sed 's|^\.\/||') raw_name=$(strip_path ${sans_cwd}) - echo patch-$(echo ${raw_name} | sed -e 's|_|&&|g; s|/|_|g') + echo "patch-$(echo ${raw_name} | sed -e 's|_|&&|g; s|/|_|g')" } patchdir_files_list() { if [ -d "${PATCHDIR}" ]; then (cd ${PATCHDIR} && \ find * -type f -name "patch-*" -maxdepth 0 \ 2>/dev/null | sed -e '/\.orig$/d' ) fi; } valid_name() { local current_patch_name=$1 local result=$3 local first_target local testres local lps first_target=$(echo $2 | sed 's|^\.\/||') for lps in __ - + ; do testres=patch-$(echo ${first_target} | sed -e "s|/|${lps}|g") if [ "${testres}" = "${current_patch_name}" ]; then result=${testres} break fi done echo ${result} } map_existing_patches() { mkdir -p ${WORKAREA} : > ${PATCHMAP} local target local future_name local std_target local P local t for P in ${old_patch_list}; do target=$(cd ${PATCHDIR} && \ grep "^+++ " ${P} | awk '{print $2}' ) # For single patches, we honor previous separators, but use # a standard patch name if the current patch name does not # conform. However, if two or more patches are contained in # single file, then we do *NOT* rename the file future_name= for t in ${target}; do if [ -n "${future_name}" ]; then future_name=${P} break; fi std_target=$(std_patch_filename ${t}) future_name=$(valid_name ${P} ${t} ${std_target}) done for t in ${target}; do std_target=$(std_patch_filename ${t}) echo "${future_name} ${std_target}" >> ${PATCHMAP} done done } extract_comment_from_patch() { local existing_patch=${PATCHDIR}/$1 local contains local rawname local fname local num contains=$(grep "^+++ " ${existing_patch} | awk '{x++; print x}') for num in ${contains}; do rawname=$(grep "^+++ " ${existing_patch} | \ awk -v num=${num} '{x++; if (x==num) print $2}') fname=$(std_patch_filename $rawname) awk -v num=${num} '\ BEGIN { done=0; x=0; hunk=0; looking=(num==1) } \ { \ if (!done) { \ if ($1 == "@@") { \ split ($2,a,","); \ split ($3,b,","); \ hca = a[2]; hcb = a[3]; hunk = 1; } else if (hunk) { \ first=substr($1,1,1); \ if (first == "-") { hca-- } \ else if (first == "+") { hcb-- } \ else {hca--; hcb--} \ if (hca == 0 && hcb == 0) {hunk = 0} \ } \ if ($1 == "---") { \ x++; \ if (x == num) { done = 1 } \ if (x + 1 == num) { looking = 1 } \ } else if (!hunk && looking) { \ if ($1!="diff" && $1!="index" && $1!="+++") {\ print $0 \ } \ } \ } \ }' ${existing_patch} > ${COMMENTS}/${fname} done } extract_comments() { mkdir -p ${COMMENTS} rm -f ${COMMENTS}/* local P for P in ${old_patch_list}; do extract_comment_from_patch ${P} done } regenerate_patches() { mkdir -p ${REGENNED} rm -f ${REGENNED}/* [ ! -d "${PATCH_WRKSRC}" ] && return local F local NEW local OUT local ORIG local new_list new_list=$(cd "${PATCH_WRKSRC}" && \ find -s * -type f -name '*.orig' 2>/dev/null) (cd "${PATCH_WRKSRC}" && for F in ${new_list}; do ORIG=${F#./} NEW=${ORIG%.orig} cmp -s ${ORIG} ${NEW} && continue OUT=${REGENNED}/$(std_patch_filename ${NEW}) TZ=UTC diff -udp ${ORIG} ${NEW} | sed \ -e '/^---/s|\.[0-9]* +0000$| UTC|' \ -e '/^+++/s|\([[:blank:]][-0-9:.+]*\)*$||' \ > ${OUT} || true done) } get_patch_name() { awk -v name=$1 '\ { if ($2 == name) \ { \ if (!done) { print $1 }; \ done = 1; \ } \ } \ END { if (!done) print name }' ${PATCHMAP} } stage_patches() { mkdir -p ${DESTDIR} rm -f ${DESTDIR}/* local P local name local patch_list patch_list=$(cd ${REGENNED} && find * -name "patch-*" 2>/dev/null) for P in ${patch_list}; do name=$(get_patch_name ${P}) [ -e ${COMMENTS}/${P} ] && cat ${COMMENTS}/${P} \ >> ${DESTDIR}/${name} if [ "${P}" = "${name}" ]; then echo "Generated ${P}" else echo "Generated ${P} >> ${name} (legacy)" fi cat ${REGENNED}/${P} >> ${DESTDIR}/${name} done } compare_common_patches() { [ -z "${old_patch_list}" ] && return local archive_patch_list local P local ppatch local ppatch_stripped local cpatch local cpatch_stripped for P in ${old_patch_list}; do if [ -e ${DESTDIR}/${P} ]; then ppatch=${PATCHDIR}/${P} cpatch=${DESTDIR}/${P} ppatch_stripped=$(mktemp -t portpatch) cpatch_stripped=$(mktemp -t portpatch) egrep -v -- '--- .+ UTC$' ${ppatch} \ > ${ppatch_stripped} egrep -v -- '--- .+ UTC$' ${cpatch} \ > ${cpatch_stripped} # Don't replace patches with only metadata changes if ! cmp -s ${ppatch_stripped} ${cpatch_stripped}; then archive_patch_list="${archive_patch_list} ${P}" else echo "${P} only contains metadata changes; not replacing" rm ${cpatch} fi rm ${ppatch_stripped} rm ${cpatch_stripped} fi done old_patch_list=${archive_patch_list} } conserve_old_patches() { mkdir -p ${SAVEDIR} rm -f ${SAVEDIR}/* [ -z "${old_patch_list}" ] && return local P for P in ${old_patch_list}; do mv ${PATCHDIR}/${P} ${SAVEDIR}/${P} done echo "The previous patches have been placed here:" echo ${SAVEDIR} } install_regenerated_patches() { local testdir testdir=$(find ${DESTDIR} -empty) if [ -z "${testdir}" ]; then mkdir -p ${PATCHDIR} find ${DESTDIR} -type f -exec mv {} ${PATCHDIR}/ \; fi } old_patch_list=$(patchdir_files_list) map_existing_patches extract_comments regenerate_patches stage_patches compare_common_patches conserve_old_patches install_regenerated_patches