in src/aaz_dev/command/api/_cmds.py [0:0]
def verify(target):
def verify_resource(model, path):
if "commandGroups" not in model:
return
for grp in model["commandGroups"]:
base_path = os.path.join(path, *grp["name"].split())
if not os.path.exists(base_path):
raise FileNotFoundError(base_path)
for cmd in grp.get("commands", []):
file_path = os.path.join(base_path, f"_{cmd['name']}.md")
if not os.path.isfile(file_path):
raise FileNotFoundError(file_path)
verify_resource(grp, base_path)
def verify_command(file_path):
with open(file_path, "r", encoding="utf-8") as fp:
content = fp.read()
base_path = os.path.dirname(file_path)
curr_grp = " ".join(os.path.relpath(base_path, aaz.commands_folder).split(os.sep))
curr_cmd = os.path.splitext(os.path.basename(file_path))[0][1:]
paths = re.findall(r"]\(([^)]+)\)", content)
for path in paths:
json_path = os.path.join(Config.AAZ_PATH, os.path.splitext(path)[0][1:] + ".json")
json_path = os.path.normpath(json_path)
if not os.path.exists(json_path):
raise Exception(f"{json_path} defined in {file_path} is missing.")
with open(json_path, "r", encoding="utf-8", errors="ignore") as fp:
model = json.load(fp)
try:
verify_resource(model, aaz.commands_folder)
except FileNotFoundError as e:
raise Exception(f"Cannot find {e} defined in {json_path}.")
target = curr_grp
while target:
try:
for grp in model["commandGroups"]:
if target.startswith(grp["name"]):
target = target[len(grp["name"]):].strip()
model = grp
break
except KeyError:
raise Exception(f"{curr_grp} has no corresponding definition in {json_path}.")
commands = model["commands"]
if not any(cmd["name"] == curr_cmd for cmd in commands):
raise Exception(f"There is no {curr_cmd} command info in {json_path}.")
model_set.add(json_path)
model_set = set()
aaz = AAZSpecsManager()
parent = aaz.commands_folder
stack = [os.path.join(parent, target)] if target else [
os.path.join(parent, i)
for i in os.listdir(parent)
if os.path.isdir(os.path.join(parent, i))
]
while stack:
curr_path = stack.pop()
if os.path.isdir(curr_path):
readme_path = os.path.join(curr_path, "readme.md")
if not os.path.exists(readme_path):
raise Exception(f"Missing `readme.md` under {curr_path}.")
with open(readme_path, "r", encoding="utf-8") as fp:
content = fp.read()
matches = re.findall(r"## (.+)\n\n(((?!\n##)[\s\S])+)", content)
for match in matches:
level = match[0]
items = re.findall(r"- \[([^[\]]+)]", match[1])
if level == "Commands":
if len(items) != len(set(items)):
raise Exception(f"{readme_path} has duplicate command names.")
items = set(items)
files = {i for i in os.listdir(curr_path) if os.path.isfile(os.path.join(curr_path, i))}
files.remove("readme.md")
if (cmd_set := set(map(lambda x: x[1:-3], files))) != items: # _<command_name>.md
diff = cmd_set - items or items - cmd_set
raise Exception(f"Command info {diff} doesn't match in {readme_path}.")
for file in files:
verify_command(os.path.join(curr_path, file))
else:
if len(items) != len(set(items)):
raise Exception(f"{readme_path} has duplicate command group names.")
items = set(items)
folders = {i for i in os.listdir(curr_path) if os.path.isdir(os.path.join(curr_path, i))}
if folders != items:
diff = folders - items or items - folders
raise Exception(f"Command group info {diff} doesn't match in {readme_path}.")
for folder in folders:
stack.append(os.path.join(curr_path, folder))
if not target:
for root, _, files in os.walk(aaz.resources_folder):
for file in files:
if not file.endswith(".json") or file.startswith("client"): # support data-plane
continue
file_path = os.path.join(root, file)
if file_path not in model_set:
raise Exception(f"{file_path} is redundant.")