fix(cli): widen Windows .bat wrapper fix to custom-name alias path
The profile alias --name path in main.py rewrote the wrapper with a hardcoded #!/bin/sh script right after create_wrapper_script(), clobbering the .bat on Windows and reintroducing the exact bug for custom aliases. create_wrapper_script() now takes an optional target so the alias file is named after the alias while the -p content references the profile — one platform-aware code path, no post-hoc rewrite.
This commit is contained in:
@ -10562,11 +10562,10 @@ def cmd_profile(args):
|
||||
if collision:
|
||||
print(f"Error: {collision}")
|
||||
sys.exit(1)
|
||||
wrapper_path = create_wrapper_script(alias_name)
|
||||
wrapper_path = create_wrapper_script(
|
||||
alias_name, target=name if custom_name else None
|
||||
)
|
||||
if wrapper_path:
|
||||
# If custom name, write the profile name into the wrapper
|
||||
if custom_name:
|
||||
wrapper_path.write_text(f'#!/bin/sh\nexec hermes -p {name} "$@"\n')
|
||||
print(f"✓ Alias created: {wrapper_path}")
|
||||
if not _is_wrapper_dir_in_path():
|
||||
print(f"⚠ {_get_wrapper_dir()} is not in your PATH.")
|
||||
|
||||
@ -359,13 +359,18 @@ def _is_wrapper_dir_in_path() -> bool:
|
||||
return wrapper_dir in os.environ.get("PATH", "").split(os.pathsep)
|
||||
|
||||
|
||||
def create_wrapper_script(name: str) -> Optional[Path]:
|
||||
def create_wrapper_script(name: str, target: Optional[str] = None) -> Optional[Path]:
|
||||
"""Create a shell wrapper script at ~/.local/bin/<name>.
|
||||
|
||||
The wrapper file is named after ``name`` (the alias). The profile it
|
||||
activates is ``target`` if given, otherwise ``name`` — this lets a custom
|
||||
alias name point at a differently-named profile without a post-hoc rewrite.
|
||||
|
||||
On Windows, creates a ``.bat`` file instead of a POSIX shell script.
|
||||
Returns the path to the created wrapper, or None if creation failed.
|
||||
"""
|
||||
canon = normalize_profile_name(name)
|
||||
profile = normalize_profile_name(target) if target else canon
|
||||
wrapper_dir = _get_wrapper_dir()
|
||||
try:
|
||||
wrapper_dir.mkdir(parents=True, exist_ok=True)
|
||||
@ -377,7 +382,7 @@ def create_wrapper_script(name: str) -> Optional[Path]:
|
||||
if is_windows:
|
||||
wrapper_path = wrapper_dir / f"{canon}.bat"
|
||||
try:
|
||||
wrapper_path.write_text(f"@echo off\r\nhermes -p {canon} %*\r\n")
|
||||
wrapper_path.write_text(f"@echo off\r\nhermes -p {profile} %*\r\n")
|
||||
return wrapper_path
|
||||
except OSError as e:
|
||||
print(f"⚠ Could not create wrapper at {wrapper_path}: {e}")
|
||||
@ -385,7 +390,7 @@ def create_wrapper_script(name: str) -> Optional[Path]:
|
||||
else:
|
||||
wrapper_path = wrapper_dir / canon
|
||||
try:
|
||||
wrapper_path.write_text(f'#!/bin/sh\nexec hermes -p {canon} "$@"\n')
|
||||
wrapper_path.write_text(f'#!/bin/sh\nexec hermes -p {profile} "$@"\n')
|
||||
wrapper_path.chmod(wrapper_path.stat().st_mode | stat.S_IEXEC | stat.S_IXGRP | stat.S_IXOTH)
|
||||
return wrapper_path
|
||||
except OSError as e:
|
||||
|
||||
@ -682,6 +682,32 @@ class TestWrapperScript:
|
||||
from hermes_cli.profiles import remove_wrapper_script
|
||||
assert remove_wrapper_script("nonexistent") is False
|
||||
|
||||
def test_custom_alias_target_on_posix(self, profile_env, monkeypatch):
|
||||
# Custom alias name pointing at a differently-named profile: the file
|
||||
# is named after the alias, the -p content references the profile.
|
||||
monkeypatch.setattr("sys.platform", "darwin")
|
||||
from hermes_cli.profiles import create_wrapper_script
|
||||
wrapper = create_wrapper_script("rq", target="redqueen")
|
||||
assert wrapper is not None
|
||||
assert wrapper.name == "rq"
|
||||
content = wrapper.read_text()
|
||||
assert content.startswith("#!/bin/sh")
|
||||
assert "hermes -p redqueen" in content
|
||||
|
||||
def test_custom_alias_target_on_windows(self, profile_env, monkeypatch):
|
||||
# Regression: custom-name aliases must still produce an executable
|
||||
# .bat (not a clobbered #!/bin/sh) on Windows.
|
||||
monkeypatch.setattr("sys.platform", "win32")
|
||||
from hermes_cli.profiles import create_wrapper_script
|
||||
wrapper = create_wrapper_script("rq", target="redqueen")
|
||||
assert wrapper is not None
|
||||
assert wrapper.name == "rq.bat"
|
||||
content = wrapper.read_text()
|
||||
assert "@echo off" in content
|
||||
assert "hermes -p redqueen" in content
|
||||
assert "%*" in content
|
||||
assert "#!/bin/sh" not in content
|
||||
|
||||
|
||||
# ===================================================================
|
||||
# TestRenameProfile
|
||||
|
||||
Reference in New Issue
Block a user