codekingpro/portable-devtools
114k
1from __future__ import annotations2 3import logging4import os5import platform6import sys7import tempfile8 9IMPLEMENTATION = platform.python_implementation()10IS_PYPY = IMPLEMENTATION == "PyPy"11IS_CPYTHON = IMPLEMENTATION == "CPython"12IS_WIN = sys.platform == "win32"13IS_MAC_ARM64 = sys.platform == "darwin" and platform.machine() == "arm64"14ROOT = os.path.realpath(os.path.join(os.path.abspath(__file__), os.path.pardir, os.path.pardir))15IS_ZIPAPP = os.path.isfile(ROOT)16_CAN_SYMLINK = _FS_CASE_SENSITIVE = _CFG_DIR = _DATA_DIR = None17 18 19def fs_is_case_sensitive():20 global _FS_CASE_SENSITIVE # noqa: PLW060321 22 if _FS_CASE_SENSITIVE is None:23 with tempfile.NamedTemporaryFile(prefix="TmP") as tmp_file:24 _FS_CASE_SENSITIVE = not os.path.exists(tmp_file.name.lower())25 logging.debug("filesystem is %scase-sensitive", "" if _FS_CASE_SENSITIVE else "not ")26 return _FS_CASE_SENSITIVE27 28 29def fs_supports_symlink():30 global _CAN_SYMLINK # noqa: PLW060331 32 if _CAN_SYMLINK is None:33 can = False34 if hasattr(os, "symlink"):35 if IS_WIN:36 with tempfile.NamedTemporaryFile(prefix="TmP") as tmp_file:37 temp_dir = os.path.dirname(tmp_file.name)38 dest = os.path.join(temp_dir, f"{tmp_file.name}-{'b'}")39 try:40 os.symlink(tmp_file.name, dest)41 can = True42 except (OSError, NotImplementedError):43 pass44 logging.debug("symlink on filesystem does%s work", "" if can else " not")45 else:46 can = True47 _CAN_SYMLINK = can48 return _CAN_SYMLINK49 50 51def fs_path_id(path: str) -> str:52 return path.casefold() if fs_is_case_sensitive() else path53 54 55__all__ = (56 "IS_CPYTHON",57 "IS_MAC_ARM64",58 "IS_PYPY",59 "IS_WIN",60 "IS_ZIPAPP",61 "ROOT",62 "fs_is_case_sensitive",63 "fs_path_id",64 "fs_supports_symlink",65)66 