From 437a015e3a36996a6a8c9a429de82e089f9e84cd Mon Sep 17 00:00:00 2001 From: Cedric CHEDALEUX Date: Fri, 28 Mar 2025 17:33:11 +0100 Subject: [PATCH] scripts: gen_config: add support for external profiles When developing locally, we often need to load profiles that are not upstreamed (e.g. not in ./profiles directory). gen-config now supports a list of directories where profiles can be located. Upstream profiles can be loaded along with local profiles by setting GENCONFIG_PROFILE_DIRS="./profiles:/opt/mylocalprofiles". Upstream profiles can even be overriden by local profiles since the last directory takes precedence over previous directories in the list. Implements: PCF-1690 Signed-off-by: Cedric CHEDALEUX --- scripts/gen_config.py | 62 +++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/scripts/gen_config.py b/scripts/gen_config.py index 69ca558f24..8dbabebb89 100755 --- a/scripts/gen_config.py +++ b/scripts/gen_config.py @@ -10,7 +10,7 @@ from subprocess import run from os import getenv sys.stdout = io.TextIOWrapper(open(sys.stdout.fileno(), "wb", 0), write_through=True) -profile_folder = Path(getenv("PROFILES", "./profiles")) +profile_folders = getenv("GENCONFIG_PROFILE_DIRS", "./profiles") def run_cmd(cmd: list): @@ -42,38 +42,42 @@ def usage(code: int = 0): def load_yaml(fname: str, profile: dict): - profile_file = (profile_folder / fname).with_suffix(".yml") + # Allow profile overriding by searching in reverse order + for folder in profile_folders.split(':')[::-1]: + profile_file = (Path(folder) / fname).with_suffix(".yml") + + if not profile_file.is_file(): + continue + + new = yaml.safe_load(profile_file.read_text()) + for n in new: + if n in {"target", "subtarget", "external_target"}: + if profile.get(n): + die(f"Duplicate tag found {n}") + profile.update({n: new.get(n)}) + elif n in {"description"}: + profile["description"].append(new.get(n)) + elif n in {"packages"}: + profile["packages"].extend(new.get(n)) + elif n in {"profiles"}: + profile["profiles"].extend(new.get(n)) + elif n in {"diffconfig"}: + profile["diffconfig"] += new.get(n) + elif n in {"feeds"}: + for f in new.get(n): + if f.get("name", "") == "" or f.get("uri", "") == "": + die(f"Found bad feed {f}") + profile["feeds"][f.get("name")] = f + elif n in {"additional_packages"}: + for f in new.get(n): + if not f.get("feed") or not f.get("packages"): + die(f"Found bad additional_packages {f}") + profile["additional_packages"].extend(new.get(n)) + return profile if not profile_file.is_file(): die(f"Profile {fname} not found") - new = yaml.safe_load(profile_file.read_text()) - for n in new: - if n in {"target", "subtarget", "external_target"}: - if profile.get(n): - die(f"Duplicate tag found {n}") - profile.update({n: new.get(n)}) - elif n in {"description"}: - profile["description"].append(new.get(n)) - elif n in {"packages"}: - profile["packages"].extend(new.get(n)) - elif n in {"profiles"}: - profile["profiles"].extend(new.get(n)) - elif n in {"diffconfig"}: - profile["diffconfig"] += new.get(n) - elif n in {"feeds"}: - for f in new.get(n): - if f.get("name", "") == "" or f.get("uri", "") == "": - die(f"Found bad feed {f}") - profile["feeds"][f.get("name")] = f - elif n in {"additional_packages"}: - for f in new.get(n): - if not f.get("feed") or not f.get("packages"): - die(f"Found bad additional_packages {f}") - profile["additional_packages"].extend(new.get(n)) - - return profile - def extract_sha1_from_revision(revision: str) -> str: """