From f51e34b67476723ebbf2f3b163ee33232e14b4b9 Mon Sep 17 00:00:00 2001 From: Jules Date: Fri, 15 Jul 2022 11:23:45 +0200 Subject: [PATCH] Initial commit. --- .pre-commit-config.yaml | 91 ++++++++++++++++++ clickusagemd.py | 71 ++++++++++++++ poetry.lock | 203 ++++++++++++++++++++++++++++++++++++++++ pyproject.toml | 20 ++++ 4 files changed, 385 insertions(+) create mode 100644 .pre-commit-config.yaml create mode 100755 clickusagemd.py create mode 100644 poetry.lock create mode 100644 pyproject.toml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..f4a2a9b --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,91 @@ +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.3.0 + hooks: + # python + - id: check-ast + - id: check-builtin-literals + - id: check-docstring-first + - id: debug-statements + - id: fix-encoding-pragma + args: [--remove] + + # text + - id: check-executables-have-shebangs + - id: check-merge-conflict + - id: check-shebang-scripts-are-executable + - id: detect-private-key + - id: end-of-file-fixer + - id: fix-byte-order-marker + - id: mixed-line-ending + args: [--fix=lf] + - id: trailing-whitespace + + # json + - id: check-json + + # toml + - id: check-toml + + # yaml + - id: check-yaml + + # python + - repo: https://github.com/pre-commit/mirrors-isort + rev: v5.10.1 + hooks: + - id: isort + args: [--profile, black] + - repo: https://github.com/pre-commit/mirrors-mypy + rev: v0.961 + hooks: + - id: mypy + additional_dependencies: [types-all] + - repo: https://github.com/pre-commit/pygrep-hooks + rev: v1.9.0 + hooks: + - id: python-check-blanket-noqa + - id: python-check-blanket-type-ignore + - id: python-no-eval + - id: python-use-type-annotations + - repo: https://github.com/asottile/dead + rev: v1.5.0 + hooks: + - id: dead + args: [--exclude, ups/schemas/.*] + - repo: https://github.com/asottile/pyupgrade + rev: v2.34.0 + hooks: + - id: pyupgrade + args: [--py38-plus] + - repo: https://github.com/psf/black/ + rev: 22.6.0 + hooks: + - id: black + language_version: python3.10 + - repo: https://github.com/PyCQA/bandit + rev: 1.7.4 + hooks: + - id: bandit + args: [--severity-level, medium] + - repo: https://github.com/PyCQA/flake8 + rev: 4.0.1 + hooks: + - id: flake8 + additional_dependencies: [flake8-typing-imports==1.12.0] + args: [--max-line-length, '100'] + + # toml + - repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks + rev: v2.3.0 + hooks: + - id: pretty-format-toml + args: [--autofix] + files: pyproject.toml + + # yaml + - repo: https://github.com/jumanjihouse/pre-commit-hook-yamlfmt + rev: 0.2.1 + hooks: + - id: yamlfmt + args: [--mapping, '2', --sequence, '4', --offset, '2', --width, '100', --implicit_start] diff --git a/clickusagemd.py b/clickusagemd.py new file mode 100755 index 0000000..466ab27 --- /dev/null +++ b/clickusagemd.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python + +import importlib +from typing import Iterator + +import click +import toml + + +def iter_commands( + module_name: str, + 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: + yield f"{'#'*depth} {cliobj.name}" + + for name in cliobj.commands: + yield from iter_commands( + module_name, cmd_chain + [name], cliobj.commands[name], depth=depth + 1 + ) + else: + ctx = click.get_current_context() + cmd = f"{module_name} {' '.join(cmd_chain)}" + help_message = cliobj.get_help(ctx).replace(ctx.command_path, cmd) + + if cliobj.name == "cli": + cmd_title = "Default Command Line" + else: + cmd_title = cliobj.name + + yield f"{'#'*(depth)} {cmd_title}\n```\n{help_message}\n```\n" + + +def generate_usage_md(script: str): + assert ":" in script + module, cliobj = script.split(":") + if "." in module: + module_name = module.split(".")[0] + else: + module_name = module + + mod = importlib.import_module(module) + cli = getattr(mod, cliobj) + + with open("USAGE.md", "wt") as fd: + print(f"# {module_name.capitalize()} - Command Usage Overview", file=fd) + for command in iter_commands(module_name, [], cli): + print(command, file=fd) + + +@click.command() +@click.argument("poetry_project_file", type=click.File()) +@click.pass_context +def cli(ctx, poetry_project_file): + contents = toml.loads(poetry_project_file.read()) + try: + scripts = contents["tool"]["poetry"]["scripts"] + for script in scripts.values(): + generate_usage_md(script) + except KeyError: + click.echo("[ERROR] File does not contain 'tool.poetry.scripts' definitions.") + ctx.exit(1) + + +if __name__ == "__main__": + cli() diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 0000000..5d77205 --- /dev/null +++ b/poetry.lock @@ -0,0 +1,203 @@ +[[package]] +name = "asttokens" +version = "2.0.5" +description = "Annotate AST trees with source code positions" +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +six = "*" + +[package.extras] +test = ["astroid", "pytest"] + +[[package]] +name = "cfgv" +version = "3.3.1" +description = "Validate configuration and produce human readable error messages." +category = "dev" +optional = false +python-versions = ">=3.6.1" + +[[package]] +name = "click" +version = "8.1.3" +description = "Composable command line interface toolkit" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[[package]] +name = "colorama" +version = "0.4.5" +description = "Cross-platform colored terminal text." +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[[package]] +name = "distlib" +version = "0.3.4" +description = "Distribution utilities" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "executing" +version = "0.8.3" +description = "Get the currently executing AST node of a frame, and other information" +category = "dev" +optional = false +python-versions = "*" + +[[package]] +name = "filelock" +version = "3.7.1" +description = "A platform independent file lock." +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.extras] +docs = ["furo (>=2021.8.17b43)", "sphinx (>=4.1)", "sphinx-autodoc-typehints (>=1.12)"] +testing = ["covdefaults (>=1.2.0)", "coverage (>=4)", "pytest (>=4)", "pytest-cov", "pytest-timeout (>=1.4.2)"] + +[[package]] +name = "icecream" +version = "2.1.2" +description = "Never use print() to debug again; inspect variables, expressions, and program execution with a single, simple function call." +category = "dev" +optional = false +python-versions = "*" + +[package.dependencies] +asttokens = ">=2.0.1" +colorama = ">=0.3.9" +executing = ">=0.3.1" +pygments = ">=2.2.0" + +[[package]] +name = "identify" +version = "2.5.1" +description = "File identification library for Python" +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.extras] +license = ["ukkonen"] + +[[package]] +name = "nodeenv" +version = "1.7.0" +description = "Node.js virtual environment builder" +category = "dev" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" + +[[package]] +name = "platformdirs" +version = "2.5.2" +description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.extras] +docs = ["furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)", "sphinx (>=4)"] +test = ["appdirs (==1.4.4)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)", "pytest (>=6)"] + +[[package]] +name = "pre-commit" +version = "2.20.0" +description = "A framework for managing and maintaining multi-language pre-commit hooks." +category = "dev" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +cfgv = ">=2.0.0" +identify = ">=1.0.0" +nodeenv = ">=0.11.1" +pyyaml = ">=5.1" +toml = "*" +virtualenv = ">=20.0.8" + +[[package]] +name = "pygments" +version = "2.12.0" +description = "Pygments is a syntax highlighting package written in Python." +category = "dev" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "pyyaml" +version = "6.0" +description = "YAML parser and emitter for Python" +category = "dev" +optional = false +python-versions = ">=3.6" + +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" + +[[package]] +name = "toml" +version = "0.10.2" +description = "Python Library for Tom's Obvious, Minimal Language" +category = "dev" +optional = false +python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" + +[[package]] +name = "virtualenv" +version = "20.15.1" +description = "Virtual Python Environment builder" +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" + +[package.dependencies] +distlib = ">=0.3.1,<1" +filelock = ">=3.2,<4" +platformdirs = ">=2,<3" +six = ">=1.9.0,<2" + +[package.extras] +docs = ["proselint (>=0.10.2)", "sphinx (>=3)", "sphinx-argparse (>=0.2.5)", "sphinx-rtd-theme (>=0.4.3)", "towncrier (>=21.3)"] +testing = ["coverage (>=4)", "coverage-enable-subprocess (>=1)", "flaky (>=3)", "pytest (>=4)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.1)", "pytest-mock (>=2)", "pytest-randomly (>=1)", "pytest-timeout (>=1)", "packaging (>=20.0)"] + +[metadata] +lock-version = "1.1" +python-versions = "^3.10" +content-hash = "84c8c86d4babe9a74088ea483f90699b35c06213b972b36977ba81e87386a30a" + +[metadata.files] +asttokens = [] +cfgv = [] +click = [] +colorama = [] +distlib = [] +executing = [] +filelock = [] +icecream = [] +identify = [] +nodeenv = [] +platformdirs = [] +pre-commit = [] +pygments = [] +pyyaml = [] +six = [] +toml = [] +virtualenv = [] diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..eb93939 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,20 @@ +[build-system] +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" + +[tool.poetry] +name = "clickusagemd" +version = "0.1.0" +description = "" +authors = ["Jules "] + +[tool.poetry.dependencies] +python = "^3.10" +click = "^8.1.3" + +[tool.poetry.dev-dependencies] +pre-commit = "^2.20.0" +icecream = "^2.1.2" + +[tool.poetry.scripts] +clickusagemd = "clickusagemd:cli"