* Rename cmuxterm to cmux across entire codebase - Rename GitHub repos: manaflow-ai/cmuxterm -> manaflow-ai/cmux, manaflow-ai/homebrew-cmuxterm -> manaflow-ai/homebrew-cmux - Rename bundle IDs: com.cmuxterm.app -> com.cmux.app - Rename CLI: CLI/cmuxterm.swift -> CLI/cmux.swift - Rename homebrew submodule: homebrew-cmuxterm -> homebrew-cmux - Update all socket paths: /tmp/cmuxterm*.sock -> /tmp/cmux*.sock - Update all GitHub URLs, DMG names, Sparkle URLs - Update all source files, scripts, tests, docs, CI workflows * Bump version to 1.23.0
102 lines
3.3 KiB
Python
102 lines
3.3 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Regression: if the user's .zshenv changes ZDOTDIR, then .zshrc should be sourced
|
|
from the updated ZDOTDIR (matching vanilla zsh semantics).
|
|
|
|
Why this matters for cmux:
|
|
- cmux sets ZDOTDIR to the app wrapper directory so zsh loads wrapper
|
|
startup files.
|
|
- The wrapper .zshenv temporarily restores ZDOTDIR to the original directory
|
|
while sourcing the user's real .zshenv.
|
|
- Some users set ZDOTDIR in their .zshenv to point to a dotfiles directory that
|
|
contains their real .zshrc (and plugin setup like zsh-autosuggestions).
|
|
|
|
If we clobber that user-chosen ZDOTDIR before sourcing .zshrc, interactive
|
|
startup behavior diverges from Ghostty/vanilla zsh and plugins may not load.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import shutil
|
|
import subprocess
|
|
from pathlib import Path
|
|
|
|
|
|
def main() -> int:
|
|
root = Path(__file__).resolve().parents[1]
|
|
wrapper_dir = root / "Resources" / "shell-integration"
|
|
if not (wrapper_dir / ".zshenv").exists():
|
|
print(f"SKIP: missing wrapper .zshenv at {wrapper_dir}")
|
|
return 0
|
|
|
|
base = Path("/tmp") / f"cmux_zdotdir_user_override_{os.getpid()}"
|
|
try:
|
|
shutil.rmtree(base, ignore_errors=True)
|
|
base.mkdir(parents=True, exist_ok=True)
|
|
|
|
orig = base / "orig"
|
|
alt = base / "alt"
|
|
home = base / "home"
|
|
orig.mkdir(parents=True, exist_ok=True)
|
|
alt.mkdir(parents=True, exist_ok=True)
|
|
home.mkdir(parents=True, exist_ok=True)
|
|
|
|
out_path = base / "sourced.txt"
|
|
|
|
# User .zshenv that redirects ZDOTDIR to an alternate directory.
|
|
# This is a common pattern for dotfiles-managed setups.
|
|
(orig / ".zshenv").write_text(
|
|
f'export ZDOTDIR="{alt}"\n',
|
|
encoding="utf-8",
|
|
)
|
|
|
|
# Two competing .zshrc files to prove which directory was honored.
|
|
(orig / ".zshrc").write_text(
|
|
f'echo "orig" > "{out_path}"\n',
|
|
encoding="utf-8",
|
|
)
|
|
(alt / ".zshrc").write_text(
|
|
f'echo "alt" > "{out_path}"\n',
|
|
encoding="utf-8",
|
|
)
|
|
|
|
env = dict(os.environ)
|
|
env["HOME"] = str(home)
|
|
env["ZDOTDIR"] = str(wrapper_dir)
|
|
env["CMUX_ZSH_ZDOTDIR"] = str(orig)
|
|
env["CMUX_SHELL_INTEGRATION"] = "0"
|
|
|
|
# Interactive is required for .zshrc; -d disables global rc files for isolation.
|
|
result = subprocess.run(
|
|
["zsh", "-d", "-i", "-c", "true"],
|
|
env=env,
|
|
capture_output=True,
|
|
text=True,
|
|
timeout=5,
|
|
)
|
|
if result.returncode != 0:
|
|
print("FAIL: zsh exited non-zero")
|
|
if result.stderr.strip():
|
|
print(result.stderr.strip())
|
|
return 1
|
|
|
|
if not out_path.exists():
|
|
print("FAIL: no output file created (user .zshrc did not run?)")
|
|
return 1
|
|
|
|
seen = out_path.read_text(encoding="utf-8").strip()
|
|
if seen != "alt":
|
|
print(f"FAIL: expected .zshrc from alt ZDOTDIR, got {seen!r}")
|
|
print(f" orig={orig}")
|
|
print(f" alt={alt}")
|
|
return 1
|
|
|
|
print("PASS: .zshrc sourced from user-updated ZDOTDIR")
|
|
return 0
|
|
finally:
|
|
shutil.rmtree(base, ignore_errors=True)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|