mirror of
https://github.com/thatmattlove/hyperglass.git
synced 2026-01-17 08:48:05 +00:00
76 lines
2.4 KiB
Python
76 lines
2.4 KiB
Python
"""Helpers for hyperglass docs."""
|
|
|
|
# Standard Library
|
|
import json
|
|
import typing as t
|
|
from pathlib import Path
|
|
from importlib.util import module_from_spec, spec_from_file_location
|
|
|
|
|
|
class PlatformSpec(t.TypedDict):
|
|
"""Definition for each platform."""
|
|
|
|
name: str
|
|
keys: t.Tuple[str, ...]
|
|
native: bool
|
|
|
|
|
|
def get_directive_variable(path: Path, variable: str) -> t.Any:
|
|
"""Read a variable from a directive file."""
|
|
|
|
name, _ = path.name.split(".")
|
|
spec = spec_from_file_location(name, location=path)
|
|
module = module_from_spec(spec)
|
|
spec.loader.exec_module(module)
|
|
|
|
exports = tuple(getattr(module, e, None) for e in dir(module) if e == variable)
|
|
if len(exports) < 1:
|
|
raise RuntimeError(f"'{path!s} exists', but it is missing a variable named '{variable}'")
|
|
|
|
value, *_ = exports
|
|
return value
|
|
|
|
|
|
def create_platform_list() -> str:
|
|
"""Create a list of platforms as a JSON file for use by the docs."""
|
|
# Third Party
|
|
from netmiko.ssh_dispatcher import CLASS_MAPPER # type: ignore
|
|
|
|
project_root = Path(__file__).parent.parent.parent
|
|
|
|
dir_ = project_root / "docs"
|
|
file_ = dir_ / "platforms.json"
|
|
|
|
builtin_directives = project_root / "hyperglass" / "defaults" / "directives"
|
|
|
|
platforms: t.Tuple[PlatformSpec] = ()
|
|
|
|
keys = []
|
|
|
|
for path in builtin_directives.iterdir():
|
|
if not path.name.startswith("_"):
|
|
name = get_directive_variable(path, "NAME")
|
|
if not isinstance(name, str):
|
|
raise RuntimeError("'NAME' variable is missing or invalid in '{!s}'".format(path))
|
|
_platforms = get_directive_variable(path, "PLATFORMS")
|
|
if not isinstance(_platforms, t.Tuple, t.List):
|
|
raise RuntimeError(
|
|
"'PLATFORMS' variable is missing or invalid in '{!s}'".format(path)
|
|
)
|
|
spec: PlatformSpec = {"name": name, "keys": _platforms, "native": True}
|
|
platforms += (spec,)
|
|
keys = [*keys, *_platforms]
|
|
|
|
for key in CLASS_MAPPER.keys():
|
|
if key not in keys:
|
|
spec: PlatformSpec = {"name": "", "keys": (key,), "native": False}
|
|
platforms += (spec,)
|
|
|
|
sorted_platforms = list(platforms)
|
|
sorted_platforms.sort(key=lambda x: x["keys"][0])
|
|
sorted_platforms.sort(key=lambda x: not x["native"])
|
|
|
|
with file_.open("w+") as opened_file:
|
|
json.dump(sorted_platforms, opened_file)
|
|
|
|
return f"Wrote platforms to {file_!s}"
|