[arch-projects] [mkinitcpio][PATCH 4/6] add support for HOOKDIR/INSTDIR as arrays

Dave Reisner d at falconindy.com
Sat Mar 3 17:47:42 EST 2012


This is a really ugly patch, but allows mkinitcpio to read hooks from
multiple locations, namely:

  /usr/lib/initcpio/{install,hooks}
  /lib/initcpio/{install,hooks}

Preference is given to the first.

Signed-off-by: Dave Reisner <dreisner at archlinux.org>
---
 Makefile         |   24 ++++++++--------
 functions        |   18 ++++++++++--
 install/base     |    4 +--
 install/shutdown |    2 +-
 mkinitcpio       |   82 ++++++++++++++++++++++++++++++++----------------------
 5 files changed, 79 insertions(+), 51 deletions(-)

diff --git a/Makefile b/Makefile
index e1fe5aa..a9c6351 100644
--- a/Makefile
+++ b/Makefile
@@ -6,9 +6,9 @@ DIRS = \
 	/usr/bin \
 	/etc/bash_completion.d \
 	/etc/mkinitcpio.d \
-	/lib/initcpio/hooks \
-	/lib/initcpio/install \
-	/lib/initcpio/udev \
+	/usr/lib/initcpio/hooks \
+	/usr/lib/initcpio/install \
+	/usr/lib/initcpio/udev \
 	/usr/share/man/man8
 
 DIST_EXTRA = \
@@ -20,26 +20,26 @@ install: all
 	$(foreach dir,${DIRS},install -dm755 ${DESTDIR}${dir};)
 
 	sed -e 's|^CONFIG=.*|CONFIG=/etc/mkinitcpio.conf|' \
-	    -e 's|^FUNCTIONS=.*|FUNCTIONS=/lib/initcpio/functions|' \
-	    -e 's|^HOOKDIR=.*|HOOKDIR=/lib/initcpio/hooks|' \
-	    -e 's|^INSTDIR=.*|INSTDIR=/lib/initcpio/install|' \
+	    -e 's|^FUNCTIONS=.*|FUNCTIONS=/usr/lib/initcpio/functions|' \
+	    -e 's|^HOOKDIR=.*|HOOKDIR=({/usr,}/lib/initcpio/hooks)|' \
+	    -e 's|^INSTDIR=.*|INSTDIR=({/usr,}/lib/initcpio/install)|' \
 	    -e 's|^PRESETDIR=.*|PRESETDIR=/etc/mkinitcpio.d|' \
 	    -e 's|%VERSION%|${VERSION}|g' \
 	    < mkinitcpio > ${DESTDIR}/usr/bin/mkinitcpio
 
-	sed -e 's|\(^declare FUNCTIONS\)=.*|\1=/lib/initcpio/functions|' \
+	sed -e 's|\(^declare FUNCTIONS\)=.*|\1=/usr/lib/initcpio/functions|' \
 	    -e 's|%VERSION%|${VERSION}|g' \
 	    < lsinitcpio > ${DESTDIR}/usr/bin/lsinitcpio
 
 	chmod 755 ${DESTDIR}/usr/bin/lsinitcpio ${DESTDIR}/usr/bin/mkinitcpio
 
 	install -m644 mkinitcpio.conf ${DESTDIR}/etc/mkinitcpio.conf
-	install -m755 -t ${DESTDIR}/lib/initcpio init shutdown
-	install -m644 -t ${DESTDIR}/lib/initcpio init_functions functions
-	install -m644 01-memdisk.rules ${DESTDIR}/lib/initcpio/udev/01-memdisk.rules
+	install -m755 -t ${DESTDIR}/usr/lib/initcpio init shutdown
+	install -m644 -t ${DESTDIR}/usr/lib/initcpio init_functions functions
+	install -m644 01-memdisk.rules ${DESTDIR}/usr/lib/initcpio/udev/01-memdisk.rules
 
