blob: 08b75eeca967586b8c3e5f789ff08ac57f730850 [file] [log] [blame]
# Copyright 2023 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Support for XDG paths.
https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
"""
import functools
import getpass
import logging
import os
from pathlib import Path
import tempfile
from chromite.utils import os_util
@functools.lru_cache(maxsize=None)
def _is_chrome_bot() -> bool:
"""Is the current user/run the 'chrome-bot' builder.
chrome-bot gets permission denied for /home/chrome-bot/.config/chromite.
"""
return "chrome-bot" in (
getpass.getuser(),
os.environ.get("SUDO_USER"),
)
@functools.lru_cache(maxsize=None)
def _get_homedir() -> Path:
"""Find the user's homedir."""
if _is_chrome_bot():
# pylint: disable=consider-using-with
return Path(tempfile.gettempdir())
elif os_util.is_root_user():
# Running as root, fall back to hardcoded, most common answer for the
# user.
try:
return os_util.non_root_home()
except os_util.Error as e:
logging.warning(
"Unable to locate a non-root user home, "
"falling back to root's configs."
)
logging.debug(e)
return Path("~").expanduser()
def _get_path(
subdir: str, xdg_property: str, xdg_optional: bool = False
) -> Path:
"""Get the xdg path.
Args:
subdir: The subdir name if XDG APIs are not available.
xdg_property: The XDG module API to use if available.
xdg_optional: Whether to ignore missing XDG APIs.
"""
if _is_chrome_bot() or os_util.is_root_user():
return _get_homedir() / subdir
try:
import xdg.BaseDirectory
attr = getattr(xdg.BaseDirectory, xdg_property, None)
if attr:
return Path(attr)
elif not xdg_optional:
raise AttributeError(
f"xdg.BaseDirectory.{xdg_property} does not exist; "
"is your pyxdg old?"
)
except ImportError:
pass
return _get_homedir() / subdir
def _get_cache_home() -> Path:
"""The $XDG_CACHE_HOME."""
# pyxdg has always supported this API.
return _get_path(".cache", "xdg_cache_home")
def _get_config_home() -> Path:
"""The $XDG_CONFIG_HOME."""
# pyxdg has always supported this API.
return _get_path(".config", "xdg_config_home")
def _get_state_home() -> Path:
"""The $XDG_STATE_HOME."""
# pyxdg introduced xdg_state_home in 0.28 in Jun 2022.
return _get_path(".local/state", "xdg_state_home", xdg_optional=True)
# The base directory relative to which user-specific non-essential data files
# should be stored.
CACHE_HOME = _get_cache_home()
# The base directory relative to which user-specific configuration files should
# be stored.
CONFIG_HOME = _get_config_home()
# The base directory relative to which user-specific state files should be
# stored.
STATE_HOME = _get_state_home()