2022-07-18 10:39:14 +02:00
|
|
|
#!/usr/bin/env python3
|
2022-07-15 11:23:45 +02:00
|
|
|
|
|
|
|
import importlib
|
2022-08-11 11:56:06 +02:00
|
|
|
import os
|
2023-12-08 14:42:17 +01:00
|
|
|
from pathlib import Path
|
2022-07-15 11:23:45 +02:00
|
|
|
from typing import Iterator
|
|
|
|
|
|
|
|
import click
|
2022-08-11 11:56:06 +02:00
|
|
|
import git
|
2022-07-15 11:23:45 +02:00
|
|
|
import toml
|
|
|
|
|
2022-07-18 10:31:24 +02:00
|
|
|
from clickusagelib.githook import install_hook, uninstall_hook
|
2022-07-18 10:09:33 +02:00
|
|
|
|
2022-07-15 11:23:45 +02:00
|
|
|
|
2023-12-08 14:42:17 +01:00
|
|
|
def find_git_root(path) -> Path:
|
2022-08-11 11:56:06 +02:00
|
|
|
git_repo = git.Repo(path, search_parent_directories=True)
|
|
|
|
git_root = git_repo.git.rev_parse("--show-toplevel")
|
2023-12-08 14:42:17 +01:00
|
|
|
return Path(git_root)
|
2022-08-11 11:56:06 +02:00
|
|
|
|
|
|
|
|
2022-07-15 11:23:45 +02:00
|
|
|
def iter_commands(
|
2023-08-15 12:10:50 +02:00
|
|
|
tool_name: str,
|
2022-07-15 11:23:45 +02:00
|
|
|
cmd_chain: list,
|
|
|
|
cliobj: click.Group | click.Command,
|
|
|
|
depth: int = 1,
|
|
|
|
) -> Iterator[str]:
|
|
|
|
assert isinstance(cliobj, click.Command) or isinstance(cliobj, click.Group)
|
|
|
|
|
|
|
|
if isinstance(cliobj, click.Group):
|
|
|
|
if depth > 1:
|
2023-12-08 14:39:42 +01:00
|
|
|
yield f"{'#'*depth} {tool_name} {cliobj.name}\n"
|
2022-07-15 11:23:45 +02:00
|
|
|
|
2022-09-08 17:22:23 +02:00
|
|
|
for name in sorted(cliobj.commands):
|
2022-07-15 11:23:45 +02:00
|
|
|
yield from iter_commands(
|
2023-08-15 12:10:50 +02:00
|
|
|
tool_name, cmd_chain + [name], cliobj.commands[name], depth=depth + 1
|
2022-07-15 11:23:45 +02:00
|
|
|
)
|
|
|
|
else:
|
|
|
|
ctx = click.get_current_context()
|
2023-08-15 12:10:50 +02:00
|
|
|
cmd = f"{tool_name} {' '.join(cmd_chain)}"
|
2022-07-15 11:23:45 +02:00
|
|
|
help_message = cliobj.get_help(ctx).replace(ctx.command_path, cmd)
|
|
|
|
|
2023-08-18 15:50:33 +02:00
|
|
|
yield f"{'#'*(depth)} {tool_name} {' '.join(cmd_chain)}\n```\n{help_message}\n```"
|
2022-07-15 11:23:45 +02:00
|
|
|
|
|
|
|
|
2022-07-15 12:37:03 +02:00
|
|
|
def generate_usage_md(script: str, version: str):
|
2023-08-15 12:16:02 +02:00
|
|
|
script_name, module = script
|
|
|
|
assert ":" in module
|
2023-08-15 12:10:50 +02:00
|
|
|
module_name, cliobj = module.split(":")
|
2022-07-15 11:23:45 +02:00
|
|
|
|
2023-08-15 12:10:50 +02:00
|
|
|
mod = importlib.import_module(module_name)
|
2022-07-15 11:23:45 +02:00
|
|
|
cli = getattr(mod, cliobj)
|
|
|
|
|
|
|
|
with open("USAGE.md", "wt") as fd:
|
2023-08-15 13:33:04 +02:00
|
|
|
if "." in module_name:
|
|
|
|
module_name = module_name.split(".")[0]
|
|
|
|
|
2022-07-15 12:37:03 +02:00
|
|
|
print(
|
2023-12-08 14:39:42 +01:00
|
|
|
f"# {module_name.capitalize()} v{version} - {script_name} - Command Usage Overview\n",
|
2023-12-08 14:37:56 +01:00
|
|
|
file=fd,
|
2022-07-15 12:37:03 +02:00
|
|
|
)
|
2023-08-15 12:16:02 +02:00
|
|
|
for command in iter_commands(script_name, [], cli):
|
2022-07-15 11:23:45 +02:00
|
|
|
print(command, file=fd)
|
|
|
|
|
|
|
|
|
2022-07-18 10:09:33 +02:00
|
|
|
@click.group()
|
|
|
|
def cli():
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
@cli.command(help="Generate markdown usage description.")
|
2022-08-11 11:56:06 +02:00
|
|
|
@click.argument(
|
|
|
|
"poetry_project_file",
|
|
|
|
type=click.File(),
|
|
|
|
default=os.path.join(find_git_root(os.getcwd()), "pyproject.toml"),
|
|
|
|
)
|
2022-07-18 10:14:02 +02:00
|
|
|
@click.pass_context
|
2022-07-18 10:09:33 +02:00
|
|
|
def run(ctx, poetry_project_file):
|
2022-07-15 11:23:45 +02:00
|
|
|
contents = toml.loads(poetry_project_file.read())
|
|
|
|
try:
|
2023-08-15 12:10:50 +02:00
|
|
|
scripts = contents["tool"]["poetry"]["scripts"].items()
|
2022-07-15 12:37:03 +02:00
|
|
|
version = contents["tool"]["poetry"]["version"]
|
2023-08-15 12:16:02 +02:00
|
|
|
for script in scripts:
|
2022-07-15 12:37:03 +02:00
|
|
|
generate_usage_md(script, version)
|
2022-07-15 11:23:45 +02:00
|
|
|
except KeyError:
|
|
|
|
click.echo("[ERROR] File does not contain 'tool.poetry.scripts' definitions.")
|
|
|
|
ctx.exit(1)
|
|
|
|
|
|
|
|
|
2022-07-18 10:09:33 +02:00
|
|
|
@cli.command(help="Install clickusagemd as pre-push hook.")
|
|
|
|
def install():
|
2022-08-11 11:56:06 +02:00
|
|
|
install_hook(find_git_root(os.getcwd()))
|
2022-07-18 10:09:33 +02:00
|
|
|
|
|
|
|
|
|
|
|
@cli.command(help="Uninstall clickusagemd pre-push hook.")
|
|
|
|
def uninstall():
|
2022-08-11 11:56:06 +02:00
|
|
|
uninstall_hook(find_git_root(os.getcwd()))
|
2022-07-18 10:09:33 +02:00
|
|
|
|
|
|
|
|
|
|
|
cli.add_command(run)
|
|
|
|
cli.add_command(install)
|
|
|
|
cli.add_command(uninstall)
|
|
|
|
|
|
|
|
|
2022-07-15 11:23:45 +02:00
|
|
|
if __name__ == "__main__":
|
|
|
|
cli()
|