Last active
June 4, 2025 10:42
-
-
Save konstruktoid/29facb031454ffd7257cd9534fe5831a to your computer and use it in GitHub Desktop.
Skeleton Ansible argument spec generator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# ruff: noqa: T201 | |
"""Print a skeleton Ansible argument_specs.yml file.""" | |
import os | |
from pathlib import Path | |
import yaml | |
def find_yaml_files(directory: str) -> list[str]: | |
"""Find all yaml files in the given directory and its subdirectories.""" | |
yaml_files = [] | |
for root, _dirs, files in os.walk(directory): | |
for file in files: | |
if file.endswith((".yaml", ".yml")): | |
yaml_files.append(os.path.join(root, file)) # noqa: PTH118, PERF401 | |
return yaml_files | |
def parse_yaml_file(file_path: str) -> dict: | |
"""Parse a yaml file and return the data.""" | |
with Path.open(file_path) as file: | |
return yaml.safe_load(file) | |
def extract_arguments(data: dict, prefix: str = "") -> dict: | |
"""Extract arguments from the yaml data.""" | |
arguments = {} | |
if isinstance(data, dict): | |
for key, value in data.items(): | |
new_prefix = f"{prefix}.{key}" if prefix else key | |
if isinstance(value, dict): | |
arguments.update(extract_arguments(value, new_prefix)) | |
else: | |
arguments[new_prefix] = value | |
return arguments | |
def read_author_from_meta() -> str: | |
"""Read the author from the meta/main.yml file.""" | |
meta_file = "meta/main.yml" | |
with Path.open(meta_file) as file: | |
data = yaml.safe_load(file) | |
return data.get("galaxy_info", {}).get("author", "unknown") | |
def read_role_name_from_meta() -> str: | |
"""Read the role name from the meta/main.yml file.""" | |
meta_file = "meta/main.yml" | |
with Path.open(meta_file) as file: | |
data = yaml.safe_load(file) | |
return data.get("galaxy_info", {}).get("role_name", "unknown") | |
def read_description_from_meta() -> str: | |
"""Read the description from the meta/main.yml file.""" | |
meta_file = "meta/main.yml" | |
with Path.open(meta_file) as file: | |
data = yaml.safe_load(file) | |
unknown_desc = ( | |
f"This is the main entrypoint for the C({read_role_name_from_meta()}) role." | |
) | |
return data.get("galaxy_info", {}).get("description", unknown_desc) | |
def generate_argspec(yaml_files: list[str]) -> dict: | |
"""Generate a list of arguments and their default values from the yaml files.""" | |
all_arguments = {} | |
for yaml_file in yaml_files: | |
data = parse_yaml_file(yaml_file) | |
arguments = extract_arguments(data) | |
all_arguments.update(arguments) | |
return all_arguments | |
def main() -> None: | |
"""Print generated output.""" | |
directory = "defaults" | |
yaml_files = find_yaml_files(directory) | |
all_arguments = generate_argspec(yaml_files) | |
author = read_author_from_meta() | |
description = read_description_from_meta() | |
header = f"""argument_specs: | |
main: | |
short_description: {description} | |
description: | |
- {description} | |
author: | |
- {author} | |
options:""" | |
print(header) | |
for arg, value in all_arguments.items(): | |
if type(value).__name__ == "list": | |
entry = f""" {arg}: | |
description: \"{arg} description\" | |
type: \"{type(value).__name__}\" | |
elements: \"str\" | |
default: \"{value}\"""" | |
else: | |
entry = f""" {arg}: | |
description: \"{arg} description\" | |
type: \"{type(value).__name__}\" | |
default: \"{value}\"""" | |
print(entry) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment