diff --git a/platformio/project/options.py b/platformio/project/options.py index d0a4b0e8e9..42c896ceed 100644 --- a/platformio/project/options.py +++ b/platformio/project/options.py @@ -14,13 +14,16 @@ # pylint: disable=redefined-builtin, too-many-arguments +import logging import os from collections import OrderedDict +from posixpath import expanduser import click from platformio import fs from platformio.compat import IS_WINDOWS +from test_core_dir import PackageException, VCSBaseException class ConfigOption: # pylint: disable=too-many-instance-attributes,too-many-positional-arguments @@ -91,13 +94,29 @@ def validate_dir(path): def get_default_core_dir(): - path = os.path.join(fs.expanduser("~"), ".platformio") + # Default to ~/.platformio + path = os.path.join(expanduser("~"), ".platformio") + + # Handle Windows-specific directory fallback if IS_WINDOWS: win_core_dir = os.path.splitdrive(path)[0] + "\\.platformio" - if os.path.isdir(win_core_dir): - return win_core_dir - return path + # Use Windows root directory only if it exists and is writable + if os.path.isdir(win_core_dir) and os.access(win_core_dir, os.W_OK): + path = win_core_dir + + # Ensure the directory exists, but handle invalid symlink creation + if not os.path.exists(path): + try: + os.makedirs(path, exist_ok=True) + except OSError as e: + logging.error("Library Manager: Installing symlink: %s", path) + raise PackageException(f"Can not create a symbolic link for `{path}`, not a directory") from e + if not os.path.isdir(path): + logging.error("Library Manager: Installing symlink: %s", path) + raise VCSBaseException(f"VCS: Unknown repository type symlink: {path}") + + return path ProjectOptions = OrderedDict( [