diff --git a/docs/cli_documentation.md b/docs/cli_documentation.md new file mode 100644 index 0000000..6ebceec --- /dev/null +++ b/docs/cli_documentation.md @@ -0,0 +1,97 @@ +# Floridayvine CLI Documentation + +This document provides an overview of the Floridayvine CLI application and its commands. + +## Usage + +``` +floridayvine [OPTIONS] COMMAND [ARGS]... +``` + +## Global Options + +- `--help`: Show this message and exit. + +## Commands + +### `sync` + +#### Usage + +``` +floridayvine sync [OPTIONS] [ARGS]... +``` + +#### Options + +This command has no options. + +*This command has no subcommands.* + +For more detailed information, use `floridayvine sync --help`. + +### `version` + +#### Usage + +``` +floridayvine version [OPTIONS] [ARGS]... +``` + +#### Options + +This command has no options. + +*This command has no subcommands.* + +For more detailed information, use `floridayvine version --help`. + +### `database` + +#### Usage + +``` +floridayvine database [OPTIONS] [ARGS]... +``` + +#### Options + +This command has no options. + +*This command has no subcommands.* + +For more detailed information, use `floridayvine database --help`. + +### `floriday` + +#### Usage + +``` +floridayvine floriday [OPTIONS] [ARGS]... +``` + +#### Options + +This command has no options. + +*This command has no subcommands.* + +For more detailed information, use `floridayvine floriday --help`. + +### `minio` + +#### Usage + +``` +floridayvine minio [OPTIONS] [ARGS]... +``` + +#### Options + +This command has no options. + +*This command has no subcommands.* + +For more detailed information, use `floridayvine minio --help`. + +Note: This documentation is automatically generated. Some commands may have additional options or subcommands not captured here. Always use the `--help` option with any command for the most up-to-date and detailed information. diff --git a/makefile b/makefile index 92afdd1..64b53cb 100644 --- a/makefile +++ b/makefile @@ -20,9 +20,10 @@ test-integration: build: python -m build documentation: + python scripts/generate_cli_docs.py printversion: @python -m setuptools_scm -release: +release: documentation @if [ -n "$$(git status --porcelain)" ]; then \ echo "There are uncommitted changes or untracked files"; \ exit 1; \ @@ -35,8 +36,10 @@ release: echo "Local branch is ahead of origin"; \ exit 1; \ fi + @git add docs/cli_documentation.md + @git commit -m "Update CLI documentation for release" @git tag v$$(python -m setuptools_scm --strip-dev) - @git push origin --tags + @git push origin main --tags docker_image: docker build -t ghcr.io/serraict/vine-floriday-adapter:$(VERSION) . docker_push: docker_image diff --git a/scripts/generate_cli_docs.py b/scripts/generate_cli_docs.py new file mode 100644 index 0000000..ff8a457 --- /dev/null +++ b/scripts/generate_cli_docs.py @@ -0,0 +1,138 @@ +import importlib +import inspect +import os +import typer +from typing import Dict, Any, Union + + +def import_commands(): + commands = {} + commands_dir = os.path.join("src", "floridayvine", "commands") + for filename in os.listdir(commands_dir): + if filename.endswith(".py") and not filename.startswith("__"): + module_name = f"floridayvine.commands.{filename[:-3]}" + module = importlib.import_module(module_name) + for name, obj in inspect.getmembers(module): + if isinstance(obj, typer.Typer): + commands[filename[:-3]] = obj + return commands + + +def get_command_help(command: Union[typer.Typer, typer.models.CommandInfo]) -> str: + if isinstance(command, typer.Typer): + return command.info.help if command.info and command.info.help else "" + elif isinstance(command, typer.models.CommandInfo): + return command.help if command.help else "" + return "" + + +def get_subcommands(command: Union[typer.Typer, typer.models.CommandInfo]) -> list: + if isinstance(command, typer.Typer): + return [ + cmd + for cmd in command.registered_commands + if cmd.name and cmd.name != "None" and not cmd.name.startswith("_") + ] + return [] + + +def document_command( + command: Union[typer.Typer, typer.models.CommandInfo], name: str, indent: str = "" +) -> str: + md_content = f"{indent}### `{name}`\n\n" + + help_text = get_command_help(command) + if help_text: + md_content += f"{indent}{help_text}\n\n" + + md_content += f"{indent}#### Usage\n\n" + md_content += f"{indent}```\n" + md_content += f"{indent}floridayvine {name} [OPTIONS] [ARGS]...\n" + md_content += f"{indent}```\n\n" + + # Document options + if isinstance(command, typer.Typer) and command.registered_callback: + md_content += document_options(command.registered_callback, indent) + elif isinstance(command, typer.models.CommandInfo): + md_content += document_options(command, indent) + else: + md_content += f"{indent}#### Options\n\n" + md_content += f"{indent}This command has no options.\n\n" + + subcommands = get_subcommands(command) + if subcommands: + md_content += f"{indent}#### Subcommands\n\n" + for subcommand in subcommands: + subcommand_help = get_command_help(subcommand) + md_content += f"{indent}- `{subcommand.name}`" + if subcommand_help: + md_content += f": {subcommand_help}" + md_content += "\n" + md_content += "\n" + + for subcommand in subcommands: + md_content += document_command( + subcommand, f"{name} {subcommand.name}", indent + " " + ) + else: + md_content += f"{indent}*This command has no subcommands.*\n\n" + + md_content += ( + f"{indent}For more detailed information, use `floridayvine {name} --help`.\n\n" + ) + + return md_content + + +def document_options(callback: Any, indent: str = "") -> str: + md_content = f"{indent}#### Options\n\n" + params = callback.params if hasattr(callback, "params") else [] + if not params: + md_content += f"{indent}This command has no options.\n\n" + return md_content + for param in params: + option_str = f"{indent}- `" + if param.opts: + option_str += ", ".join(param.opts) + option_str += "`" + if param.help: + option_str += f": {param.help}" + if param.default is not None and not callable(param.default): + option_str += f" (default: {param.default})" + md_content += f"{option_str}\n" + md_content += "\n" + return md_content + + +def generate_markdown(commands: Dict[str, typer.Typer]) -> str: + md_content = "# Floridayvine CLI Documentation\n\n" + md_content += "This document provides an overview of the Floridayvine CLI application and its commands.\n\n" + + md_content += "## Usage\n\n" + md_content += "```\n" + md_content += "floridayvine [OPTIONS] COMMAND [ARGS]...\n" + md_content += "```\n\n" + + md_content += "## Global Options\n\n" + md_content += "- `--help`: Show this message and exit.\n\n" + + md_content += "## Commands\n\n" + + for command_name, command in commands.items(): + md_content += document_command(command, command_name) + + md_content += "Note: This documentation is automatically generated. Some commands may have additional options or subcommands not captured here. Always use the `--help` option with any command for the most up-to-date and detailed information.\n" + + return md_content + + +def main(): + commands = import_commands() + md_content = generate_markdown(commands) + with open("docs/cli_documentation.md", "w") as f: + f.write(md_content) + print("CLI documentation has been generated and saved to docs/cli_documentation.md") + + +if __name__ == "__main__": + main() diff --git a/work/definition-of-done.md b/work/definition-of-done.md index e4a7bd3..cacfdcb 100644 --- a/work/definition-of-done.md +++ b/work/definition-of-done.md @@ -3,50 +3,70 @@ This document outlines the specific criteria that must be met for a new increment of our application to be considered releasable. It serves as a checklist for developers and AI agents to ensure quality and consistency in our releases. -## Code Quality and Testing +## Code Quality -- [ ] `make quality` command passes, which includes: - - Linting with `flake8` (as configured in .flake8) - - Formatting with `black` - - Running pre-commit hooks - - Running non-integration tests with `pytest` -- [ ] All new functionality has corresponding unit tests in the `tests/` directory -- [ ] GitHub Actions CI workflow passes on the main branch +Our code is well-readable and understandable for humans and AI agents. +For this application, we prefer readability, simplicity, and understandability over performance. +Therefore, we lint with `flake8`, format with `black` and `pytest` before we commit. +Enforced on merges to `main` by [`ci.yml` Github action](.github/workflows/ci.yml). + +Measure: `make quality` + +## Testing + +We validate our code by testing it. +Do not add code without tests. +Fast, local unit tests can be run without any prerequisites. +These tests are part of our CI job. + +Measure: `make test` + +Our integration tests require access to a local database and a Floriday staging environment. +These tests ensure our application works end-to-end. +These tests as of now are not part of our CI job and need to be executed manually before creating a release. + +Measure: `make test-integration` ## Documentation -- [ ] README.md is updated with any new features, dependencies, or usage instructions -- [ ] Any new environment variables are added to both `.env.example` and `mongo/.env.default` -- [ ] `docs/software_architecture.md` is up-to-date with the current architecture and design forces. +Our documentation should help our players to make their next move in the game. +The documentation is accessible to the end users on the command line. -## Functionality +For other players, we rely on manual inspection of the following: -- [ ] All new CLI commands are implemented in `src/floridayvine/commands/` and properly integrated in `src/floridayvine/__main__.py` +- [ ] <../README.md> is updated with any new features, dependencies, or usage instructions +- [ ] Any new environment variables are added to both `.env.example` and `mongo/.env.default` +- [ ] <../docs/software_architecture.md> is up-to-date with the current architecture and design forces. +- [ ] <../docs/cli_documentation.md> is helpful to get an overview of the capabilities of the application. ## Performance and Security +For now, these require manual verification: + - [ ] No sensitive information (API keys, passwords) is hardcoded or logged - [ ] All database queries are optimized and indexed appropriately - [ ] Environment variables are used for all configuration options -## DevOps and Deployment +## DevOps - [ ] `Dockerfile` and `docker-compose.yml` are updated if there are new dependencies or services - [ ] `requirements-dev.txt` is updated with any new development dependencies - [ ] Version number is incremented appropriately - [ ] Configuration files (.flake8, .pre-commit-config.yaml, .vscode/settings.json) are up-to-date and committed to the repository -## Cross-compatibility +## Cross platform compatibility - [ ] Application runs successfully on both development and production environments - [ ] Any new dependencies are added to `pyproject.toml` and are compatible with both Linux and macOS ## Release and Deployment -- [ ] Code and documentation are pushed to the central code repository -- [ ] Release is identified using Semantic Versioning -- [ ] Release is tagged in the repository -- [ ] GitHub Actions package workflow successfully builds and publishes the Docker container to ghcr.io +Running `make release` will take care of: + +- [x] Code and documentation are pushed to the central code repository +- [x] Release is identified using Semantic Versioning +- [x] Release is tagged in the repository +- [x] GitHub Actions package workflow successfully builds and publishes the Docker container to . ## Final Checks @@ -61,8 +81,10 @@ The following items are considered important for future releases but are not cur - [ ] Create a script to automatically check if all environment variables in `.env.example` and `mongo/.env.default` are up to date - [ ] Implement a zipped version of the code for download as part of the release process - [ ] Test the application in both development and production environments. +- [ ] Document our application using specification by example. For now, we use simple `pytest`s. - [ ] Cross platform compatibility - [ ] Linux - [ ] Mac OSX -This Definition of Done should be reviewed and updated periodically to reflect the evolving needs of the project. Items from the "Undone for now" section should be considered for inclusion in the main DoD as they become implemented and integrated into our development process. +This Definition of Done should be reviewed and updated periodically to reflect the evolving needs of the project. +Items from the "Undone for now" section should be considered for inclusion in the main DoD as they become implemented and integrated into our development process.