-	install -m644 -t ${DESTDIR}/lib/initcpio/hooks hooks/*
-	install -m644 -t ${DESTDIR}/lib/initcpio/install install/*
+	install -m644 -t ${DESTDIR}/usr/lib/initcpio/hooks hooks/*
+	install -m644 -t ${DESTDIR}/usr/lib/initcpio/install install/*
 	install -m644 -t ${DESTDIR}/etc/mkinitcpio.d mkinitcpio.d/*
 
 	install -m644 mkinitcpio.8 ${DESTDIR}/usr/share/man/man8/mkinitcpio.8
diff --git a/functions b/functions
index c85806a..5485578 100644
--- a/functions
+++ b/functions
@@ -337,7 +337,7 @@ parse_hook() {
     # prior to the start of hook processing, and after each hook's build
     # function is run.
 
-    local item=
+    local item= script=
 
     for item in $MODULES; do
         if [[ ${item:(-1)} = '?' ]]; then
@@ -355,7 +355,21 @@ parse_hook() {
         add_file "$item"
     done
 
-    [[ $SCRIPT ]] && add_file "$HOOKDIR/$SCRIPT" "/hooks/$SCRIPT"
+    if [[ $SCRIPT ]]; then
+        script=$(find_in_dirs "$SCRIPT" "${HOOKDIR[@]}") &&
+            add_file "$script" "/hooks/$SCRIPT"
+    fi
+}
+
+find_in_dirs() {
+    for dir in "${@:2}"; do
+        if [[ -e $dir/$1 ]]; then
+            printf '%s' "$dir/$1"
+            return 0
+        fi
+    done
+
+    return 1
 }
 
 # vim: set ft=sh ts=4 sw=4 et:
diff --git a/install/base b/install/base
index 3b7632f..db82fdc 100644
--- a/install/base
+++ b/install/base
@@ -31,8 +31,8 @@ build() {
     # Add an empty fstab to avoid mount warning when -o remount is used
     >"$BUILDROOT/etc/fstab"
 
-    add_file "/lib/initcpio/init_functions" "/init_functions"
-    add_file "/lib/initcpio/init" "/init"
+    add_file "/usr/lib/initcpio/init_functions" "/init_functions"
+    add_file "/usr/lib/initcpio/init" "/init"
     add_file "/lib/modprobe.d/usb-load-ehci-first.conf"
 
     # write a new config file. re-source the config as we can't guarantee the
diff --git a/install/shutdown b/install/shutdown
index 7c6b7bc..5b56f17 100644
--- a/install/shutdown
+++ b/install/shutdown
@@ -4,7 +4,7 @@ build() {
     BINARIES='cp'
     SCRIPT='shutdown'
 
-    add_file "/lib/initcpio/shutdown" "/shutdown"
+    add_file "/usr/lib/initcpio/shutdown" "/shutdown"
 }
 
 help() {
diff --git a/mkinitcpio b/mkinitcpio
index 637795f..9d59f0b 100755
--- a/mkinitcpio
+++ b/mkinitcpio
@@ -110,32 +110,34 @@ trap 'cleanup 130' INT
 trap 'cleanup 143' TERM
 
 while getopts ':c:k:sb:g:p:m:nvH:LMhS:t:z:' arg; do
-    case "${arg}" in
-        c) CONFIG="${OPTARG}" ;;
+    case $arg in
+        c) CONFIG=$OPTARG ;;
         k) optkver=$OPTARG ;;
-        s) SAVELIST=1; ;;
-        b) BASEDIR="${OPTARG}" ;;
-        g) GENIMG="${OPTARG}" ;;
+        s) SAVELIST=1 ;;
+        b) BASEDIR=$OPTARG ;;
+        g) GENIMG=$OPTARG ;;
         h) usage ;;
-        p) PRESET="${OPTARG}" ;;
+        p) PRESET=$OPTARG ;;
         n) COLOR=0 ;;
         v) QUIET=0 ;;
         S) IFS=, read -r -a SKIPHOOKS <<< "$OPTARG" ;;
-        H) if [[ ! -r "${INSTDIR}/${OPTARG}" ]]; then
-               error "No hook ${OPTARG}"
+        H) if script=$(find_in_dirs "$OPTARG" "${INSTDIR[@]}"); then
+               . "$script"
+               if [[ $(type -t help) != function ]]; then
+                   error "No help for hook $OPTARG"
+                   exit 1
+               fi
+           else
+               error "No hook '$OPTARG'"
                exit 1
            fi
-           . "${INSTDIR}/${OPTARG}"
-           if [[ $(type -t help) != function ]]; then
-               error "No help for hook ${OPTARG}"
-               exit 1
-           fi
-           msg "Help for hook '${OPTARG}':"
+           msg "Help for hook '$OPTARG':"
            help
            exit 0 ;;
         L) msg "Available hooks"
-           cd "$INSTDIR" >/dev/null
-           printf '   %s\n' * | column -c$(tput cols)
+           for dir in "${INSTDIR[@]}"; do
+               ( cd "$dir" >/dev/null; printf '   %s\n' * )
+           done | column -c$(tput cols)
            exit 0 ;;
         M) SHOW_AUTOMODS=1 ;;
         t) TMPDIR=$OPTARG ;;
@@ -276,9 +278,10 @@ fi
 
 if (( SHOW_AUTOMODS )); then
     msg "Modules autodetected"
-    . "${INSTDIR}/autodetect"
+    autodetect=$(find_in_dirs 'autodetect' "${INSTDIR[@]}")
+    . "$autodetect"
     build
-    cat "${MODULE_FILE}"
+    cat "$MODULE_FILE"
     cleanup 0
 fi
 
@@ -307,26 +310,37 @@ done
 for hook in ${HOOKS}; do
     in_array "$hook" "${SKIPHOOKS[@]}" && continue
     unset MODULES BINARIES FILES SCRIPT
-    build () { error "$hook: no build function..."; }
-
-    # A hook is considered deprecated if it is a symlink within $INSTDIR.
-    if [[ -L "$INSTDIR/$hook" ]]; then
-        newhook=$(readlink -e "$INSTDIR/$hook")
-        if [[ $newhook && "$INSTDIR/${newhook##*/}" -ef "$newhook" ]]; then
-            newhook=${newhook##*/}
-            warning "Hook '%s' is deprecated. Replace it with '%s' in your config" "$hook" "$newhook"
-            hook=$newhook
+    build() { error "$hook: no build function..."; return 1; }
+
+    # find script in install dirs
+    if ! script=$(find_in_dirs "$hook" "${INSTDIR[@]}"); then
+        error "Hook '$hook' cannot be found."
+        (( ++builderrors ))
+        continue
+    fi
+
+    # check for deprecation
+    if [[ -L $script ]]; then
+        if ! realscript=$(readlink -e "$script"); then
+            error "$script is a broken symlink to $(realpath "$script")"
+            (( ++builderrors ))
+            continue
         fi
+        warning "Hook '%s' is deprecated. Replace it with '%s' in your config" "$script" "$realscript"
+        script=$realscript
     fi
-    if [[ -r "${INSTDIR}/${hook}" ]]; then
-        . "${INSTDIR}/${hook}"
-        msg2 "Parsing hook: [%s]" "$hook"
-        build
-        parse_hook
-    else
-        error "Hook '$hook' can not be found."
+
+    # source
+    if ! . "$script"; then
+        error 'Failed to read %s' "$script"
         (( ++builderrors ))
+        continue
     fi
+
+    # run
+    msg2 "Parsing hook: [%s]" "${script##*/}"
+    build
+    parse_hook
 done
 
 # restore $CONFIG vars add to image
-- 
1.7.9.2



More information about the arch-projects mailing list