From f01a48e608ef7a07185a2e26ca48b6450f976cf4 Mon Sep 17 00:00:00 2001 From: Felix Moessbauer Date: Thu, 13 Feb 2025 16:10:30 +0100 Subject: [PATCH] kas: lazy resolve top repo path Previously the top repo path was resolved when creating the config. This has proven to be problematic as at this point in time neither the home nor the git / mercurial environment is set up. This makes it impossible to configure e.g. the git safe.dir in the dynamically generated .gitconfig file, as this is created after the Config instantiation but before the init_setup_repos. We now change this by adding support to lazily resolve the top repo path. In case the IncludeHandler is created with top_repo_path=None, this path is resolved on the first access (i.e. on the first invocation of get_top_repo_path). Signed-off-by: Felix Moessbauer --- kas/config.py | 6 +----- kas/includehandler.py | 12 ++++++++++-- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/kas/config.py b/kas/config.py index fbe775ec..b358d527 100644 --- a/kas/config.py +++ b/kas/config.py @@ -51,8 +51,6 @@ def __init__(self, ctx, filename, target=None, task=None): self.filenames = [os.path.abspath(configfile) for configfile in filename.split(':')] - top_repo_path = Repo.get_root_path( - os.path.dirname(self.filenames[0])) repo_paths = [Repo.get_root_path(os.path.dirname(configfile), fallback=False) @@ -65,9 +63,7 @@ def __init__(self, ctx, filename, target=None, task=None): update = ctx.args.update if hasattr(ctx.args, 'update') else False - self.handler = IncludeHandler(self.filenames, - top_repo_path, - not update) + self.handler = IncludeHandler(self.filenames, None, not update) self.repo_dict = self._get_repo_dict() self.repo_cfg_hashes = {} diff --git a/kas/includehandler.py b/kas/includehandler.py index c0ae593c..4ed1b2b2 100644 --- a/kas/includehandler.py +++ b/kas/includehandler.py @@ -130,7 +130,8 @@ class IncludeHandler: current file, or as a dictionary. The dictionary must have a 'file' key containing the path to the include file and a 'repo' key containing the key of the repository. The path is interpreted - relative to the repository root path. + relative to the repository root path. If no top_repo_path is provided, + the path is lazy resolved by the first access of a method. The includes are read and merged from the deepest level upwards. @@ -150,6 +151,13 @@ def get_lockfile(self, kasfile=None): return file.parent / (file.stem + '.lock' + file.suffix) def get_top_repo_path(self): + """ + Lazy resolve top repo path as we might need a prepared environment + """ + from kas.repos import Repo + if not self.top_repo_path: + self.top_repo_path = \ + Repo.get_root_path(os.path.dirname(self.top_files[0])) return self.top_repo_path def get_config(self, repos=None): @@ -304,7 +312,7 @@ def _internal_dict_merge(dest, upd): missing_repos = [] for configfile in self.top_files: cfgs, reps = _internal_include_handler(configfile, - self.top_repo_path) + self.get_top_repo_path()) configs.extend(cfgs) for repo in reps: if repo not in missing_repos: