Skip to content

Commit

Permalink
Definition of Done improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
serra committed Oct 10, 2024
1 parent 1a58357 commit dcd57b3
Show file tree
Hide file tree
Showing 4 changed files with 282 additions and 22 deletions.
97 changes: 97 additions & 0 deletions docs/cli_documentation.md
Original file line number Diff line number Diff line change
@@ -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.
7 changes: 5 additions & 2 deletions makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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; \
Expand All @@ -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
Expand Down
138 changes: 138 additions & 0 deletions scripts/generate_cli_docs.py
Original file line number Diff line number Diff line change
@@ -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()
62 changes: 42 additions & 20 deletions work/definition-of-done.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 <https://ghcr.io/serraict/vine-floriday-adapter>.

## Final Checks

Expand All @@ -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.

0 comments on commit dcd57b3

Please sign in to comment.