Files
wehub-resource-sync 4b6817381b
CI (OpenClaw E2E) / openclaw test (push) Has been cancelled
CI / coverage-report (push) Has been cancelled
CI / test-kubernetes (push) Has been cancelled
CI / should-run-thorough (push) Has been cancelled
CI / test-thorough (cloudwatch-demo) (push) Has been cancelled
CI / test-thorough (flink-ecs) (push) Has been cancelled
CI / test-thorough (upstream-lambda) (push) Has been cancelled
CI / test-thorough (prefect-ecs-fargate) (push) Has been cancelled
Release / build-binaries (zip, opensre.exe, onefile, windows-latest, windows-x64) (push) Has been cancelled
Benchmark image — build + push to ECR (any adapter) / build + push (push) Has been cancelled
CI / quality (ubuntu-latest) (push) Has been cancelled
CI / test (tools-runtime) (push) Has been cancelled
CI / test (e2e-general) (push) Has been cancelled
CI / test (cli-runtime) (push) Has been cancelled
CI / test (e2e-provider-and-openclaw) (push) Has been cancelled
CI / test (integrations-and-misc) (push) Has been cancelled
Release / verify (push) Has been cancelled
Release / build-python-dist (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-15-intel, darwin-x64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-latest, darwin-arm64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04, linux-x64) (push) Has been cancelled
Release / publish-release (push) Has been cancelled
Release / publish-main-release (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-checks (no-LLM) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-live shard ${{ matrix.shard_index }} (push) Has been cancelled
Release / prepare (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04-arm, linux-arm64) (push) Has been cancelled
Synthetic Deterministic Tests / Synthetic offline (deterministic) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:10:45 +08:00

166 lines
4.3 KiB
Python

from __future__ import annotations
import shutil
import subprocess
import sys
from pathlib import Path
from config.constants.paths import OPENSRE_HOME_DIR
def _is_windows() -> bool:
return sys.platform == "win32"
def _is_binary_install() -> bool:
return bool(getattr(sys, "frozen", False))
def _remove_path(p: Path) -> tuple[bool, str | None]:
if not p.exists() and not p.is_symlink():
return True, None
try:
if p.is_dir():
shutil.rmtree(p)
else:
p.unlink()
return True, None
except OSError as exc:
return False, str(exc)
def _pip_uninstall() -> int:
result = subprocess.run(
[sys.executable, "-m", "pip", "uninstall", "--yes", "opensre"],
check=False,
capture_output=True,
)
return result.returncode
def _data_dirs() -> list[Path]:
return [
OPENSRE_HOME_DIR,
Path.home() / ".config" / "opensre",
]
def _is_onedir_binary(exe_path: Path) -> bool:
return exe_path.parent.name == ".opensre-app" and (exe_path.parent / "_internal").is_dir()
def _launcher_for_binary(exe_path: Path) -> Path | None:
launcher = shutil.which("opensre")
if not launcher:
return None
launcher_path = Path(launcher)
try:
if launcher_path.resolve() == exe_path.resolve():
return launcher_path
except OSError:
return None
return None
def _binary_install_paths(exe_path: Path | None = None) -> list[Path]:
exe = exe_path or Path(sys.executable)
paths: list[Path] = []
if launcher := _launcher_for_binary(exe):
paths.append(launcher)
if _is_onedir_binary(exe):
paths.append(exe.parent)
else:
paths.append(exe)
deduped: list[Path] = []
seen: set[str] = set()
for path in paths:
key = str(path)
if key in seen:
continue
seen.add(key)
deduped.append(path)
return deduped
def run_uninstall(*, yes: bool = False) -> int:
dirs = _data_dirs()
binary = _is_binary_install()
binary_paths = _binary_install_paths() if binary else []
print()
print(" The following will be permanently deleted:")
print()
for d in dirs:
tag = "found" if d.exists() else "not found"
print(f" {d} ({tag})")
if binary:
for path in binary_paths:
print(f" {path} (binary)")
else:
print(" pip package: opensre")
print()
if not yes:
try:
import questionary
confirmed = questionary.confirm(
" Uninstall opensre from this machine?", default=False
).ask()
except (EOFError, KeyboardInterrupt):
print("\n Aborted.")
return 1
if not confirmed:
print(" Cancelled.")
return 0
print()
any_error = False
for d in dirs:
if not d.exists():
print(f" skipped {d} (not found)")
continue
ok, err = _remove_path(d)
if ok:
print(f" deleted {d}")
else:
print(f" error {d}: {err}", file=sys.stderr)
any_error = True
if binary:
for path in binary_paths:
ok, err = _remove_path(path)
if ok:
print(f" deleted {path}")
else:
print(f" error {path}: {err}", file=sys.stderr)
any_error = True
else:
print(" running pip uninstall opensre")
rc = _pip_uninstall()
if rc == 0:
print(" deleted pip package opensre")
else:
print(f" error pip uninstall failed (exit {rc})", file=sys.stderr)
if _is_windows():
hint = "pip uninstall opensre"
else:
hint = "pip uninstall opensre (or: pipx uninstall opensre)"
print(f" retry manually: {hint}", file=sys.stderr)
any_error = True
print()
if any_error:
print(" Uninstall finished with errors. See above for details.", file=sys.stderr)
return 1
print(" opensre has been uninstalled.")
print()
print(" Your config and data have been removed.")
print(" To reinstall: curl -fsSL https://install.opensre.com | bash")
return 0