f
This commit is contained in:
167
docs/BOOTSTRAP_TROUBLESHOOTING.md
Normal file
167
docs/BOOTSTRAP_TROUBLESHOOTING.md
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
# Bootstrap Installation Troubleshooting Guide
|
||||||
|
|
||||||
|
## Problem on "Other Computer"
|
||||||
|
|
||||||
|
When running `bootstrap.py` on another machine, the installation completes successfully with messages about creating `mm.ps1` and `mm.bat`, but the `mm` command is not recognized when executed.
|
||||||
|
|
||||||
|
**Root Cause:** Windows terminal sessions cache the PATH environment variable. When registry changes are made, existing terminal sessions don't automatically reload the new PATH. The shim files are created correctly, but they're not discoverable until PATH is reloaded.
|
||||||
|
|
||||||
|
## Solution
|
||||||
|
|
||||||
|
### Option 1: Restart Terminal (Easiest)
|
||||||
|
Simply close and reopen your terminal window or PowerShell session. Windows will automatically load the updated PATH from the registry.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# Close the current terminal
|
||||||
|
# Then open a new PowerShell or CMD window
|
||||||
|
mm --help
|
||||||
|
```
|
||||||
|
|
||||||
|
### Option 2: Reload PATH in Current Session (Manual)
|
||||||
|
If you don't want to restart, you can reload the PATH in your current PowerShell session:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
$env:PATH = [Environment]::GetEnvironmentVariable('PATH', 'User') + ';' + [Environment]::GetEnvironmentVariable('PATH', 'Machine')
|
||||||
|
mm --help
|
||||||
|
```
|
||||||
|
|
||||||
|
Note: The bootstrap installation automatically attempts this, but it may not work if PowerShell was launched with a restricted execution policy.
|
||||||
|
|
||||||
|
### Option 3: Manual PATH Reload (PowerShell)
|
||||||
|
```powershell
|
||||||
|
$env:Path = [Environment]::GetEnvironmentVariable('PATH', 'User') + ';' + [Environment]::GetEnvironmentVariable('PATH', 'Machine')
|
||||||
|
mm --help
|
||||||
|
```
|
||||||
|
|
||||||
|
## Diagnostic Command
|
||||||
|
|
||||||
|
To verify the installation and troubleshoot issues:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
python scripts/bootstrap.py --check-install
|
||||||
|
```
|
||||||
|
|
||||||
|
This will check:
|
||||||
|
- ✓ Shim files exist (`mm.ps1` and `mm.bat`)
|
||||||
|
- ✓ Shim files have valid content
|
||||||
|
- ✓ PATH environment variable is configured
|
||||||
|
- ✓ Registry PATH was updated
|
||||||
|
- ✓ Test if `mm` command is accessible
|
||||||
|
|
||||||
|
### Example Output
|
||||||
|
|
||||||
|
```
|
||||||
|
Checking 'mm' command installation...
|
||||||
|
|
||||||
|
Checking for shim files:
|
||||||
|
mm.ps1: ✓ (C:\Users\Admin\bin\mm.ps1)
|
||||||
|
mm.bat: ✓ (C:\Users\Admin\bin\mm.bat)
|
||||||
|
|
||||||
|
Checking PATH environment variable:
|
||||||
|
C:\Users\Admin\bin in current session PATH: ✓
|
||||||
|
C:\Users\Admin\bin in registry PATH: ✓
|
||||||
|
|
||||||
|
Testing 'mm' command...
|
||||||
|
✗ 'mm' command not found in PATH
|
||||||
|
Shims exist but command is not accessible via PATH
|
||||||
|
|
||||||
|
Attempting to call shim directly...
|
||||||
|
✓ Direct shim call works!
|
||||||
|
The shim files are valid and functional.
|
||||||
|
|
||||||
|
⚠️ 'mm' is not in PATH, but the shims are working correctly.
|
||||||
|
Possible causes and fixes:
|
||||||
|
1. Terminal needs restart: Close and reopen your terminal/PowerShell
|
||||||
|
2. PATH reload: Run: . scripts\reload-path.ps1
|
||||||
|
3. Manual PATH: Add C:\Users\Admin\bin to your system PATH manually
|
||||||
|
```
|
||||||
|
|
||||||
|
If the diagnostic shows:
|
||||||
|
- **✓ Direct shim call works!** → Your installation is fine, just reload PATH
|
||||||
|
- **✗ Shim files not found** → Re-run `bootstrap.py` without arguments
|
||||||
|
- **✗ PATH not in registry** → Run bootstrap with `--debug` to see what happened
|
||||||
|
|
||||||
|
## Debug Mode
|
||||||
|
|
||||||
|
For detailed diagnostic output during installation:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
python scripts\bootstrap.py --debug
|
||||||
|
```
|
||||||
|
|
||||||
|
This shows:
|
||||||
|
- Repo path detection
|
||||||
|
- Venv creation status
|
||||||
|
- Shim file creation details
|
||||||
|
- PATH registration results
|
||||||
|
|
||||||
|
## Installation Steps (for "Other Computer")
|
||||||
|
|
||||||
|
1. **Run bootstrap:**
|
||||||
|
```powershell
|
||||||
|
python scripts\bootstrap.py
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Check installation:**
|
||||||
|
```powershell
|
||||||
|
python scripts\bootstrap.py --check-install
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **If 'mm' is not found:**
|
||||||
|
- Close and reopen your terminal (simplest), OR
|
||||||
|
- Reload PATH: `$env:PATH = [Environment]::GetEnvironmentVariable('PATH', 'User') + ';' + [Environment]::GetEnvironmentVariable('PATH', 'Machine')`
|
||||||
|
|
||||||
|
4. **Verify it works:**
|
||||||
|
```powershell
|
||||||
|
mm --help
|
||||||
|
```
|
||||||
|
|
||||||
|
## Shim File Locations
|
||||||
|
|
||||||
|
The installation creates Windows shim files in:
|
||||||
|
- **User bin directory:** `C:\Users\<YourUsername>\bin\`
|
||||||
|
- **Files created:**
|
||||||
|
- `mm.ps1` - PowerShell shim
|
||||||
|
- `mm.bat` - Command Prompt shim
|
||||||
|
|
||||||
|
These files contain the absolute path to your project and venv, so they work from any location.
|
||||||
|
|
||||||
|
## Why This Happens
|
||||||
|
|
||||||
|
On Windows, the PATH environment variable is read from the registry when a terminal session starts. If you change the registry PATH while a terminal is open, that terminal doesn't automatically pick up the change. That's why:
|
||||||
|
|
||||||
|
1. **New terminals work:** They read the updated registry PATH
|
||||||
|
2. **Current terminal doesn't work:** It still has the old PATH
|
||||||
|
3. **Shim files still work:** They can be called directly by absolute path
|
||||||
|
|
||||||
|
This is a Windows OS behavior, not a bug in the installation script.
|
||||||
|
|
||||||
|
## Manual PATH Addition (If Registry Update Fails)
|
||||||
|
|
||||||
|
If for some reason the registry update fails (requires admin rights), you can add the path manually:
|
||||||
|
|
||||||
|
1. Open System Properties:
|
||||||
|
- Press `Win + X`, select "System"
|
||||||
|
- Click "Advanced system settings"
|
||||||
|
|
||||||
|
2. Click "Environment Variables"
|
||||||
|
|
||||||
|
3. Under "User variables," click "New"
|
||||||
|
- Variable name: `PATH`
|
||||||
|
- Variable value: `C:\Users\Admin\bin`
|
||||||
|
|
||||||
|
4. Click OK and close all terminals
|
||||||
|
|
||||||
|
5. Open a new terminal and test `mm --help`
|
||||||
|
|
||||||
|
## Next Steps
|
||||||
|
|
||||||
|
Once `mm` works:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
mm --help # Show all available commands
|
||||||
|
mm pipeline --help # Get help for specific command
|
||||||
|
mm config --show # Show current configuration
|
||||||
|
```
|
||||||
|
|
||||||
|
For more information, see the main [README](../readme.md).
|
||||||
@@ -43,6 +43,9 @@ Optional flags:
|
|||||||
--no-deno Skip installing the Deno runtime
|
--no-deno Skip installing the Deno runtime
|
||||||
--deno-version Pin a specific Deno version to install (e.g., v1.34.3)
|
--deno-version Pin a specific Deno version to install (e.g., v1.34.3)
|
||||||
--upgrade-pip Upgrade pip, setuptools, and wheel before installing deps
|
--upgrade-pip Upgrade pip, setuptools, and wheel before installing deps
|
||||||
|
--check-install Verify that the 'mm' command was installed correctly
|
||||||
|
--debug Show detailed diagnostic information during installation
|
||||||
|
--quiet Suppress output (used internally by platform scripts)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
@@ -289,6 +292,16 @@ def main() -> int:
|
|||||||
action="store_true",
|
action="store_true",
|
||||||
help="Upgrade pip/setuptools/wheel before installing requirements",
|
help="Upgrade pip/setuptools/wheel before installing requirements",
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--debug",
|
||||||
|
action="store_true",
|
||||||
|
help="Show detailed diagnostic information during installation",
|
||||||
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--check-install",
|
||||||
|
action="store_true",
|
||||||
|
help="Verify that the 'mm' command was installed correctly",
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--uninstall",
|
"--uninstall",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
@@ -528,10 +541,140 @@ def main() -> int:
|
|||||||
if args.uninstall:
|
if args.uninstall:
|
||||||
return _do_uninstall()
|
return _do_uninstall()
|
||||||
|
|
||||||
# If invoked without any arguments and not asked to skip delegation, prefer
|
if args.check_install:
|
||||||
# the interactive menu when running in a TTY; otherwise delegate to the
|
# Verify mm command is properly installed
|
||||||
# platform-specific bootstrap helper (non-interactive).
|
home = Path.home()
|
||||||
if len(sys.argv) == 1 and not args.no_delegate:
|
system = platform.system().lower()
|
||||||
|
|
||||||
|
print("Checking 'mm' command installation...")
|
||||||
|
print()
|
||||||
|
|
||||||
|
if system == "windows":
|
||||||
|
user_bin = Path(os.environ.get("USERPROFILE", str(home))) / "bin"
|
||||||
|
mm_ps1 = user_bin / "mm.ps1"
|
||||||
|
mm_bat = user_bin / "mm.bat"
|
||||||
|
|
||||||
|
print(f"Checking for shim files:")
|
||||||
|
print(f" mm.ps1: {'✓' if mm_ps1.exists() else '✗'} ({mm_ps1})")
|
||||||
|
print(f" mm.bat: {'✓' if mm_bat.exists() else '✗'} ({mm_bat})")
|
||||||
|
print()
|
||||||
|
|
||||||
|
if mm_ps1.exists():
|
||||||
|
ps1_content = mm_ps1.read_text(encoding="utf-8")
|
||||||
|
if "$repo" in ps1_content or "$REPO" in ps1_content:
|
||||||
|
print(f" mm.ps1 content looks valid ({len(ps1_content)} bytes)")
|
||||||
|
else:
|
||||||
|
print(f" ⚠️ mm.ps1 content may be corrupted")
|
||||||
|
|
||||||
|
if mm_bat.exists():
|
||||||
|
bat_content = mm_bat.read_text(encoding="utf-8")
|
||||||
|
if "REPO=" in bat_content or "PY=" in bat_content:
|
||||||
|
print(f" mm.bat content looks valid ({len(bat_content)} bytes)")
|
||||||
|
else:
|
||||||
|
print(f" ⚠️ mm.bat content may be corrupted")
|
||||||
|
print()
|
||||||
|
|
||||||
|
# Check PATH
|
||||||
|
path = os.environ.get("PATH", "")
|
||||||
|
user_bin_str = str(user_bin)
|
||||||
|
in_path = user_bin_str in path
|
||||||
|
print(f"Checking PATH environment variable:")
|
||||||
|
print(f" {user_bin_str} in current session PATH: {'✓' if in_path else '✗'}")
|
||||||
|
|
||||||
|
# Check registry
|
||||||
|
try:
|
||||||
|
import winreg
|
||||||
|
reg = winreg.ConnectRegistry(None, winreg.HKEY_CURRENT_USER)
|
||||||
|
key = winreg.OpenKey(reg, "Environment", 0, winreg.KEY_READ)
|
||||||
|
current_path = winreg.QueryValueEx(key, "Path")[0]
|
||||||
|
winreg.CloseKey(key)
|
||||||
|
in_reg = user_bin_str in current_path
|
||||||
|
print(f" {user_bin_str} in registry PATH: {'✓' if in_reg else '✗'}")
|
||||||
|
if not in_reg:
|
||||||
|
print()
|
||||||
|
print("📝 Note: Path is not in registry. It may work in this session but won't persist.")
|
||||||
|
print(f" To fix, run: [Environment]::SetEnvironmentVariable('PATH', '{user_bin_str};' + [Environment]::GetEnvironmentVariable('PATH','User'), 'User')")
|
||||||
|
except Exception as e:
|
||||||
|
print(f" Could not check registry: {e}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
# Test if mm command works
|
||||||
|
print("Testing 'mm' command...")
|
||||||
|
try:
|
||||||
|
result = subprocess.run(["mm", "--help"], capture_output=True, text=True, timeout=5)
|
||||||
|
if result.returncode == 0:
|
||||||
|
print(f" ✓ 'mm --help' works!")
|
||||||
|
print(f" Output (first line): {result.stdout.split(chr(10))[0]}")
|
||||||
|
else:
|
||||||
|
print(f" ✗ 'mm --help' failed with exit code {result.returncode}")
|
||||||
|
if result.stderr:
|
||||||
|
print(f" Error: {result.stderr.strip()}")
|
||||||
|
except FileNotFoundError:
|
||||||
|
# mm not found via PATH, try calling the .ps1 directly
|
||||||
|
print(f" ✗ 'mm' command not found in PATH")
|
||||||
|
print(f" Shims exist but command is not accessible via PATH")
|
||||||
|
print()
|
||||||
|
print("Attempting to call shim directly...")
|
||||||
|
try:
|
||||||
|
result = subprocess.run(
|
||||||
|
["powershell", "-NoProfile", "-Command", f"& '{mm_ps1}' --help"],
|
||||||
|
capture_output=True, text=True, timeout=5
|
||||||
|
)
|
||||||
|
if result.returncode == 0:
|
||||||
|
print(f" ✓ Direct shim call works!")
|
||||||
|
print(f" The shim files are valid and functional.")
|
||||||
|
print()
|
||||||
|
print("⚠️ 'mm' is not in PATH, but the shims are working correctly.")
|
||||||
|
print()
|
||||||
|
print("Possible causes and fixes:")
|
||||||
|
print(f" 1. Terminal needs restart: Close and reopen your terminal/PowerShell")
|
||||||
|
print(f" 2. PATH reload: Run: $env:Path = [Environment]::GetEnvironmentVariable('PATH', 'User') + ';' + [Environment]::GetEnvironmentVariable('PATH', 'Machine')")
|
||||||
|
print(f" 3. Manual PATH: Add C:\\Users\\Admin\\bin to your system PATH manually")
|
||||||
|
else:
|
||||||
|
print(f" ✗ Direct shim call failed")
|
||||||
|
if result.stderr:
|
||||||
|
print(f" Error: {result.stderr.strip()}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f" ✗ Could not test direct shim: {e}")
|
||||||
|
except subprocess.TimeoutExpired:
|
||||||
|
print(f" ✗ 'mm' command timed out")
|
||||||
|
except Exception as e:
|
||||||
|
print(f" ✗ Error testing 'mm': {e}")
|
||||||
|
else:
|
||||||
|
# POSIX (Linux/macOS)
|
||||||
|
user_bin = home / ".local" / "bin"
|
||||||
|
mm_sh = user_bin / "mm"
|
||||||
|
|
||||||
|
print(f"Checking for shim file:")
|
||||||
|
print(f" mm: {'✓' if mm_sh.exists() else '✗'} ({mm_sh})")
|
||||||
|
print()
|
||||||
|
|
||||||
|
path = os.environ.get("PATH", "")
|
||||||
|
user_bin_str = str(user_bin)
|
||||||
|
in_path = user_bin_str in path
|
||||||
|
print(f"Checking PATH environment variable:")
|
||||||
|
print(f" {user_bin_str} in current session PATH: {'✓' if in_path else '✗'}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
# Test if mm command works
|
||||||
|
print("Testing 'mm' command...")
|
||||||
|
try:
|
||||||
|
result = subprocess.run(["mm", "--help"], capture_output=True, text=True, timeout=5)
|
||||||
|
if result.returncode == 0:
|
||||||
|
print(f" ✓ 'mm --help' works!")
|
||||||
|
print(f" Output (first line): {result.stdout.split(chr(10))[0]}")
|
||||||
|
else:
|
||||||
|
print(f" ✗ 'mm --help' failed with exit code {result.returncode}")
|
||||||
|
if result.stderr:
|
||||||
|
print(f" Error: {result.stderr.strip()}")
|
||||||
|
except FileNotFoundError:
|
||||||
|
print(f" ✗ 'mm' command not found in PATH")
|
||||||
|
except Exception as e:
|
||||||
|
print(f" ✗ Error testing 'mm': {e}")
|
||||||
|
|
||||||
|
print()
|
||||||
|
print("✅ Installation check complete!")
|
||||||
|
return 0
|
||||||
if sys.stdin.isatty() and not args.quiet:
|
if sys.stdin.isatty() and not args.quiet:
|
||||||
sel = _interactive_menu()
|
sel = _interactive_menu()
|
||||||
if sel == "install":
|
if sel == "install":
|
||||||
@@ -852,6 +995,12 @@ if (Test-Path (Join-Path $repo 'CLI.py')) {
|
|||||||
user_bin = Path(os.environ.get("USERPROFILE", str(home))) / "bin"
|
user_bin = Path(os.environ.get("USERPROFILE", str(home))) / "bin"
|
||||||
user_bin.mkdir(parents=True, exist_ok=True)
|
user_bin.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
# Validate repo path
|
||||||
|
if not (repo / ".venv").exists():
|
||||||
|
print(f"WARNING: venv not found at {repo}/.venv - mm command may not work", file=sys.stderr)
|
||||||
|
if not (repo / "scripts").exists():
|
||||||
|
print(f"WARNING: scripts folder not found at {repo}/scripts - mm command may not work", file=sys.stderr)
|
||||||
|
|
||||||
# Convert repo path to string with proper escaping
|
# Convert repo path to string with proper escaping
|
||||||
repo_str = str(repo).replace("\\", "\\\\")
|
repo_str = str(repo).replace("\\", "\\\\")
|
||||||
|
|
||||||
@@ -877,6 +1026,8 @@ if (Test-Path (Join-Path $repo 'CLI.py')) {
|
|||||||
bak = mm_ps1.with_suffix(f".bak{int(time.time())}")
|
bak = mm_ps1.with_suffix(f".bak{int(time.time())}")
|
||||||
mm_ps1.replace(bak)
|
mm_ps1.replace(bak)
|
||||||
mm_ps1.write_text(ps1_text, encoding="utf-8")
|
mm_ps1.write_text(ps1_text, encoding="utf-8")
|
||||||
|
if not args.quiet:
|
||||||
|
print(f"Created {mm_ps1}")
|
||||||
|
|
||||||
# Write mm.bat (CMD shim for better compatibility)
|
# Write mm.bat (CMD shim for better compatibility)
|
||||||
mm_bat = user_bin / "mm.bat"
|
mm_bat = user_bin / "mm.bat"
|
||||||
@@ -905,6 +1056,20 @@ if (Test-Path (Join-Path $repo 'CLI.py')) {
|
|||||||
mm_bat.replace(bak)
|
mm_bat.replace(bak)
|
||||||
mm_bat.write_text(bat_text, encoding="utf-8")
|
mm_bat.write_text(bat_text, encoding="utf-8")
|
||||||
|
|
||||||
|
# Validate that shim files were created correctly
|
||||||
|
ps1_ok = mm_ps1.exists() and len(mm_ps1.read_text(encoding="utf-8")) > 0
|
||||||
|
bat_ok = mm_bat.exists() and len(mm_bat.read_text(encoding="utf-8")) > 0
|
||||||
|
|
||||||
|
if not ps1_ok or not bat_ok:
|
||||||
|
raise RuntimeError(f"Failed to create shim files: mm.ps1={ps1_ok}, mm.bat={bat_ok}")
|
||||||
|
|
||||||
|
if args.debug:
|
||||||
|
print(f"DEBUG: Created mm.ps1 ({len(ps1_text)} bytes)")
|
||||||
|
print(f"DEBUG: Created mm.bat ({len(bat_text)} bytes)")
|
||||||
|
print(f"DEBUG: Repo path embedded in shims: {repo}")
|
||||||
|
print(f"DEBUG: Venv location: {repo}/.venv")
|
||||||
|
print(f"DEBUG: Shim directory: {user_bin}")
|
||||||
|
|
||||||
# Add user_bin to PATH for current and future sessions
|
# Add user_bin to PATH for current and future sessions
|
||||||
str_bin = str(user_bin)
|
str_bin = str(user_bin)
|
||||||
cur_path = os.environ.get("PATH", "")
|
cur_path = os.environ.get("PATH", "")
|
||||||
@@ -912,8 +1077,6 @@ if (Test-Path (Join-Path $repo 'CLI.py')) {
|
|||||||
# Update current session PATH if not already present
|
# Update current session PATH if not already present
|
||||||
if str_bin not in cur_path:
|
if str_bin not in cur_path:
|
||||||
os.environ["PATH"] = str_bin + ";" + cur_path
|
os.environ["PATH"] = str_bin + ";" + cur_path
|
||||||
if not args.quiet:
|
|
||||||
print(f"Added {user_bin} to current session PATH")
|
|
||||||
|
|
||||||
# Persist to user's Windows registry PATH for future sessions
|
# Persist to user's Windows registry PATH for future sessions
|
||||||
try:
|
try:
|
||||||
@@ -922,21 +1085,51 @@ if (Test-Path (Join-Path $repo 'CLI.py')) {
|
|||||||
"$cur = [Environment]::GetEnvironmentVariable('PATH','User');"
|
"$cur = [Environment]::GetEnvironmentVariable('PATH','User');"
|
||||||
"if ($cur -notlike \"*$bin*\") {{"
|
"if ($cur -notlike \"*$bin*\") {{"
|
||||||
"[Environment]::SetEnvironmentVariable('PATH', ($bin + ';' + ($cur -ne $null ? $cur : '')), 'User');"
|
"[Environment]::SetEnvironmentVariable('PATH', ($bin + ';' + ($cur -ne $null ? $cur : '')), 'User');"
|
||||||
"Write-Host 'Added {bin} to User PATH in registry' -ForegroundColor Green"
|
|
||||||
"}}"
|
"}}"
|
||||||
).format(bin=str_bin.replace("\\", "\\\\"))
|
).format(bin=str_bin.replace("\\", "\\\\"))
|
||||||
subprocess.run(
|
result = subprocess.run(
|
||||||
["powershell",
|
["powershell",
|
||||||
"-NoProfile",
|
"-NoProfile",
|
||||||
"-Command",
|
"-Command",
|
||||||
ps_cmd],
|
ps_cmd],
|
||||||
check=False,
|
check=False,
|
||||||
stdout=subprocess.DEVNULL,
|
capture_output=True,
|
||||||
stderr=subprocess.DEVNULL
|
text=True
|
||||||
|
)
|
||||||
|
if args.debug and result.stderr:
|
||||||
|
print(f"DEBUG: PowerShell output: {result.stderr}")
|
||||||
|
|
||||||
|
# Also reload PATH in current session for immediate availability
|
||||||
|
reload_cmd = (
|
||||||
|
"$env:PATH = [Environment]::GetEnvironmentVariable('PATH', 'User') + ';' + [Environment]::GetEnvironmentVariable('PATH', 'Machine')"
|
||||||
|
)
|
||||||
|
subprocess.run(
|
||||||
|
["powershell",
|
||||||
|
"-NoProfile",
|
||||||
|
"-Command",
|
||||||
|
reload_cmd],
|
||||||
|
check=False,
|
||||||
|
capture_output=True,
|
||||||
|
text=True
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
if args.debug:
|
||||||
|
print(f"DEBUG: Could not persist PATH to registry: {e}", file=sys.stderr)
|
||||||
|
|
||||||
if not args.quiet:
|
if not args.quiet:
|
||||||
print(f"Note: Could not persist PATH to registry (this is non-critical): {e}", file=sys.stderr)
|
print(f"Installed global launchers to: {user_bin}")
|
||||||
|
print(f"✓ mm.ps1 (PowerShell)")
|
||||||
|
print(f"✓ mm.bat (Command Prompt)")
|
||||||
|
print()
|
||||||
|
print("You can now run 'mm' from any shell to start the application.")
|
||||||
|
print()
|
||||||
|
print("📝 If 'mm' is not recognized, you may need to:")
|
||||||
|
print(f" 1. Restart your terminal")
|
||||||
|
print(f" 2. Or add '{user_bin}' manually to your PATH")
|
||||||
|
print()
|
||||||
|
print("🐛 Debug mode: Set MM_DEBUG=1 environment variable for detailed info:")
|
||||||
|
print(" PowerShell: $env:MM_DEBUG=1; mm --help")
|
||||||
|
print(" CMD: set MM_DEBUG=1 && mm --help")
|
||||||
|
|
||||||
if not args.quiet:
|
if not args.quiet:
|
||||||
print(f"\nInstalled global launchers to: {user_bin}")
|
print(f"\nInstalled global launchers to: {user_bin}")
|
||||||
@@ -1052,7 +1245,18 @@ if (Test-Path (Join-Path $repo 'CLI.py')) {
|
|||||||
|
|
||||||
_install_user_shims(repo_root)
|
_install_user_shims(repo_root)
|
||||||
|
|
||||||
print("Setup complete.")
|
if not args.quiet:
|
||||||
|
print("\n✅ Setup complete!")
|
||||||
|
print()
|
||||||
|
print("The 'mm' command should now work from any terminal.")
|
||||||
|
print()
|
||||||
|
print("Verify the installation:")
|
||||||
|
print(" python scripts/bootstrap.py --check-install")
|
||||||
|
print()
|
||||||
|
print("Then run the app:")
|
||||||
|
print(" mm --help")
|
||||||
|
print()
|
||||||
|
print("💡 If 'mm' is not recognized, close and reopen your terminal.")
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
except subprocess.CalledProcessError as exc:
|
except subprocess.CalledProcessError as exc:
|
||||||
|
|||||||
Reference in New Issue
Block a user