mirror of
https://github.com/openai/codex.git
synced 2026-09-05 15:18:41 +00:00
fix(core): preserve zsh tied path exports with combined flags
Co-authored-by: Codex noreply@openai.com
This commit is contained in:
@@ -342,9 +342,10 @@ export_lines=$(export -p | awk '
|
||||
line=$0
|
||||
name=line
|
||||
sub(/^(export|declare -x|typeset -x) /, "", name)
|
||||
if (name ~ /^-T [A-Za-z_][A-Za-z0-9_]* [A-Za-z_][A-Za-z0-9_]*=/) {
|
||||
# Zsh prints tied parameters like PATH/path as `export -T NAME tied=(...)`.
|
||||
sub(/^-T /, "", name)
|
||||
if (name ~ /^-[A-Za-z]*T[A-Za-z]* [A-Za-z_][A-Za-z0-9_]* [A-Za-z_][A-Za-z0-9_]*=/) {
|
||||
# Zsh prints tied parameters like PATH/path as `export -T NAME tied=(...)`;
|
||||
# the option group may include flags such as `-UT`.
|
||||
sub(/^-[A-Za-z]*T[A-Za-z]* /, "", name)
|
||||
sub(/ .*/, "", name)
|
||||
} else {
|
||||
sub(/=.*/, "", name)
|
||||
|
||||
@@ -189,47 +189,52 @@ fn bash_snapshot_preserves_multiline_exports() -> Result<()> {
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[test]
|
||||
fn zsh_snapshot_preserves_tied_path_export() -> Result<()> {
|
||||
let dir = tempdir()?;
|
||||
let tool_dir = dir.path().join("toolbin");
|
||||
let expected_path = format!("{}:/usr/bin:/bin", tool_dir.display());
|
||||
std::fs::write(
|
||||
dir.path().join(".zshrc"),
|
||||
format!("export PATH='{expected_path}'\n"),
|
||||
)?;
|
||||
fn zsh_snapshot_preserves_tied_path_exports() -> Result<()> {
|
||||
for (zshrc_prefix, expected_export) in [
|
||||
("", "export -T PATH path="),
|
||||
("typeset -U PATH path\n", "export -UT PATH path="),
|
||||
] {
|
||||
let dir = tempdir()?;
|
||||
let tool_dir = dir.path().join("toolbin");
|
||||
let expected_path = format!("{}:/usr/bin:/bin", tool_dir.display());
|
||||
std::fs::write(
|
||||
dir.path().join(".zshrc"),
|
||||
format!("{zshrc_prefix}export PATH='{expected_path}'\n"),
|
||||
)?;
|
||||
|
||||
let output = Command::new("/bin/zsh")
|
||||
.arg("-fc")
|
||||
.arg(zsh_snapshot_script())
|
||||
.env("ZDOTDIR", dir.path())
|
||||
.output()?;
|
||||
assert!(output.status.success());
|
||||
let output = Command::new("/bin/zsh")
|
||||
.arg("-fc")
|
||||
.arg(zsh_snapshot_script())
|
||||
.env("ZDOTDIR", dir.path())
|
||||
.output()?;
|
||||
assert!(output.status.success());
|
||||
|
||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||
assert!(
|
||||
stdout.contains("export -T PATH path="),
|
||||
"snapshot should include zsh tied PATH export; stdout={stdout:?}"
|
||||
);
|
||||
let stdout = String::from_utf8_lossy(&output.stdout);
|
||||
assert!(
|
||||
stdout.contains(expected_export),
|
||||
"snapshot should include {expected_export:?}; stdout={stdout:?}"
|
||||
);
|
||||
|
||||
let snapshot_path = dir.path().join("snapshot.sh");
|
||||
std::fs::write(&snapshot_path, stdout.as_bytes())?;
|
||||
let snapshot_path = dir.path().join("snapshot.sh");
|
||||
std::fs::write(&snapshot_path, stdout.as_bytes())?;
|
||||
|
||||
let validate = Command::new("/bin/zsh")
|
||||
.arg("-fc")
|
||||
.arg("PATH=/should/not/survive; . \"$1\"; print -r -- \"$PATH\"")
|
||||
.arg("zsh")
|
||||
.arg(&snapshot_path)
|
||||
.output()?;
|
||||
assert!(
|
||||
validate.status.success(),
|
||||
"snapshot validation failed: {}",
|
||||
String::from_utf8_lossy(&validate.stderr)
|
||||
);
|
||||
let validate = Command::new("/bin/zsh")
|
||||
.arg("-fc")
|
||||
.arg("PATH=/should/not/survive; . \"$1\"; print -r -- \"$PATH\"")
|
||||
.arg("zsh")
|
||||
.arg(&snapshot_path)
|
||||
.output()?;
|
||||
assert!(
|
||||
validate.status.success(),
|
||||
"snapshot validation failed: {}",
|
||||
String::from_utf8_lossy(&validate.stderr)
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
String::from_utf8_lossy(&validate.stdout).trim(),
|
||||
expected_path
|
||||
);
|
||||
assert_eq!(
|
||||
String::from_utf8_lossy(&validate.stdout).trim(),
|
||||
expected_path
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user