Merge pull request #10954 from reitermarkus/rmdir-sh

Speed up `pkg` uninstallation and only call `find` on directories.
This commit is contained in:
Markus Reiter 2021-04-02 22:49:49 +02:00 committed by GitHub
commit bcb3fc111f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 69 additions and 43 deletions

View File

@ -107,41 +107,14 @@ module Cask
# Helper script to delete empty directories after deleting `.DS_Store` files and broken symlinks. # Helper script to delete empty directories after deleting `.DS_Store` files and broken symlinks.
# Needed in order to execute all file operations with `sudo`. # Needed in order to execute all file operations with `sudo`.
RMDIR_SH = <<~'BASH' RMDIR_SH = (HOMEBREW_LIBRARY_PATH/"cask/utils/rmdir.sh").freeze
set -euo pipefail
for path in "${@}"; do
if [[ ! -e "${path}" ]]; then
continue
fi
if [[ -e "${path}/.DS_Store" ]]; then
/bin/rm -f "${path}/.DS_Store"
fi
# Some packages leave broken symlinks around; we clean them out before
# attempting to `rmdir` to prevent extra cruft from accumulating.
/usr/bin/find "${path}" -mindepth 1 -maxdepth 1 -type l ! -exec /bin/test -e {} \; -delete
if [[ -L "${path}" ]]; then
# Delete directory symlink.
/bin/rm "${path}"
elif [[ -d "${path}" ]]; then
# Delete directory if empty.
/usr/bin/find "${path}" -maxdepth 0 -type d -empty -exec /bin/rmdir {} \;
else
# Try `rmdir` anyways to show a proper error.
/bin/rmdir "${path}"
fi
done
BASH
private_constant :RMDIR_SH private_constant :RMDIR_SH
sig { params(path: T.any(Pathname, T::Array[Pathname])).void } sig { params(path: T.any(Pathname, T::Array[Pathname])).void }
def rmdir(path) def rmdir(path)
@command.run!( @command.run!(
"/usr/bin/xargs", "/usr/bin/xargs",
args: ["-0", "--", "/bin/bash", "-c", RMDIR_SH, "--"], args: ["-0", "--", RMDIR_SH.to_s],
input: Array(path).join("\0"), input: Array(path).join("\0"),
sudo: true, sudo: true,
) )

View File

@ -0,0 +1,41 @@
#!/bin/bash
set -euo pipefail
# Try removing as many empty directories as possible with a single
# `rmdir` call to avoid or at least speed up the loop below.
if /bin/rmdir -- "${@}" &>/dev/null; then
exit
fi
for path in "${@}"; do
symlink=true
[[ -L "${path}" ]] || symlink=false
directory=false
if [[ -d "${path}" ]]; then
directory=true
if [[ -e "${path}/.DS_Store" ]]; then
/bin/rm -- "${path}/.DS_Store"
fi
# Some packages leave broken symlinks around; we clean them out before
# attempting to `rmdir` to prevent extra cruft from accumulating.
/usr/bin/find -f "${path}" -- -mindepth 1 -maxdepth 1 -type l ! -exec /bin/test -e {} \; -delete
elif ! ${symlink} && [[ ! -e "${path}" ]]; then
# Skip paths that don't exists and aren't a broken symlink.
continue
fi
if ${symlink}; then
# Delete directory symlink.
/bin/rm -- "${path}"
elif ${directory}; then
# Delete directory if empty.
/usr/bin/find -f "${path}" -- -maxdepth 0 -type d -empty -exec /bin/rmdir -- {} \;
else
# Try `rmdir` anyways to show a proper error.
/bin/rmdir -- "${path}"
fi
done

View File

@ -7,7 +7,7 @@ pathremove() {
NEWPATH=${NEWPATH:+$NEWPATH:}$DIR NEWPATH=${NEWPATH:+$NEWPATH:}$DIR
fi fi
done done
export $PATHVARIABLE="$NEWPATH" export "$PATHVARIABLE"="$NEWPATH"
} }
if [[ -n "$HOMEBREW_MAKE" && "$HOMEBREW_MAKE" != "make" ]] if [[ -n "$HOMEBREW_MAKE" && "$HOMEBREW_MAKE" != "make" ]]
@ -16,7 +16,8 @@ then
else else
SAVED_PATH="$PATH" SAVED_PATH="$PATH"
pathremove "$HOMEBREW_LIBRARY/Homebrew/shims/linux/super" pathremove "$HOMEBREW_LIBRARY/Homebrew/shims/linux/super"
export MAKE="$(which make)" MAKE="$(which make)"
export MAKE
export PATH="$SAVED_PATH" export PATH="$SAVED_PATH"
fi fi

View File

@ -1,6 +1,9 @@
#!/bin/bash #!/bin/bash
# System Ruby's mkmf on Mojave (10.14) and later require SDKROOT set to work correctly. # System Ruby's mkmf on Mojave (10.14) and later require SDKROOT set to work correctly.
# Don't need shellcheck to follow the `source`.
# shellcheck disable=SC1090
source "$HOMEBREW_LIBRARY/Homebrew/shims/utils.sh" source "$HOMEBREW_LIBRARY/Homebrew/shims/utils.sh"
try_exec_non_system "$SHIM_FILE" "$@" try_exec_non_system "$SHIM_FILE" "$@"

View File

