From a69ccd115238357c706383bc49db5c6ff33a5f4a Mon Sep 17 00:00:00 2001 From: Thierry Vignaud Date: Mon, 24 Sep 2018 11:36:47 +0200 Subject: add __brp_mangle_shebangs from FC in order to: - fix /bin -> /usr/bin - resolve "env foobar" -> "foobar" install it in /usr/lib/rpm/redhat to make clear from where it comes --- Makefile.am | 7 +++ NEWS | 2 + brp-mangle-shebangs | 142 ++++++++++++++++++++++++++++++++++++++++++++++++++++ build.macros.in | 6 +++ 4 files changed, 157 insertions(+) create mode 100755 brp-mangle-shebangs diff --git a/Makefile.am b/Makefile.am index 64f4cd4..619d682 100644 --- a/Makefile.am +++ b/Makefile.am @@ -54,6 +54,9 @@ pkg_attr_defs = \ perl_from_meta.attr \ php.attr +redhat_defs = \ + brp-mangle-shebangs + BUILT_SOURCES = macros-perarch make_arch_macrosfiles.sh rpmgenplatform foobar_pkglibdir = @RPMVENDORDIR@ @@ -81,6 +84,7 @@ EXTRA_DIST = \ $(pkg_attr_defs) \ $(pkg_scripts) \ $(pkg_scripts_in) \ + $(redhat_defs) \ macros-perarch.in make_arch_macrosfiles.sh.in \ rpmgenplatform.in rpmrc.in \ rpm-spec-mode.el \ @@ -128,6 +132,9 @@ endif for i in $(pkg_attr_defs); do \ $(install_sh_DATA) $${i} $(DESTDIR)$(RPMLIBDIR)/fileattrs/$${i}; \ done + for i in $(redhat_defs); do \ + $(install_sh_DATA) $${i} $(DESTDIR)$(RPMLIBDIR)/redhat/$${i}; \ + done if RPMPLATFORM for i in $(pkg_gconfig); do \ $(install_sh_DATA) $${i} $(DESTDIR)$(RPMSYSCONFDIR)/$${i}; \ diff --git a/NEWS b/NEWS index 20cd17f..1ffda0b 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,5 @@ +- add __brp_mangle_shebangs in order to fix /bin -> /usr/bin & "env foobar" + Version 2.35 - 24 September 2018, by Thierry Vignaud - reduce triming changelog from 3 to 2 years diff --git a/brp-mangle-shebangs b/brp-mangle-shebangs new file mode 100755 index 0000000..67a1a7d --- /dev/null +++ b/brp-mangle-shebangs @@ -0,0 +1,142 @@ +#!/bin/bash -eu + +# If using normal root, avoid changing anything. +if [ -z "$RPM_BUILD_ROOT" -o "$RPM_BUILD_ROOT" = "/" ]; then + exit 0 +fi + +exclude_files="" +exclude_files_from="" +exclude_shebangs="" +exclude_shebangs_from="" + +usage() { + local verbose=$1 && shift + local outfile=$1 && shift + local status=$1 && shift + + ( + echo 'usage: brp-mangle-shebangs [--files ] [--files-from ] [--shebangs ] [--shebangs-from ]' + if [ "${verbose}" == "yes" ]; then + echo ' --files: extended regexp of files to ignore' + echo ' --files-from: file containing a list of extended regexps of files to ignore' + echo ' --shebangs: extended regexp of shebangs to ignore' + echo ' --shebangs-from: file containing a list of extended regexps of shebangs to ignore' + fi + ) >>${outfile} + exit ${status} +} + +while [ $# -gt 0 ] ; do + case "$1" in + --files) + exclude_files="${2}" + shift + ;; + --files=*) + exclude_files="${1##--files=}" + ;; + --files-from) + exclude_files_from="${2}" + shift + ;; + --files-from=*) + exclude_files_from="${1##--files-from=}" + ;; + --shebangs) + exclude_shebangs="${2}" + shift + ;; + --shebangs=*) + exclude_shebangs="${1##--shebangs=}" + ;; + --shebangs-from) + exclude_shebangs_from="${2}" + shift + ;; + --shebangs-from=*) + exclude_shebangs_from="${1##--shebangs-from=}" + ;; + --help|--usage|"-?"|-h) + usage yes /dev/stdout 0 + ;; + *) + echo "Unknown option \"${1}\"" 1>&2 + usage no /dev/stderr 1 + ;; + esac + shift +done + +cd "$RPM_BUILD_ROOT" + +trim() { + printf '%s' "$*" +} + +fail=0 +while IFS= read -r -d $'\0' f; do + file -N --mime-type "$f" | grep -q -P ".+(?=: text/)" || continue + + # Remove the dot + path="${f#.}" + + if [ -n "$exclude_files" ]; then + echo "$path" | grep -q -E "$exclude_files" && continue + fi + if [ -n "$exclude_files_from" ]; then + echo "$path" | grep -q -E -f "$exclude_files_from" && continue + fi + + ts=$(stat -c %y "$f") + + read shebang_line < "$f" || : + orig_shebang=$(trim $(echo "$shebang_line" | grep -Po "#!\K.*" || echo)) + shebang="$orig_shebang" + if [ -n "$exclude_shebangs" ]; then + echo "$shebang" | grep -q -E "$exclude_shebangs" && continue + fi + if [ -n "$exclude_shebangs_from" ]; then + echo "$shebang" | grep -q -E -f "$exclude_shebangs_from" && continue + fi + + if [ -z "$shebang" ]; then + echo >&2 "*** WARNING: $f is executable but has empty or no shebang, removing executable bit" + chmod -x "$f" + touch -d "$ts" "$f" + continue + elif [ -n "${shebang##/*}" ]; then + echo >&2 "*** ERROR: $f has shebang which doesn't start with '/' ($shebang)" + fail=1 + continue + fi + + if ! { echo "$shebang" | grep -q -P "^/(?:usr/)?(?:bin|sbin)/"; }; then + continue + fi + + # Replace "special" env shebang: + # /whatsoever/env /whatever/foo → /whatever/foo + shebang=$(echo "$shebang" | sed -r -e 's@^(.+)/env /(.+)$@/\2@') + # /whatsoever/env foo → /whatsoever/foo + shebang=$(echo "$shebang" | sed -r -e 's@^(.+/)env (.+)$@\1\2@') + + # If the shebang now starts with /bin, change it to /usr/bin + # https://bugzilla.redhat.com/show_bug.cgi?id=1581757 + shebang=$(echo "$shebang" | sed -r -e 's@^/bin/@/usr/bin/@') + + # Replace ambiguous python with python2 + py_shebang=$(echo "$shebang" | sed -r -e 's@/usr/bin/python(\s|$)@/usr/bin/python2\1@') + + if [ "$shebang" != "$py_shebang" ]; then + echo >&2 "*** ERROR: ambiguous python shebang in $path: #!$orig_shebang. Change it to python3 (or python2) explicitly." + fail=1 + elif [ "#!$shebang" != "#!$orig_shebang" ]; then + sed -i -e "1c #!$shebang" "$f" + echo "mangling shebang in $path from $orig_shebang to #!$shebang" + fi + + touch -d "$ts" "$f" +done < <(find -executable -type f -print0) + +exit $fail diff --git a/build.macros.in b/build.macros.in index 1125682..e37e157 100644 --- a/build.macros.in +++ b/build.macros.in @@ -447,11 +447,17 @@ fi %__brp_python_bytecompile /usr/lib/rpm/brp-python-bytecompile "%{__python}" "%{?_python_bytecompile_errors_terminate_build}" "%{?_python_bytecompile_extra}" %__brp_python_hardlink /usr/lib/rpm/brp-python-hardlink +# __brp_mangle_shebangs_exclude - shebangs to exclude +# __brp_mangle_shebangs_exclude_file - file from which to get shebangs to exclude +# __brp_mangle_shebangs_exclude_from - files to ignore +# __brp_mangle_shebangs_exclude_from_file - file from which to get files to ignore +%__brp_mangle_shebangs /usr/lib/rpm/redhat/brp-mangle-shebangs %{?__brp_mangle_shebangs_exclude:--shebangs "%{?__brp_mangle_shebangs_exclude}"} %{?__brp_mangle_shebangs_exclude_file:--shebangs-from "%{__brp_mangle_shebangs_exclude_file}"} %{?__brp_mangle_shebangs_exclude_from:--files "%{?__brp_mangle_shebangs_exclude_from}"} %{?__brp_mangle_shebangs_exclude_from_file:--files-from "%{__brp_mangle_shebangs_exclude_from_file}"} %__os_install_post \ %{?__spec_helper_post}%{?!__spec_helper_post:/usr/share/spec-helper/spec-helper} \ %{?py_auto_byte_compile:%{?__brp_python_bytecompile}} \ %{?__brp_python_hardlink} \ + %{?__brp_mangle_shebangs} \ %{nil} %install %{?_enable_debug_packages:%{?buildsubdir:%{debug_package}}}\ -- cgit v1.2.1