Skip to content

Refactor App Directory Handling for XDG Compliance (data/config/cache) and Backwards Compatibility #12

@thorwhalen

Description

@thorwhalen

Problem: Misalignment of Terminology and Standard

The config2py package currently uses the generic term "App Data Folder" when referring to the primary storage location for user-specific files.

Historically, the core function, config2py.util.get_app_data_folder, defaults to the path specified by Linux/macOS configuration standards: ~/.config/{app_name} (via the deprecated DFLT_APP_DATA_FOLDER which resolves to ~/.config).

This creates two issues:

  1. Semantic Misalignment: Under the widely adopted XDG Base Directory Specification, ~/.config is strictly for user configuration (settings/preferences). Essential user files, application databases, and sessions (which is what config2py is designed to store) belong in the User Data Directory, defaulting to ~/.local/share/.

  2. Monolithic Storage: By collapsing configuration, essential data, and potential cache into a single directory, we prevent users from easily managing backups (you want to back up data and config, but not cache) or using OS-specific tools to clean temporary files.

We need to adopt the full XDG structure to provide clarity and flexibility.

Solution: Implement Full XDG Directory Handling

We will refactor directory handling to correctly distinguish between three core App Folder Kinds (config, data, and cache), respecting the standard XDG environment variables and fallback paths.

Standard Roles and Locations

The following table summarizes the roles and standard locations that config2py will now follow across platforms:

Folder Kind (Role) Purpose Linux/XDG (Default Path) XDG Environment Variable macOS (Traditional Path) Windows (Traditional Path)
config Preferences/Settings. User-editable files (e.g., API keys, theme choice). ~/.config/{app_name} $XDG_CONFIG_HOME ~/Library/Preferences/{app_name} %APPDATA%\{app_name}
data Essential User Data. Portable files and application state (e.g., sessions, databases, save files). ~/.local/share/{app_name} $XDG_DATA_HOME ~/Library/Application Support/{app_name} %LOCALAPPDATA%\{app_name}
cache Non-Essential/Temporary Data. Regeneratable files (e.g., downloaded content, build caches). ~/.cache/{app_name} $XDG_CACHE_HOME ~/Library/Caches/{app_name} %LOCALAPPDATA%\Temp\{app_name}

Refactoring Plan (Backward Compatibility Critical)

Refactoring must be done carefully to prevent breaking existing user installations where configurations/data were incorrectly written to the "config" folder using the old get_app_data_folder function.

Phase 1: New Unified Getter

Introduce a unified function, get_app_folder(folder_kind: AppFolderKind, ...) in config2py.util. This function will correctly implement the three-tier precedence logic for finding any folder kind:

# Precedence Logic for any Folder Kind (e.g., 'data')
def get_app_folder(folder_kind, app_name, custom_env_var, xdg_env_var, default_path):
    # 1. Custom App ENV Variable (Highest priority, user override)
    if os.getenv(custom_env_var):
        return Path(os.getenv(custom_env_var)) / app_name
    # 2. XDG Standard ENV Variable
    elif os.getenv(xdg_env_var):
        return Path(os.getenv(xdg_env_var)) / app_name
    # 3. XDG Default Fallback (Lowest priority)
    else:
        return Path(default_path).expanduser() / app_name

Phase 2: Updating Public Interface (The Critical Change)

The existing, public-facing function get_app_data_folder is currently returning the config path. To honor its name and adhere to the XDG standard:

  1. Rename/Alias Usage: All internal library calls currently using get_app_data_folder for config files (like get_configs_folder_for_app) must be refactored to call a new function, get_app_config_folder.

  2. New get_app_config_folder: This function will be the new public interface for accessing the config folder. It should internally call the new general getter:

    get_app_config_folder(...) -> get_app_folder(folder_kind='config', ...)
  3. Redefine get_app_data_folder: The original get_app_data_folder must be redefined to correctly point to the data folder getter:

    get_app_data_folder(...) -> get_app_folder(folder_kind='data', ...)

    This change allows us to deprecate the misaligned behavior while correctly positioning the function for future use.

Phase 3: Migration Strategy (Addressing Back-Compatibility)

Since existing users will have their "sessions/data" stored under the old config location (~/.config/config2py/configs), we need a robust, yet optional, migration tool (perhaps a function config2py.migrate_old_data()):

  • The library MUST continue to read from the old config location (~/.config/config2py/configs) if data is found there, until the user explicitly migrates.
  • New essential data must be written to the new data location (~/.local/share/config2py/configs).
  • We should advise users to run a one-time migration to move their essential files from the old ~/.config/config2py location to the new ~/.local/share/config2py location.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions