mirror of
https://github.com/Homebrew/brew.git
synced 2026-10-28 09:34:42 +08:00
Merge pull request #24360 from Homebrew/as-brew-user-relative-brewfile
Preserve working directories when switching users
This commit is contained in:
5 files changed
+20
-30
No files matched your search
@@ -52,7 +52,7 @@ RSpec.describe Homebrew::Cmd::AsBrewUser do
|
||||
|
||||
it "runs directly as the prefix owner without sudo" do
|
||||
brew_file = test_root/"brew"
|
||||
brew_file.write "#!/bin/bash\nprintf '%s\\n' \"$USER|$HOME|$*|$HOMEBREW_NO_SUDO\"\n"
|
||||
brew_file.write "#!/bin/bash\nprintf '%s\\n' \"$USER|$HOME|$PWD|$*|$HOMEBREW_NO_SUDO\"\n"
|
||||
brew_file.chmod(0755)
|
||||
stdout, = run_as_brew_user_shell(
|
||||
<<~SH,
|
||||
@@ -69,7 +69,7 @@ RSpec.describe Homebrew::Cmd::AsBrewUser do
|
||||
"HOMEBREW_BREW_FILE" => brew_file.to_s),
|
||||
)
|
||||
|
||||
expect(stdout).to eq("brewer|#{test_root}|list|1\n")
|
||||
expect(stdout).to eq("brewer|#{test_root}|#{Dir.pwd}|list|1\n")
|
||||
end
|
||||
|
||||
it "rejects a root-owned prefix" do
|
||||
@@ -85,9 +85,9 @@ RSpec.describe Homebrew::Cmd::AsBrewUser do
|
||||
expect(stderr).to include("The Homebrew prefix owner must not be root.")
|
||||
end
|
||||
|
||||
it "enters the owner's home after switching users" do
|
||||
it "preserves the working directory and relative paths after switching users" do
|
||||
brew_file = test_root/"brew"
|
||||
brew_file.write "#!/bin/bash\nprintf '%s\\n' \"$PWD\"\n"
|
||||
brew_file.write "#!/bin/bash\nprintf '%s\\n' \"$PWD\" \"$@\"\n"
|
||||
brew_file.chmod(0755)
|
||||
stdout, = run_as_brew_user_shell(
|
||||
<<~SH,
|
||||
@@ -97,14 +97,13 @@ RSpec.describe Homebrew::Cmd::AsBrewUser do
|
||||
[[ "$1" == -un ]] && { echo operator; return; }
|
||||
printf 'brewer:*:503:20::0:0:Brewer:#{test_root}:/bin/zsh\\n'
|
||||
}
|
||||
cd() { return 1; }
|
||||
sudo() { shift 3; "$@"; }
|
||||
homebrew-as-brew-user list
|
||||
homebrew-as-brew-user bundle --file ./Brewfile
|
||||
SH
|
||||
macos_env.merge("HOMEBREW_PREFIX" => "/opt/homebrew", "HOMEBREW_BREW_FILE" => brew_file.to_s),
|
||||
)
|
||||
|
||||
expect(stdout).to eq("#{test_root}\n")
|
||||
expect(stdout).to eq("#{Dir.pwd}\nbundle\n--file\n./Brewfile\n")
|
||||
end
|
||||
|
||||
it "selects the prefix owner on Linux" do
|
||||
|
||||
@@ -266,7 +266,7 @@ RSpec.describe Homebrew::Cmd::AsConsoleUser do
|
||||
expect(stdout).to be_empty
|
||||
expect(stderr).to be_empty
|
||||
expect(args_file.read).to eq <<~EOS
|
||||
cwd=#{console_home}
|
||||
cwd=#{Dir.pwd}
|
||||
-H
|
||||
-u
|
||||
mike
|
||||
@@ -275,7 +275,7 @@ RSpec.describe Homebrew::Cmd::AsConsoleUser do
|
||||
HOME=#{console_home}
|
||||
USER=mike
|
||||
LOGNAME=mike
|
||||
PWD=#{console_home}
|
||||
PWD=#{Dir.pwd}
|
||||
PATH=/usr/bin:/bin:/usr/sbin:/sbin
|
||||
/opt/homebrew/bin/brew
|
||||
upgrade
|
||||
|
||||
@@ -74,7 +74,7 @@ RSpec.shared_examples "switching users without sudo" do |command_name = nil|
|
||||
stdout, stderr, status = result
|
||||
|
||||
expect([stdout.lines(chomp: true), stderr, status.exitstatus]).to eq([
|
||||
["brewer", test_root.to_s, test_root.to_s, "1", "unset",
|
||||
["brewer", test_root.to_s, Dir.pwd, "1", "unset",
|
||||
"list", "argument with spaces", "", '$(exit 1); * "quotes"'],
|
||||
"", 42
|
||||
])
|
||||
|
||||
@@ -78,24 +78,12 @@ homebrew-as-user() {
|
||||
fi
|
||||
fi
|
||||
|
||||
(
|
||||
if [[ "${command_name}" == as-brew-user ]]
|
||||
then
|
||||
# Expand HOME only after switching to the prefix owner.
|
||||
# shellcheck disable=SC2016
|
||||
set -- /bin/bash -c 'cd -- "$HOME" && exec "$@"' -- "${HOMEBREW_BREW_FILE}" "$@"
|
||||
else
|
||||
cd "${selected_home}" &>/dev/null || odie "Failed to cd to ${selected_home}!"
|
||||
set -- "${HOMEBREW_BREW_FILE}" "$@"
|
||||
fi
|
||||
|
||||
"${user_command[@]}" /usr/bin/env -i \
|
||||
"HOME=${selected_home}" \
|
||||
"USER=${selected_user}" \
|
||||
"LOGNAME=${selected_user}" \
|
||||
"PWD=${selected_home}" \
|
||||
"PATH=/usr/bin:/bin:/usr/sbin:/sbin" \
|
||||
${HOMEBREW_NO_SUDO:+"HOMEBREW_NO_SUDO=${HOMEBREW_NO_SUDO}"} \
|
||||
"$@"
|
||||
)
|
||||
"${user_command[@]}" /usr/bin/env -i \
|
||||
"HOME=${selected_home}" \
|
||||
"USER=${selected_user}" \
|
||||
"LOGNAME=${selected_user}" \
|
||||
"PWD=${PWD}" \
|
||||
"PATH=/usr/bin:/bin:/usr/sbin:/sbin" \
|
||||
${HOMEBREW_NO_SUDO:+"HOMEBREW_NO_SUDO=${HOMEBREW_NO_SUDO}"} \
|
||||
"${HOMEBREW_BREW_FILE}" "$@"
|
||||
}
|
||||
@@ -85,6 +85,8 @@ brew as-brew-user install wget
|
||||
```
|
||||
|
||||
The command uses the owner's home and a clean environment, switching accounts through sudo when necessary.
|
||||
It preserves the caller's working directory, so relative paths resolve as usual.
|
||||
The owner must have access to the working directory and any files used by the command.
|
||||
When sudo is disabled or unavailable, an already-root process switches through macOS `login` or Linux `runuser` instead.
|
||||
These commands use the selected account's primary and supplementary groups.
|
||||
Without permission to switch accounts, log in as the owner instead.
|
||||
@@ -102,6 +104,7 @@ brew as-console-user install wget
|
||||
```
|
||||
|
||||
The command uses that user's home and a clean environment.
|
||||
Like `as-brew-user`, it preserves the caller's working directory, which the selected user must be able to access.
|
||||
An already-root process can switch users even when sudo is disabled or unavailable, using the same fallback as `as-brew-user`.
|
||||
Other accounts need sudo access to switch users.
|
||||
It fails if no supported console user is logged in.
|
||||
|
||||
Reference in new issue
Block a user