Describes the Recipe class and validates recipes using pydantic
dump_model(recipe_file, recipe, readonly=False, force=False)
Dumps recipe to yaml file.
Source code in hpcman/hpcman/software/recipe.py
| @log_call()
def dump_model(recipe_file: Path, recipe: BaseModel, readonly: bool = False, force: bool = False) -> None:
"""Dumps recipe to yaml file."""
writer = YAML(typ="rt", pure=True)
if force and recipe_file.exists() and not os.access(recipe_file, os.W_OK):
recipe_file.chmod(stat.S_IWUSR)
try:
to_yaml_file(recipe_file, recipe, custom_yaml_writer=writer)
except PermissionError:
rprint(f"You do not have permission to over-write {recipe_file.as_posix()}.")
rprint("Use the '--force' option and try again. Also, check your '$USER'")
return None
if readonly:
recipe_file.chmod(mode=0o444)
|
export_and_dump(recipe_dir, recipe)
Makes directory and dumps recipe there
Source code in hpcman/hpcman/software/recipe.py
| @log_call()
def export_and_dump(recipe_dir: Path, recipe: BaseRecipe) -> Path:
"""Makes directory and dumps recipe there"""
new_recipe = Path(recipe_dir / recipe.recipe_name)
new_recipe.mkdir(mode=0o775, exist_ok=True)
dump_model(Path(new_recipe / RECIPE_FN), recipe)
return new_recipe
|
export_model_schema(method)
Exports schema from pydantic model
Source code in hpcman/hpcman/software/recipe.py
| def export_model_schema(method: InstallMethod) -> None:
"""Exports schema from pydantic model"""
if method is InstallMethod.CONDA:
recipe = CondaRecipe
elif method is InstallMethod.PIXI:
recipe = PixiRecipe
elif method is InstallMethod.PIPX:
recipe = PipxRecipe
else:
rprint(f"Method '{method.value}' hasn't been implemented yet.")
exit()
print_json(json.dumps(recipe.model_json_schema()))
|
get_finished_recipe(**kwargs)
Generate proper Recipe Class
Source code in hpcman/hpcman/software/recipe.py
| @log_call()
def get_finished_recipe(**kwargs) -> BaseRecipe:
"""Generate proper Recipe Class"""
method = kwargs.get("method")
if method == InstallMethod.CONDA:
return CondaRecipe(**kwargs)
elif method == InstallMethod.COMPILE:
return BaseRecipe(**kwargs)
elif method == InstallMethod.PIPX:
if "pkgs" in kwargs:
if len(pkgs := kwargs.pop("pkgs", [])) == 1:
kwargs["pkg"] = pkgs[0]
else:
rprint("[red]Pipx recipe only supports one package[/red]")
rprint("Either update your recipe with one pkg and/or specify additional pkgs with --libs.")
exit(1)
return PipxRecipe(**kwargs)
elif method == InstallMethod.PIXI:
if "pkgs" in kwargs:
if len(pkgs := kwargs.pop("pkgs", [])) == 1:
kwargs["pkg"] = pkgs[0]
else:
rprint("[red]Pixi recipe only supports one package[/red]")
rprint("Either update your recipe with one pkg or use the conda install method.")
exit(1)
return PixiRecipe(**kwargs)
else:
rprint(f"[red]Unknown method {method}[/red]")
return BaseRecipe(**kwargs)
|
get_recipe_list(recipe_dir)
Get list of recipe names.
Source code in hpcman/hpcman/software/recipe.py
| def get_recipe_list(recipe_dir: Path) -> List[str]:
"""Get list of recipe names."""
recipes = [x.name for x in recipe_dir.iterdir() if x.is_dir() and Path(x / RECIPE_FN).exists()]
return recipes
|
handle_recipe_errors(e)
Handles recipe errors and prints messages
Source code in hpcman/hpcman/software/recipe.py
| def handle_recipe_errors(e: ValidationError) -> None:
"""Handles recipe errors and prints messages"""
rprint(f"Detected {e.error_count()} validation error(s):")
for error in e.errors():
if (
any(option in error["loc"] for option in ("recipe_name", "name"))
and error["type"] == "string_pattern_mismatch"
):
error["msg"] = "'recipe_name' and 'name' must not contain spaces. Check settings and try again."
rprint(f" => Fields: {error['loc']}")
rprint(f" => {error['msg']} -> type={error['type']}, input_value={error['input']}\n")
rprint("Please provide these values in the hpcrecipe.yaml file or as command-line options and try again.")
exit(1)
|
update_recipe(recipe, **kwargs)
Update recipe with new info
Source code in hpcman/hpcman/software/recipe.py
| @log_call()
def update_recipe(recipe: BaseRecipe, **kwargs) -> BaseRecipe:
"""Update recipe with new info"""
for k, v in kwargs.items():
if hasattr(recipe, k):
setattr(recipe, k, v)
else:
logger.warning(f"Attempting to set option '{k}' which is not present for method '{recipe.method}'.")
return recipe
|