fix(pkg): _fixup_imports truncates paths with spaces, breaking otool

pgadmin4-appbundle-build #110 (macos-x64) failed with:
  error: otool-classic: can't open file: ./Contents/Frameworks/pgAdmin
  error: otool-classic: can't open file: ./Contents/Frameworks/Electron

_fixup_imports built its worklist with `awk -F':| '`, a regex
alternation that splits on a literal ':' OR any bare space. `file`'s
actual output format is "path: description" (colon-space as one
token), so any space *inside* the path itself - "pgAdmin 4 Helper
(Plugin).app", "Electron Framework.framework", both routine in macOS
app bundles - also got treated as a split point, truncating $1 to
whatever preceded the first space.

The resulting list was then joined with a single space (ORS=" ") and
iterated via an unquoted `for x in $list`, which word-splits on
spaces again - doubly ambiguous between a path's own spaces and the
list's separator, unrecoverable however it's parsed.

Fix: split only on the literal ": " token file emits (`awk -F': '`,
not `-F ':| '`), and switch the whole worklist to newline-separated
instead of space-separated, iterated with `while IFS= read -r`
instead of `for x in $unquoted_list`, at both the outer (executable)
level and inner (library-copy) level (`TODO="${TODO}"$'\n'"..."`).

Not yet verified against a real buildfarm run - can't reproduce the
macOS codesigning environment locally. Watching the next
pgadmin4-appbundle-build run.
This commit is contained in:
Ashesh Vashi
2026-07-30 09:48:03 +05:30
parent 689c969f95
commit 0296de48ee
+23 -9
View File
@@ -169,29 +169,43 @@ _build_docs() {
}
_fixup_imports() {
local TODO TODO_OLD FW_RELPATH LIB LIB_BN
local TODO TODO_OLD TODO_PYTHON FW_RELPATH LIB LIB_BN
echo "Fixing imports on the core appbundle..."
pushd "$1" > /dev/null || exit
# Find all the files that may need tweaks
# Find all the files that may need tweaks.
#
# NOTE: entries are newline-separated, not space-separated. macOS
# app bundles routinely have spaces in paths (helper .app names,
# "Electron Framework.framework", etc.) - splitting/joining on
# spaces truncates those paths at the first space (e.g.
# "pgAdmin 4 Helper (Plugin)" becomes just "pgAdmin"), which then
# fails outright in otool/install_name_tool below. `awk -F': '`
# splits only on the literal ": " token `file` emits between the
# path and its description, leaving spaces inside the path intact.
TODO=$(find . -perm +0111 -type f -exec file "{}" \; | \
grep -v "Frameworks/Python.framework" | \
grep -E "Mach-O 64-bit" | \
awk -F ':| ' '{ORS=" "; print $1}' | \
awk -F': ' '{print $1}' | \
uniq)
# Add anything in the site-packages Python directory
TODO+=$(find ./Contents/Frameworks/Python.framework/Versions/Current/lib/python*/site-packages -perm +0111 -type f -exec file "{}" \; | \
TODO_PYTHON=$(find ./Contents/Frameworks/Python.framework/Versions/Current/lib/python*/site-packages -perm +0111 -type f -exec file "{}" \; | \
grep -E "Mach-O 64-bit" | \
awk -F ':| ' '{ORS=" "; print $1}' | \
awk -F': ' '{print $1}' | \
uniq)
if [ -n "${TODO_PYTHON}" ]; then
TODO="${TODO}"$'\n'"${TODO_PYTHON}"
fi
echo "Found executables: ${TODO}"
echo "Found executables:"
echo "${TODO}"
while test "${TODO}" != ""; do
TODO_OLD=${TODO} ;
TODO="" ;
for TODO_OBJ in ${TODO_OLD}; do
while IFS= read -r TODO_OBJ; do
[ -z "${TODO_OBJ}" ] && continue
echo "Post-processing: ${TODO_OBJ}"
# The Rust interface in the Python Cryptography module contains
@@ -234,7 +248,7 @@ _fixup_imports() {
install_name_tool \
-id "${LIB_BN}" \
"Contents/Frameworks/${LIB_BN}" || exit 1
TODO="${TODO} ./Contents/Frameworks/${LIB_BN}"
TODO="${TODO}"$'\n'"./Contents/Frameworks/${LIB_BN}"
fi
# Rewrite the dependency paths
@@ -248,7 +262,7 @@ _fixup_imports() {
"@loader_path/${FW_RELPATH}/${TARGET_FILE}" \
"${TODO_OBJ}" || exit 1
done
done
done <<< "${TODO_OLD}"
done
echo "Imports updated on the core appbundle."