-
Notifications
You must be signed in to change notification settings - Fork 0
fix(brew): update Homebrew before non-interactive installs #43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,6 +17,23 @@ export class ShellCommandError extends Error { | |
| } | ||
| } | ||
|
|
||
| let homebrewUpdated = false; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 为了支持在其他模块和测试中更新或重置 这样做有两个主要好处:
let homebrewUpdated = false;
export function setHomebrewUpdated(value) {
homebrewUpdated = value;
} |
||
|
|
||
| export function brewUpdate() { | ||
| if (homebrewUpdated) return; | ||
|
|
||
| const cmd = "env -u HOMEBREW_ASK brew update"; | ||
| try { | ||
| execSync(cmd, { stdio: "inherit" }); | ||
| homebrewUpdated = true; | ||
| } catch (error) { | ||
| throw new ShellCommandError(cmd, { | ||
| code: error.status, | ||
| signal: error.signal, | ||
| }); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Run a shell command synchronously. Returns stdout as string. | ||
| * Throws on non-zero exit. | ||
|
|
@@ -57,13 +74,15 @@ export function brewInstalled(name) { | |
| * Install a Homebrew formula or cask. Returns true on success. | ||
| */ | ||
| export function brewInstall(name, { cask = false } = {}) { | ||
| brewUpdate(); | ||
| const args = cask ? ["install", "--no-ask", "--cask", name] : ["install", "--no-ask", name]; | ||
| const cmd = `brew ${args.join(" ")}`; | ||
| try { | ||
| execSync(`brew ${args.join(" ")}`, { stdio: "inherit" }); | ||
| execSync(cmd, { stdio: "inherit" }); | ||
| return true; | ||
| } catch (error) { | ||
| if (error.signal === "SIGINT" || error.status === 130) { | ||
| throw new ShellCommandError(`brew ${args.join(" ")}`, { | ||
| throw new ShellCommandError(cmd, { | ||
| code: error.status, | ||
| signal: error.signal, | ||
| }); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -47,10 +47,12 @@ describe("shell utilities", () => { | |
|
|
||
| test("installs Homebrew packages without prompting", () => { | ||
| expect(brewInstall("jq")).toBe(true); | ||
| expect(execSync).toHaveBeenCalledWith("env -u HOMEBREW_ASK brew update", { stdio: "inherit" }); | ||
| expect(execSync).toHaveBeenCalledWith("brew install --no-ask jq", { stdio: "inherit" }); | ||
|
|
||
| expect(brewInstall("ghostty", { cask: true })).toBe(true); | ||
| expect(execSync).toHaveBeenCalledWith("brew install --no-ask --cask ghostty", { stdio: "inherit" }); | ||
| expect(execSync.mock.calls.filter(([command]) => command.includes("brew update"))).toHaveLength(1); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 由于 在当前测试中,第一个 为了保证测试的隔离性,建议在
|
||
| }); | ||
|
|
||
| test("propagates Ctrl-C from Homebrew installs", () => { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
在成功执行
brew update并安装 Zsh 后,建议调用setHomebrewUpdated(true)。这样可以确保后续通过
brewInstall安装其他软件时,不会再次触发冗余且缓慢的brew update,从而显著提升整体安装效率。