From c9946ecf1eb8cf2b9bc4360cd8a51aa62f40f595 Mon Sep 17 00:00:00 2001 From: Brandon Mayes <5610870+bdmayes@users.noreply.github.com> Date: Sun, 2 Nov 2025 12:26:57 -0500 Subject: [PATCH] fix: Various rclone fixes for cloud sync on Windows (#410) Signed-off-by: Brandon Mayes <5610870+bdmayes@users.noreply.github.com> Signed-off-by: Paul Hernandez <60959+phernandez@users.noreply.github.com> Signed-off-by: phernandez Co-authored-by: Paul Hernandez <60959+phernandez@users.noreply.github.com> Co-authored-by: phernandez --- .../cli/commands/cloud/bisync_commands.py | 5 ++ .../cli/commands/cloud/rclone_installer.py | 53 ++++++++++++++++++- 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/src/basic_memory/cli/commands/cloud/bisync_commands.py b/src/basic_memory/cli/commands/cloud/bisync_commands.py index c7ad9139..2e8a8374 100644 --- a/src/basic_memory/cli/commands/cloud/bisync_commands.py +++ b/src/basic_memory/cli/commands/cloud/bisync_commands.py @@ -1,5 +1,10 @@ """Cloud bisync utility functions for Basic Memory CLI.""" +import asyncio +import platform +import subprocess +import time +from datetime import datetime from pathlib import Path from basic_memory.cli.commands.cloud.api_client import make_api_request diff --git a/src/basic_memory/cli/commands/cloud/rclone_installer.py b/src/basic_memory/cli/commands/cloud/rclone_installer.py index 77cc24ad..bc0850e7 100644 --- a/src/basic_memory/cli/commands/cloud/rclone_installer.py +++ b/src/basic_memory/cli/commands/cloud/rclone_installer.py @@ -1,5 +1,6 @@ """Cross-platform rclone installation utilities.""" +import os import platform import shutil import subprocess @@ -116,7 +117,15 @@ def install_rclone_windows() -> None: if shutil.which("winget"): try: console.print("[blue]Installing rclone via winget...[/blue]") - run_command(["winget", "install", "Rclone.Rclone"]) + run_command( + [ + "winget", + "install", + "Rclone.Rclone", + "--accept-source-agreements", + "--accept-package-agreements", + ] + ) console.print("[green]rclone installed via winget[/green]") return except RcloneInstallError: @@ -165,6 +174,7 @@ def install_rclone(platform_override: Optional[str] = None) -> None: install_rclone_linux() elif platform_name == "windows": install_rclone_windows() + refresh_windows_path() else: raise RcloneInstallError(f"Unsupported platform: {platform_name}") @@ -180,6 +190,47 @@ def install_rclone(platform_override: Optional[str] = None) -> None: raise RcloneInstallError(f"Unexpected error during installation: {e}") from e +def refresh_windows_path() -> None: + """Refresh the Windows PATH environment variable for the current session.""" + if platform.system().lower() != "windows": + return + + # Importing here after performing platform detection. Also note that we have to ignore pylance/pyright + # warnings about winreg attributes so that "errors" don't appear on non-Windows platforms. + import winreg + + user_key_path = r"Environment" + system_key_path = r"System\CurrentControlSet\Control\Session Manager\Environment" + new_path = "" + + # Read user PATH + try: + reg_key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, user_key_path, 0, winreg.KEY_READ) # type: ignore[reportAttributeAccessIssue] + user_path, _ = winreg.QueryValueEx(reg_key, "PATH") # type: ignore[reportAttributeAccessIssue] + winreg.CloseKey(reg_key) # type: ignore[reportAttributeAccessIssue] + except Exception: + user_path = "" + + # Read system PATH + try: + reg_key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, system_key_path, 0, winreg.KEY_READ) # type: ignore[reportAttributeAccessIssue] + system_path, _ = winreg.QueryValueEx(reg_key, "PATH") # type: ignore[reportAttributeAccessIssue] + winreg.CloseKey(reg_key) # type: ignore[reportAttributeAccessIssue] + except Exception: + system_path = "" + + # Merge user and system PATHs (system first, then user) + if system_path and user_path: + new_path = system_path + ";" + user_path + elif system_path: + new_path = system_path + elif user_path: + new_path = user_path + + if new_path: + os.environ["PATH"] = new_path + + def get_rclone_version() -> Optional[str]: """Get the installed rclone version.""" if not is_rclone_installed():