@ -1,4 +1,5 @@
#!/bin/bash #!/bin/bash
# Historically, xcrun has had various bugs, and in some cases it didn't # Historically, xcrun has had various bugs, and in some cases it didn't
# work at all (e.g. CLT-only in the Xcode 4.3 era). This script emulates # work at all (e.g. CLT-only in the Xcode 4.3 era). This script emulates
# it and attempts to avoid these issues. # it and attempts to avoid these issues.
@ -27,10 +28,10 @@ arg0=$1
shift shift
exe="/usr/bin/${arg0}" exe="/usr/bin/${arg0}"
if [ -x "$exe" ]; then if [[ -x "$exe" ]]; then
if [ -n "$HOMEBREW_PREFER_CLT_PROXIES" ]; then if [[ -n "$HOMEBREW_PREFER_CLT_PROXIES" ]]; then
exec "$exe" "$@" exec "$exe" "$@"
elif [ -z "$HOMEBREW_SDKROOT" -o ! -d "$HOMEBREW_SDKROOT" ]; then elif [[ -z "$HOMEBREW_SDKROOT" || ! -d "$HOMEBREW_SDKROOT" ]]; then
exec "$exe" "$@" exec "$exe" "$@"
fi fi
fi fi
@ -38,7 +39,7 @@ fi
SUPERBIN=$(cd "${0%/*}" && pwd -P) SUPERBIN=$(cd "${0%/*}" && pwd -P)
exe=$(/usr/bin/xcrun --find "$arg0" 2>/dev/null) exe=$(/usr/bin/xcrun --find "$arg0" 2>/dev/null)
if [ -x "$exe" -a "${exe%/*}" != "$SUPERBIN" ]; then if [[ -x "$exe" && "${exe%/*}" != "$SUPERBIN" ]]; then
exec "$exe" "$@" exec "$exe" "$@"
fi fi
@ -57,7 +58,7 @@ done
IFS=$old_IFS IFS=$old_IFS
echo >&2 " echo >&2 "
Failed to execute $arg0 $@ Failed to execute ${arg0} ${*}
Xcode and/or the CLT appear to be misconfigured. Try one or both of the following: Xcode and/or the CLT appear to be misconfigured. Try one or both of the following:
xcodebuild -license xcodebuild -license

View File

@ -9,6 +9,8 @@ then
exit 1 exit 1
fi fi
# Don't need shellcheck to follow the `source`.
# shellcheck disable=SC1090
source "$HOMEBREW_LIBRARY/Homebrew/shims/utils.sh" source "$HOMEBREW_LIBRARY/Homebrew/shims/utils.sh"
case "$(lowercase "$SHIM_FILE")" in case "$(lowercase "$SHIM_FILE")" in

View File

@ -60,8 +60,10 @@ safe_exec() {
fi fi
if [[ "$HOMEBREW" = "print-path" ]] if [[ "$HOMEBREW" = "print-path" ]]
then then
local dir="$(quiet_safe_cd "${arg0%/*}/" && pwd)" local dir
local path="$(dirbasepath "$dir" "$arg0")" dir="$(quiet_safe_cd "${arg0%/*}/" && pwd)"
local path
path="$(dirbasepath "$dir" "$arg0")"
echo "$path" echo "$path"
exit exit
fi fi

View File

@ -177,13 +177,16 @@ module Homebrew
files = [ files = [
HOMEBREW_BREW_FILE, HOMEBREW_BREW_FILE,
# TODO: HOMEBREW_REPOSITORY/"completions/bash/brew", # TODO: HOMEBREW_REPOSITORY/"completions/bash/brew",
*Pathname.glob("#{HOMEBREW_LIBRARY}/Homebrew/*.sh"), *HOMEBREW_LIBRARY.glob("Homebrew/*.sh"),
*Pathname.glob("#{HOMEBREW_LIBRARY}/Homebrew/cmd/*.sh"), *HOMEBREW_LIBRARY.glob("Homebrew/shims/**/*").map(&:realpath).uniq
*Pathname.glob("#{HOMEBREW_LIBRARY}/Homebrew/utils/*.sh"), .reject { |path| path.directory? || path.basename.to_s == "cc" },
*HOMEBREW_LIBRARY.glob("Homebrew/{dev-,}cmd/*.sh"),
*HOMEBREW_LIBRARY.glob("Homebrew/{cask/,}utils/*.sh"),
] ]
end end
args = ["--shell=bash", "--", *files] # TODO: Add `--enable=all` to check for more problems. # TODO: Add `--enable=all` to check for more problems.
args = ["--shell=bash", "--external-sources", "--", *files]
case output_type case output_type
when :print when :print

View File

@ -97,7 +97,7 @@ describe Cask::Pkg, :cask do
allow(fake_system_command).to receive(:run!).and_call_original allow(fake_system_command).to receive(:run!).and_call_original
expect(fake_system_command).to receive(:run!).with( expect(fake_system_command).to receive(:run!).with(
"/usr/bin/xargs", "/usr/bin/xargs",
args: ["-0", "--", "/bin/bash", "-c", a_string_including("/bin/rmdir"), "--"], args: ["-0", "--", a_string_including("rmdir")],
input: [fake_dir].join("\0"), input: [fake_dir].join("\0"),
sudo: true, sudo: true,
).and_return(instance_double(SystemCommand::Result, stdout: "")) ).and_return(instance_double(SystemCommand::Result, stdout: ""))