From 64022f1e777606b94e8d1780402a315af194dd07 Mon Sep 17 00:00:00 2001 From: Krzysztof Boronski Date: Mon, 8 Aug 2022 10:47:53 -0500 Subject: [PATCH] Override user configuation with CLI options. Allow overriding with None Signed-off-by: Krzysztof Boronski --- f4pga/flows/argparser.py | 18 +++++++++++--- f4pga/flows/commands.py | 6 +++-- f4pga/flows/flow.py | 2 +- f4pga/flows/flow_config.py | 50 +++++++++++++++++++++++++++++++++++++- 4 files changed, 68 insertions(+), 8 deletions(-) diff --git a/f4pga/flows/argparser.py b/f4pga/flows/argparser.py index 40cb2de..f7f97c7 100644 --- a/f4pga/flows/argparser.py +++ b/f4pga/flows/argparser.py @@ -116,6 +116,10 @@ def _parse_depval(depvalstr: str): return d +def _null_generator(): + return (item for item in []) + + def _unescaped_matches(regexp: str, s: str, escape_chr="\\"): """ Find all occurences of a pattern in a string that contains escape sequences. @@ -128,17 +132,23 @@ def _unescaped_matches(regexp: str, s: str, escape_chr="\\"): # unescaped characters, but to map the results back to the string containing the # escape sequences, we need to track the offsets by which the characters were # shifted. + + # TODO: This doesn't handle self-escape case offsets = [] offset = 0 for sl in s.split(escape_chr): - if len(sl) <= 1: - continue - noescape = sl[(1 if offset != 0 else 0) :] + noescape = sl[(1 if offset != 0 else 0) :] if len(sl) > 1 else "" for _ in noescape: offsets.append(offset) offset += 2 noescapes += noescape + if len(offsets) == 0: + return _null_generator() + + last_offset = offsets[-1] + offsets.append(last_offset) + iter = re_finditer(regexp, noescapes) for m in iter: @@ -188,7 +198,7 @@ def _parse_cli_value(s: str): """ if len(s) == 0: - return "" + return None # List if s[0] == "[": diff --git a/f4pga/flows/commands.py b/f4pga/flows/commands.py index 0f78563..468bd37 100644 --- a/f4pga/flows/commands.py +++ b/f4pga/flows/commands.py @@ -44,6 +44,7 @@ from f4pga.flows.flow_config import ( FlowConfig, FlowDefinition, open_project_flow_cfg, + override_prj_flow_cfg_by_cli, verify_platform_name, ) from f4pga.flows.flow import Flow @@ -219,13 +220,14 @@ def cmd_build(args: Namespace): project_flow_cfg = open_project_flow_config(args.flow) elif part_name is not None: project_flow_cfg = ProjectFlowConfig(".temp.flow.json") - project_flow_cfg.flow_cfg = get_cli_flow_config(args, part_name) if part_name is None and project_flow_cfg is not None: part_name = project_flow_cfg.get_default_part() - if project_flow_cfg is None: + if (project_flow_cfg is None) and part_name is None: fatal(-1, "No configuration was provided. Use `--flow`, and/or " "`--part` to configure flow.") + override_prj_flow_cfg_by_cli(project_flow_cfg, get_cli_flow_config(args, part_name)) + flow_cfg = make_flow_config(project_flow_cfg, part_name) if args.info: diff --git a/f4pga/flows/flow.py b/f4pga/flows/flow.py index 811fd10..409d682 100644 --- a/f4pga/flows/flow.py +++ b/f4pga/flows/flow.py @@ -70,7 +70,7 @@ class Flow: self.dep_paths = { n: p for n, p in cfg.get_dependency_overrides().items() - if p_req_exists(p) # and not p_dep_differ(p, f4cache) + if (p is not None) and p_req_exists(p) # and not p_dep_differ(p, f4cache) } if f4cache is not None: for dep in self.dep_paths.values(): diff --git a/f4pga/flows/flow_config.py b/f4pga/flows/flow_config.py index 29ffaf7..f2977f8 100644 --- a/f4pga/flows/flow_config.py +++ b/f4pga/flows/flow_config.py @@ -132,6 +132,54 @@ class ProjectFlowConfig: return platform_ovds +def override_prj_flow_cfg_by_cli(cfg: ProjectFlowConfig, cli_d: "dict[str, dict[str, dict]]"): + for part_name, part_cfg in cli_d.items(): + print(f"OVERRIDING CONFIG FOR {part_name}") + p_cfg = cfg.flow_cfg.get(part_name) + if p_cfg is None: + p_cfg = {} + cfg.flow_cfg[part_name] = p_cfg + cli_p_values = part_cfg.get("values") + cli_p_dependencies = part_cfg.get("dependencies") + p_values = p_cfg.get("values") + p_dependencies = p_cfg.get("dependencies") + if cli_p_values is not None: + if p_values is None: + p_values = {} + part_cfg["values"] = p_values + p_values.update(cli_p_values) + if cli_p_dependencies is not None: + if p_dependencies is None: + p_dependencies = {} + part_cfg["dependencies"] = p_dependencies + p_dependencies.update(cli_p_dependencies) + + for stage_name, cli_stage_cfg in part_cfg.items(): + if _is_kword(stage_name): + continue + + stage_cfg = part_cfg.get(stage_name) + if stage_cfg is None: + stage_cfg = {} + part_cfg[stage_name] = stage_cfg + + stage_values = stage_cfg.get("values") + stage_dependencies = stage_cfg.get("dependencies") + cli_stage_values = cli_stage_cfg.get("values") + cli_stage_dependencies = cli_stage_cfg.get("dependencies") + + if cli_stage_values is not None: + if stage_values is None: + stage_values = {} + stage_cfg["values"] = stage_values + stage_values.update(cli_stage_values) + if cli_stage_dependencies is not None: + if stage_dependencies is None: + stage_dependencies = {} + stage_cfg["dependencies"] = stage_dependencies + stage_dependencies.update(cli_stage_dependencies) + + class FlowConfig: part: str r_env: ResolutionEnv @@ -144,7 +192,7 @@ class FlowConfig: self.stages = platform_def.stages self.part = part - self.dependencies_explicit = deep(lambda p: str(Path(p).resolve()))( + self.dependencies_explicit = deep(lambda p: str(Path(p).resolve()), allow_none=True)( self.r_env.resolve(project_config.get_dependencies_raw(part)) )