fix(core): spawn shell non-interactively without sourcing rc files
ShellSelect.args() ran zsh/bash with -l and explicitly sourced .zshrc/.bashrc, loading user functions and aliases that can shadow builtins and return non-zero exit codes, breaking && chains. Match the old tool behavior: plain non-login non-interactive shell -c command with cwd passed via spawn options.
This commit is contained in:
parent
381d67572e
commit
01edae4a7f
4 changed files with 8 additions and 37 deletions
|
|
@ -159,7 +159,7 @@ export const layer = Layer.effect(
|
||||||
const cwd = input.cwd ?? location.directory
|
const cwd = input.cwd ?? location.directory
|
||||||
const configShell = Config.latest(yield* config.entries(), "shell")
|
const configShell = Config.latest(yield* config.entries(), "shell")
|
||||||
const shell = ShellSelect.preferred(configShell)
|
const shell = ShellSelect.preferred(configShell)
|
||||||
const args = ShellSelect.args(shell, input.command, cwd)
|
const args = ShellSelect.args(shell, input.command)
|
||||||
const file = path.join(outputDir, `${id}.out`)
|
const file = path.join(outputDir, `${id}.out`)
|
||||||
const env = {
|
const env = {
|
||||||
...process.env,
|
...process.env,
|
||||||
|
|
|
||||||
|
|
@ -163,37 +163,10 @@ function info(file: string): Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function args(file: string, command: string, cwd: string) {
|
export function args(file: string, command: string) {
|
||||||
const n = name(file)
|
const n = name(file)
|
||||||
if (n === "nu" || n === "fish") return ["-c", command]
|
if (n === "nu" || n === "fish") return ["-c", command]
|
||||||
if (n === "zsh") {
|
if (n === "zsh" || n === "bash") return ["-c", command]
|
||||||
return [
|
|
||||||
"-l",
|
|
||||||
"-c",
|
|
||||||
`
|
|
||||||
[[ -f ~/.zshenv ]] && source ~/.zshenv >/dev/null 2>&1 || true
|
|
||||||
[[ -f "\${ZDOTDIR:-$HOME}/.zshrc" ]] && source "\${ZDOTDIR:-$HOME}/.zshrc" >/dev/null 2>&1 || true
|
|
||||||
cd -- "$1"
|
|
||||||
eval ${JSON.stringify(command)}
|
|
||||||
`,
|
|
||||||
"opencode",
|
|
||||||
cwd,
|
|
||||||
]
|
|
||||||
}
|
|
||||||
if (n === "bash") {
|
|
||||||
return [
|
|
||||||
"-l",
|
|
||||||
"-c",
|
|
||||||
`
|
|
||||||
shopt -s expand_aliases
|
|
||||||
[[ -f ~/.bashrc ]] && source ~/.bashrc >/dev/null 2>&1 || true
|
|
||||||
cd -- "$1"
|
|
||||||
eval ${JSON.stringify(command)}
|
|
||||||
`,
|
|
||||||
"opencode",
|
|
||||||
cwd,
|
|
||||||
]
|
|
||||||
}
|
|
||||||
if (n === "cmd") return ["/c", command]
|
if (n === "cmd") return ["/c", command]
|
||||||
if (ps(file)) return ["-NoProfile", "-Command", command]
|
if (ps(file)) return ["-NoProfile", "-Command", command]
|
||||||
return ["-c", command]
|
return ["-c", command]
|
||||||
|
|
|
||||||
|
|
@ -55,12 +55,10 @@ describe("shell", () => {
|
||||||
})
|
})
|
||||||
|
|
||||||
test("builds command args per shell family", () => {
|
test("builds command args per shell family", () => {
|
||||||
expect(ShellSelect.args("/bin/sh", "echo hi", "/tmp")).toEqual(["-c", "echo hi"])
|
expect(ShellSelect.args("/bin/sh", "echo hi")).toEqual(["-c", "echo hi"])
|
||||||
expect(ShellSelect.args("/usr/bin/fish", "echo hi", "/tmp")).toEqual(["-c", "echo hi"])
|
expect(ShellSelect.args("/usr/bin/fish", "echo hi")).toEqual(["-c", "echo hi"])
|
||||||
const zsh = ShellSelect.args("/bin/zsh", "echo hi", "/tmp")
|
expect(ShellSelect.args("/bin/zsh", "echo hi")).toEqual(["-c", "echo hi"])
|
||||||
expect(zsh[0]).toBe("-l")
|
expect(ShellSelect.args("/bin/bash", "echo hi")).toEqual(["-c", "echo hi"])
|
||||||
expect(zsh[1]).toBe("-c")
|
|
||||||
expect(zsh.at(-1)).toBe("/tmp")
|
|
||||||
})
|
})
|
||||||
|
|
||||||
if (process.platform === "win32") {
|
if (process.platform === "win32") {
|
||||||
|
|
|
||||||
|
|
@ -521,7 +521,7 @@ export const layer = Layer.effect(
|
||||||
|
|
||||||
const cfg = yield* config.get()
|
const cfg = yield* config.get()
|
||||||
const sh = ShellSelect.preferred(cfg.shell)
|
const sh = ShellSelect.preferred(cfg.shell)
|
||||||
const args = ShellSelect.args(sh, input.command, cwd)
|
const args = ShellSelect.args(sh, input.command)
|
||||||
let output = ""
|
let output = ""
|
||||||
let aborted = false
|
let aborted = false
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue