diff --git a/blueprintcompiler/gir.py b/blueprintcompiler/gir.py index 30a5eaa..549a510 100644 --- a/blueprintcompiler/gir.py +++ b/blueprintcompiler/gir.py @@ -25,7 +25,8 @@ from functools import cached_property import gi # type: ignore gi.require_version("GIRepository", "2.0") -from gi.repository import GIRepository # type: ignore +gi.require_version("GLib", "2.0") +from gi.repository import GIRepository, GLib # type: ignore from . import typelib, xml_reader from .errors import CompileError, CompilerBugError @@ -35,19 +36,60 @@ _namespace_cache: T.Dict[str, "Namespace"] = {} _xml_cache = {} _user_search_paths = [] +_typelib_search_paths_initalized: bool = False +_typelib_search_paths: list[str] = [] +_gir_search_paths_initalized: bool = False +_gir_search_paths: list[str] = [] -def add_typelib_search_path(path: str): - _user_search_paths.append(path) +def add_user_typelib_paths(paths: list): + global _user_search_paths + _user_search_paths += paths + + +def collect_typelib_search_paths(): + global _typelib_search_paths_initalized + if _typelib_search_paths_initalized: + return + + global _typelib_search_paths + _typelib_search_paths += [ + *_user_search_paths, + *GIRepository.Repository.get_search_path(), + # fallback paths + "/usr/local/lib/girepository-1.0", + "/usr/local/lib64/girepository-1.0", + "/usr/lib/girepository-1.0", + "/usr/lib64/girepository-1.0", + ] + _typelib_search_paths_initalized = True + + +def collect_gir_search_paths(): + global _gir_search_paths_initalized + if _gir_search_paths_initalized: + return + + base_paths = [ + GLib.get_user_data_dir(), + *GLib.get_system_data_dirs(), + # fallback paths + "/usr/local/share/", + "/usr/share/", + ] + + global _gir_search_paths + _gir_search_paths = [os.path.join(path, "gir-1.0") for path in base_paths] + _gir_search_paths_initalized = True def get_namespace(namespace: str, version: str) -> "Namespace": - search_paths = [*GIRepository.Repository.get_search_path(), *_user_search_paths] + collect_typelib_search_paths() filename = f"{namespace}-{version}.typelib" if filename not in _namespace_cache: - for search_path in search_paths: + for search_path in _typelib_search_paths: path = os.path.join(search_path, filename) if os.path.exists(path) and os.path.isfile(path): @@ -60,7 +102,7 @@ def get_namespace(namespace: str, version: str) -> "Namespace": if filename not in _namespace_cache: raise CompileError( f"Namespace {namespace}-{version} could not be found", - hints=["search path: " + os.pathsep.join(search_paths)], + hints=["search path: " + os.pathsep.join(_typelib_search_paths)], ) return _namespace_cache[filename] @@ -73,12 +115,8 @@ def get_available_namespaces() -> T.List[T.Tuple[str, str]]: if len(_available_namespaces): return _available_namespaces - search_paths: list[str] = [ - *GIRepository.Repository.get_search_path(), - *_user_search_paths, - ] - - for search_path in search_paths: + collect_typelib_search_paths() + for search_path in _typelib_search_paths: try: filenames = os.listdir(search_path) except FileNotFoundError: @@ -93,17 +131,12 @@ def get_available_namespaces() -> T.List[T.Tuple[str, str]]: def get_xml(namespace: str, version: str): - search_paths = [] - - if data_paths := os.environ.get("XDG_DATA_DIRS"): - search_paths += [ - os.path.join(path, "gir-1.0") for path in data_paths.split(os.pathsep) - ] + collect_gir_search_paths() filename = f"{namespace}-{version}.gir" if filename not in _xml_cache: - for search_path in search_paths: + for search_path in _gir_search_paths: path = os.path.join(search_path, filename) if os.path.exists(path) and os.path.isfile(path): @@ -113,7 +146,7 @@ def get_xml(namespace: str, version: str): if filename not in _xml_cache: raise CompileError( f"GObject introspection file '{namespace}-{version}.gir' could not be found", - hints=["search path: " + os.pathsep.join(search_paths)], + hints=["search path: " + os.pathsep.join(_gir_search_paths)], ) return _xml_cache[filename] diff --git a/blueprintcompiler/main.py b/blueprintcompiler/main.py index 1c3a1c6..4d787c8 100644 --- a/blueprintcompiler/main.py +++ b/blueprintcompiler/main.py @@ -27,7 +27,7 @@ import typing as T from . import formatter, interactive_port, parser, tokenizer from .decompiler import decompile_string from .errors import CompileError, CompilerBugError, PrintableError, report_bug -from .gir import add_typelib_search_path +from .gir import add_user_typelib_paths from .lsp import LanguageServer from .outputs import XmlOutput from .utils import Colors @@ -145,8 +145,7 @@ class BlueprintApp: def cmd_compile(self, opts): if opts.typelib_path != None: - for typelib_path in opts.typelib_path: - add_typelib_search_path(typelib_path) + add_user_typelib_paths(opts.typelib_path) data = opts.input.read() try: @@ -166,8 +165,7 @@ class BlueprintApp: def cmd_batch_compile(self, opts): if opts.typelib_path != None: - for typelib_path in opts.typelib_path: - add_typelib_search_path(typelib_path) + add_user_typelib_paths(opts.typelib_path) for file in opts.inputs: data = file.read()