Utility functions to support Merlin CLI command handlers.
This module provides common helper functions used by various CLI commands
in the Merlin application. These utilities focus on parsing and validating
command-line arguments related to specification files and variable overrides,
as well as loading and expanding Merlin YAML specifications.
get_merlin_spec_with_override(args)
Shared command to retrieve a MerlinSpec object
and an expanded filepath.
This function processes parsed command-line interface (CLI) arguments to validate
and expand the specified filepath and any associated variables. It then constructs
and returns a MerlinSpec object based on the
provided specification.
Parameters:
| Name |
Type |
Description |
Default |
args
|
Namespace
|
Parsed CLI arguments containing:
specification: the path to the specification file
variables: optional variable overrides to customize the spec.
|
required
|
Returns:
| Name | Type |
Description |
spec |
MerlinSpec
|
An instance of the
MerlinSpec class with the expanded
configuration based on the provided filepath and variables.
|
filepath |
str
|
The expanded filepath derived from the specification.
|
Source code in merlin/cli/utils.py
| def get_merlin_spec_with_override(args: Namespace) -> Tuple[MerlinSpec, str]:
"""
Shared command to retrieve a [`MerlinSpec`][spec.specification.MerlinSpec] object
and an expanded filepath.
This function processes parsed command-line interface (CLI) arguments to validate
and expand the specified filepath and any associated variables. It then constructs
and returns a [`MerlinSpec`][spec.specification.MerlinSpec] object based on the
provided specification.
Args:
args: Parsed CLI arguments containing:\n
- `specification`: the path to the specification file
- `variables`: optional variable overrides to customize the spec.
Returns:
spec (spec.specification.MerlinSpec): An instance of the
[`MerlinSpec`][spec.specification.MerlinSpec] class with the expanded
configuration based on the provided filepath and variables.
filepath: The expanded filepath derived from the specification.
"""
filepath = verify_filepath(args.specification)
variables_dict = parse_override_vars(args.variables)
spec = get_spec_with_expansion(filepath, override_vars=variables_dict)
return spec, filepath
|
parse_override_vars(variables_list)
Parse a list of command-line variables into a dictionary of key-value pairs.
This function takes an optional list of strings following the syntax
"KEY=val" and converts them into a dictionary. It validates the format
of the variables and ensures that keys are valid according to specified rules.
Parameters:
| Name |
Type |
Description |
Default |
variables_list
|
Optional[List[str]]
|
An optional list of strings, where each string should be in the
format "KEY=val", e.g., ["KEY1=value1", "KEY2=42"].
|
required
|
Returns:
| Type |
Description |
Optional[Dict[str, Union[str, int]]]
|
A dictionary where the keys are variable names (str) and the
values are either strings or integers. If variables_list is
None or empty, returns None.
|
Raises:
| Type |
Description |
ValueError
|
If the input format is incorrect, including:
- Missing '=' operator.
- Excess '=' operators in a variable assignment.
- Invalid variable names (must be alphanumeric and underscores).
- Attempting to override reserved variable names.
|
Source code in merlin/cli/utils.py
| def parse_override_vars(
variables_list: Optional[List[str]],
) -> Optional[Dict[str, Union[str, int]]]:
"""
Parse a list of command-line variables into a dictionary of key-value pairs.
This function takes an optional list of strings following the syntax
"KEY=val" and converts them into a dictionary. It validates the format
of the variables and ensures that keys are valid according to specified rules.
Args:
variables_list: An optional list of strings, where each string should be in the
format "KEY=val", e.g., ["KEY1=value1", "KEY2=42"].
Returns:
A dictionary where the keys are variable names (str) and the
values are either strings or integers. If `variables_list` is
None or empty, returns None.
Raises:
ValueError: If the input format is incorrect, including:\n
- Missing '=' operator.
- Excess '=' operators in a variable assignment.
- Invalid variable names (must be alphanumeric and underscores).
- Attempting to override reserved variable names.
"""
if variables_list is None:
return None
LOG.debug(f"Command line override variables = {variables_list}")
result: Dict[str, Union[str, int]] = {}
arg: str
for arg in variables_list:
try:
if "=" not in arg:
raise ValueError("--vars requires '=' operator. See 'merlin run --help' for an example.")
entry: str = arg.split("=")
if len(entry) != 2:
raise ValueError("--vars requires ONE '=' operator (without spaces) per variable assignment.")
key: str = entry[0]
if key is None or key == "" or "$" in key:
raise ValueError("--vars requires valid variable names comprised of alphanumeric characters and underscores.")
if key in RESERVED:
raise ValueError(f"Cannot override reserved word '{key}'! Reserved words are: {RESERVED}.")
val: Union[str, int] = entry[1]
with suppress(ValueError):
int(val)
val = int(val)
result[key] = val
except Exception as excpt:
raise ValueError(
f"{excpt} Bad '--vars' formatting on command line. See 'merlin run --help' for an example."
) from excpt
return result
|