diff --git a/.github/workflows/github_action.yml b/.github/workflows/github_action.yml index 9f9a48fa..27bac23a 100644 --- a/.github/workflows/github_action.yml +++ b/.github/workflows/github_action.yml @@ -1,8 +1,11 @@ -name: Deploy MkDocs +name: CI/CD Pipeline + on: push: branches: - main + tags: + - 'v*' workflow_dispatch: permissions: @@ -11,7 +14,8 @@ permissions: id-token: write jobs: - build: + build-and-deploy-docs: + if: github.ref == 'refs/heads/main' environment: github-pages runs-on: ubuntu-latest steps: @@ -24,30 +28,95 @@ jobs: with: python-version: '3.11' - - name: Install dependencies + - name: Install Poetry run: | - python -m pip install --upgrade pip - pip install mkdocs-material - pip install mkdocstrings[python] - pip install mkdocs-include-markdown-plugin - pip install mkdocs-mermaid2-plugin - pip install -e . + curl -sSL https://install.python-poetry.org | python3 - --version 1.4.2 + poetry config virtualenvs.create true + poetry config virtualenvs.in-project true + + - name: Install dependencies + run: poetry install + + - name: Test documentation generation + run: poetry run pytest tests/test_doc_generation.py -v - name: Build site - run: mkdocs build + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: poetry run mkdocs build - name: Upload artifact uses: actions/upload-pages-artifact@v3 with: path: site - deploy: - needs: build - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - runs-on: ubuntu-latest - steps: - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v4 + + release: + if: startsWith(github.ref, 'refs/tags/v') + name: Create Release + runs-on: ubuntu-latest + steps: + - name: Get version from tag + id: tag_name + run: | + echo ::set-output name=current_version::${GITHUB_REF#refs/tags/v} + shell: bash + + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Generate Changelog + id: changelog + uses: TriPSs/conventional-changelog-action@v3 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + version-file: './package.json,./pyproject.toml' + git-message: 'chore(release): {version}' + preset: 'angular' + tag-prefix: 'v' + output-file: 'CHANGELOG.md' + release-count: 0 + skip-version-file: true + skip-commit: true + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + + - name: Install Poetry + run: | + curl -sSL https://install.python-poetry.org | python3 - --version 1.4.2 + poetry config virtualenvs.create true + poetry config virtualenvs.in-project true + + - name: Install dependencies + run: poetry install + + - name: Build wheels and source tarball + run: poetry build + + - name: Create GitHub release + id: create_release + uses: softprops/action-gh-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + body: ${{ steps.changelog.outputs.clean_changelog }} + files: | + dist/*.whl + dist/*.tar.gz + CHANGELOG.md + draft: false + prerelease: false + + - name: Publish to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + user: __token__ + password: ${{ secrets.PYPI_API_TOKEN }} + skip_existing: true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index a0c317cb..00000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,85 +0,0 @@ -# Publish package on main branch if it's tagged with 'v*' - -name: release & publish workflow - -# Controls when the action will run. -on: - # Triggers the workflow on push events but only for the master branch - push: - tags: - - 'v*' - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -# A workflow run is made up of one or more jobs that can run sequentially or in parallel -jobs: - # This workflow contains a single job called "release" - release: - name: Create Release - runs-on: ubuntu-20.04 - - strategy: - matrix: - python-versions: [3.11] - - # Steps represent a sequence of tasks that will be executed as part of the job - steps: - - name: Get version from tag - id: tag_name - run: | - echo ::set-output name=current_version::${GITHUB_REF#refs/tags/v} - shell: bash - - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v2 - -# - name: Get Changelog Entry -# id: changelog_reader -# uses: mindsers/changelog-reader-action@v2 -# with: -# validation_depth: 10 -# version: ${{ steps.tag_name.outputs.current_version }} -# path: ./CHANGELOG.md - - - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-versions }} - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install poetry - - - name: build documentation - run: | - poetry install -E doc - poetry run mkdocs build - -# - name: publish documentation -# uses: peaceiris/actions-gh-pages@v3 -# with: -# personal_token: ${{ secrets.PERSONAL_TOKEN }} -# publish_dir: ./site - - - name: Build wheels and source tarball - run: >- - poetry build - - - name: create github release - id: create_release - uses: softprops/action-gh-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} - with: - body: ${{ steps.changelog_reader.outputs.changes }} - files: dist/*.whl - draft: false - prerelease: false - - - name: publish to PyPI - uses: pypa/gh-action-pypi-publish@release/v1 - with: - user: __token__ - password: ${{ secrets.PYPI_API_TOKEN }} - skip_existing: true diff --git a/.gitignore b/.gitignore index 50f3cd0f..150de4cf 100644 --- a/.gitignore +++ b/.gitignore @@ -8,7 +8,6 @@ __pycache__/ *.py[cod] *$py.class - # C extensions *.so diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..cdda72dd --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,139 @@ +# Contributing + +Thanks for your interest in contributing to auto_dev! Please take a moment to review this document **before submitting a pull request.** + +If you want to contribute but aren't sure where to start, you can create a [new discussion](https://github.com/8ball030/auto_dev/discussions) or open an issue. + +## Get started + +This guide is intended to help you get started with contributing. By following these steps, you will understand the development process and workflow. + +- [Fork the repository](#fork-the-repository) +- [Install Python and Poetry](#install-python-and-poetry) +- [Install dependencies](#install-dependencies) +- [Build the project](#build-the-project) +- [Write documentation](#write-documentation) +- [Submit a pull request](#submit-a-pull-request) +- [That's it!](#thats-it) + +
+ +--- + +
+ +## Fork the repository + +To start contributing to the project, [create a fork](https://github.com/8ball030/auto_dev/fork) and clone it to your machine using `git clone`. + +Or, use the [GitHub CLI](https://cli.github.com) to create a fork and clone it in one command: + +```bash +gh repo fork 8ball030/auto_dev --clone +``` + +
+ ↑ back to top +
+ +## Install Python and Poetry + +auto_dev uses [Poetry](https://python-poetry.org/) for dependency management. You need to install **Python 3.9 or higher** and **Poetry < 2.0**. + +You can run the following commands in your terminal to check your local Python and Poetry versions: + +```bash +python --version +poetry --version +``` + +If the versions are not correct or you don't have Python or Poetry installed: + +- Install Python from the [official website](https://python.org) or using [pyenv](https://github.com/pyenv/pyenv) +- Install [Poetry](https://python-poetry.org/docs/#installation) + +
+ ↑ back to top +
+ +## Install dependencies + +In the root directory, run the following command to install the project's dependencies: + +```bash +poetry install +``` + +
+ ↑ back to top +
+ +## Build the project + +In the root directory, run the build command: + +```bash +pip install -e . +``` + +
+ ↑ back to top +
+ + +When adding new features or fixing bugs, it's important to add test cases in /tests to cover any new or updated behavior. + +### Code Quality Checks + +Before pushing your changes, make sure to run the following quality checks: + +```bash +# Format code +make fmt + +# Run linting checks +make lint + +# Run tests +make test +``` + +These commands will ensure your code: +- Follows the project's formatting standards +- Passes all linting rules +- Successfully runs all tests + +Running these checks locally before pushing will help catch issues early and speed up the review process. + +
+ ↑ back to top +
+ +## Write documentation + +auto_dev uses [MkDocs](https://www.mkdocs.org/) with Material theme for the documentation website. To start the docs website in dev mode, run: + +```bash +poetry run mkdocs serve +``` + +
+ ↑ back to top +
+ +## Submit a pull request + +When you're ready to submit a pull request, follow these naming conventions: + +- Pull request titles use the [imperative mood](https://en.wikipedia.org/wiki/Imperative_mood) (e.g., `Add something`, `Fix something`). +- Commit messages should be clear and descriptive. + +When you submit a pull request, GitHub Actions will automatically lint, build, and test your changes. If you see an ❌, it's most likely a problem with your code. Inspect the logs through the GitHub Actions UI to find the cause. + +
+ ↑ back to top +
+ +## That's it! + +If you still have questions, please create a [new issue](https://github.com/8ball030/auto_dev/issues). \ No newline at end of file diff --git a/auto_dev/commands/augment.py b/auto_dev/commands/augment.py index 42bd2443..06dc2f13 100644 --- a/auto_dev/commands/augment.py +++ b/auto_dev/commands/augment.py @@ -227,13 +227,39 @@ def scaffold(self, handlers: list): @cli.group() def augment() -> None: - """Scaffold commands.""" + """Commands for augmenting project components. + + Available Commands: + logging: Add logging handlers to AEA configuration + customs: Augment customs components with OpenAPI3 handlers + """ @augment.command() @click.argument("handlers", nargs=-1, type=click.Choice(HANDLERS.keys()), required=True) def logging(handlers) -> None: - """Augment an aeas logging configuration.""" + """Augment AEA logging configuration with additional handlers. + + Required Parameters: + handlers: One or more handlers to add (console, http, logfile) + + Usage: + Add console handler: + adev augment logging console + + Add multiple handlers: + adev augment logging console http logfile + + Notes + ----- + - Modifies aea-config.yaml logging configuration + - Available handlers: + - console: Rich console output + - http: HTTP POST logging to server + - logfile: File-based logging + - Each handler can be configured via environment variables + + """ logger.info(f"Augmenting logging with handlers: {handlers}") logging_scaffolder = LoggingScaffolder() logging_scaffolder.scaffold(handlers) @@ -285,7 +311,34 @@ def connection(connections) -> None: @click.option("--use-daos", is_flag=True, default=False, help="Augment OpenAPI3 handlers with DAOs") @click.pass_context def customs(ctx, component_type, auto_confirm, use_daos): - """Augment a customs component with OpenAPI3 handlers.""" + """Augment a customs component with OpenAPI3 handlers. + + Required Parameters: + component_type: Type of component to augment (currently only openapi3) + + Optional Parameters: + auto_confirm: Skip confirmation prompts. Default: False + use_daos: Include DAO integration in handlers. Default: False + + Usage: + Basic OpenAPI3 augmentation: + adev augment customs openapi3 + + With DAO integration: + adev augment customs openapi3 --use-daos + + Skip confirmations: + adev augment customs openapi3 --auto-confirm + + Notes + ----- + - Requires component.yaml with api_spec field + - Generates/updates handlers.py with OpenAPI endpoints + - Creates necessary dialogue classes + - Optionally adds DAO integration + - Shows diff before updating existing handlers + + """ logger = ctx.obj["LOGGER"] logger.info(f"Augmenting {component_type} component") verbose = ctx.obj["VERBOSE"] diff --git a/auto_dev/commands/convert.py b/auto_dev/commands/convert.py index 224294e0..f2497305 100644 --- a/auto_dev/commands/convert.py +++ b/auto_dev/commands/convert.py @@ -25,7 +25,19 @@ @cli.group() def convert() -> None: - """Commands to convert between an agent and a service or vice versa.""" + """Commands for converting between component types. + + Available Commands: + agent_to_service: Convert an autonomous agent into a deployable service + + Notes + ----- + - Handles package type conversion while preserving functionality + - Manages dependencies and package structure automatically + - Validates components before conversion + - Supports Open Autonomy service standards + + """ class ConvertCliTool(BasePackageScaffolder): @@ -116,16 +128,44 @@ def check_if_service_exists( def agent_to_service( agent_public_id: PublicId, service_public_id: PublicId, number_of_agents: int = 1, force: bool = False ) -> None: - """Convert an agent to a service. - - Args: - ---- - AGENT_PUBLIC_ID: The public id of the agent. - SERVICE_PUBLIC_ID: The public id of the service to be converted to. - - Example: - ------- - adev convert AGENT_PUBLIC_ID SERVICE_PUBLIC_ID + """Convert an autonomous agent into a deployable service. + + Required Parameters: + agent_public_id: Public ID of the source agent (author/name format) + service_public_id: Public ID for the target service (author/name format) + + Optional Parameters: + number_of_agents: Number of agent instances in the service. Default: 1 + force: Overwrite existing service if it exists. Default: False + + Usage: + Basic conversion: + adev convert agent-to-service author/my_agent author/my_service + + With multiple agent instances: + adev convert agent-to-service author/my_agent author/my_service --number_of_agents 3 + + Force overwrite existing: + adev convert agent-to-service author/my_agent author/my_service --force + + Notes + ----- + - Prerequisites: + - Agent must exist in packages directory + - Agent and service public IDs must be valid + - Package Structure: + - Creates service in packages//services/ + - Follows Open Autonomy service structure + - Configuration: + - Copies agent configuration and dependencies + - Sets up service-specific overrides + - Configures number of agent instances + - Includes network and deployment settings + - Validation: + - Checks agent existence and structure + - Validates service creation path + - Verifies configuration compatibility + - Use --force to overwrite an existing service """ logger.info(f"Converting agent {agent_public_id} to service {service_public_id}.") diff --git a/auto_dev/commands/create.py b/auto_dev/commands/create.py index 63944582..6e9ed9ba 100644 --- a/auto_dev/commands/create.py +++ b/auto_dev/commands/create.py @@ -43,11 +43,30 @@ def get_available_agents() -> list[str]: def create(ctx, public_id: str, template: str, force: bool, publish: bool, clean_up: bool) -> None: """Create a new agent from a template. - :param public_id: the public_id of the agent in the open-autonmy format i.e. `author/agent` - :flag template: the template to use. + Required Parameters: + public_id: The public ID of the agent (author/name format). + template: The template to use for agent creation. - example usage: - `adev create -t eightballer/frontend_agent new_author/new_agent` + Optional Parameters: + force: Force overwrite if agent exists. Default: False + publish: Whether to publish to local registry after creation. Default: True + clean_up: Whether to clean up temporary files after creation. Default: True + + Usage: + Create with default template: + adev create new_author/new_agent + + Create from specific template: + adev create -t eightballer/frontend_agent new_author/new_agent + + Create with force overwrite: + adev create -f new_author/new_agent + + Create without publishing: + adev create --no-publish new_author/new_agent + + Create without cleanup: + adev create --no-clean-up new_author/new_agent """ agent_name = public_id.name verbose = ctx.obj["VERBOSE"] diff --git a/auto_dev/commands/deps.py b/auto_dev/commands/deps.py index 11e99410..a3d683f8 100644 --- a/auto_dev/commands/deps.py +++ b/auto_dev/commands/deps.py @@ -266,8 +266,11 @@ def deps( ctx: click.Context, # noqa ) -> None: """Commands for managing dependencies. - - update: Update both the packages.json from the parent repo and the packages in the child repo. - - generate_gitignore: Generate the gitignore file from the packages.json file. + + Available Commands: + update: Update packages.json from parent repo and packages in child repo. + generate_gitignore: Generate .gitignore entries from packages.json. + verify: Verify dependencies against version set and update if needed. """ @@ -314,9 +317,26 @@ def update( auto_confirm: bool = False, manual: bool = False, ) -> None: - """We update aea packages.json dependencies from a parent repo. - Example usage: - adev deps update -p /path/to/parent/repo -c /path/to/child/repo. + """Update dependencies from parent repo to child repo. + + Required Parameters: + parent_repo: Path to the parent repository containing source packages.json. + child_repo: Path to the child repository to update. + + Optional Parameters: + location: Location of dependencies (local or remote). Default: local + auto_confirm: Skip confirmation prompts. Default: False + manual: Enable manual mode for updates. Default: False + + Usage: + Update with defaults: + adev deps update -p /path/to/parent -c /path/to/child + + Auto-confirm updates: + adev deps update -p /path/to/parent -c /path/to/child --auto-confirm + + Manual mode: + adev deps update -p /path/to/parent -c /path/to/child --manual """ logger = ctx.obj["LOGGER"] logger.info("Updating the dependencies... 📝") @@ -342,9 +362,20 @@ def update( def generate_gitignore( ctx: click.Context, ) -> None: - """We generate the gitignore file from the packages.json file - Example usage: - adev deps generate_gitignore. + """Generate .gitignore entries from packages.json. + + Reads the packages.json file and adds any third-party package paths + to the .gitignore file if they're not already present. + + Usage: + adev deps generate-gitignore + + Notes + ----- + - Only adds new entries, doesn't remove existing ones + - Focuses on third-party packages from packages.json + - Appends entries to existing .gitignore file + """ package_dict = get_package_json(repo=Path()) third_party_packages = package_dict.get("third_party", {}) @@ -589,12 +620,52 @@ def verify( ctx: click.Context, auto_approve: bool = False, ) -> None: - """Verify the packages.json file. - - Requires GITHUB_TOKEN env variable to be set. - - Example usage: - adev deps verify + """Verify and optionally update package dependencies. + + Optional Parameters: + auto_approve: Skip confirmation prompts for updates. Default: False + - Automatically applies all updates + - No interactive prompts + - Use with caution in production + + Usage: + Verify with prompts: + adev deps verify + + Auto-approve updates: + adev deps verify --auto-approve + + Notes + ----- + - Authentication: + - Requires GITHUB_TOKEN environment variable + - Token needs repo and packages read access + - Can be generated at github.com/settings/tokens + + - Verification Process: + - Checks both autonomy and poetry dependencies + - Verifies against specified version sets + - Compares local vs remote package hashes + - Validates dependency compatibility + + - Update Process: + - Updates packages.json for autonomy packages + - Updates pyproject.toml for poetry dependencies + - Handles dependency resolution + - Maintains version consistency + + - Features: + - Parallel version checking + - Detailed diff viewing + - Selective update approval + - Dependency tree analysis + - Version conflict detection + + - Best Practices: + - Run before deployments + - Include in CI/CD pipelines + - Regular scheduled verification + - Version pinning enforcement """ if not os.getenv("GITHUB_TOKEN"): diff --git a/auto_dev/commands/fmt.py b/auto_dev/commands/fmt.py index 57d56e09..dc29f7cd 100644 --- a/auto_dev/commands/fmt.py +++ b/auto_dev/commands/fmt.py @@ -27,7 +27,43 @@ ) @click.pass_context def fmt(ctx, path, changed_only) -> None: - """Runs the formatting tooling.""" + """Format code using the configured formatters. + + Optional Parameters: + path: Path to code to format. Default: None + - If not provided, formats all packages + - Can be file or directory path + - Must exist in workspace + changed_only: Only format files that have changed. Default: False + - Uses git to detect changes + - Only formats files with uncommitted changes + - Ignores untracked files + + Usage: + Format all packages: + adev fmt + + Format specific path: + adev fmt -p ./my_package + + Format only changed files: + adev fmt --changed-only + + Format specific path and only changed files: + adev fmt -p ./my_package --changed-only + + Notes + ----- + - Uses multiple formatters: + - black: Python code formatting + - isort: Import sorting + - docformatter: Docstring formatting + - Supports parallel processing for faster formatting + - Shows formatting statistics on completion + - Exits with error if any formatting fails + - Can be integrated into pre-commit hooks + - Respects .gitignore patterns + """ verbose = ctx.obj["VERBOSE"] num_processes = ctx.obj["NUM_PROCESSES"] logger = ctx.obj["LOGGER"] diff --git a/auto_dev/commands/fsm.py b/auto_dev/commands/fsm.py index c82db464..74d86c8e 100644 --- a/auto_dev/commands/fsm.py +++ b/auto_dev/commands/fsm.py @@ -45,11 +45,28 @@ class FsmType(Enum): "--output", type=click.Choice([f.value for f in FsmType], case_sensitive=False), default=FsmType.MERMAID.value ) def from_file(fsm_spec: str, fsm_name: str, in_type: str, output: str) -> None: - """We parse an fsm file, in order to covnert between mermaid and fsm_spec. + """Convert between FSM specification formats. - Example Usage: - `adev fsm from-file auto_dev/data/fsm/samples/fsm_specification.yaml testAbciApp` - `adev fsm from-file auto_dev/data/fsm/samples/fsm_specification.yaml testAbciApp --output fsm_spec` + Required Parameters: + fsm_spec: Path to the FSM specification file. + fsm_name: Name of the FSM to process. + + Optional Parameters: + in_type: Input format type (fsm_spec or mermaid). Default: fsm_spec + output: Output format type (fsm_spec or mermaid). Default: mermaid + + Usage: + Convert FSM spec to mermaid: + adev fsm from-file fsm_specification.yaml testAbciApp + + Convert FSM spec to FSM spec (validation): + adev fsm from-file fsm_specification.yaml testAbciApp --output fsm_spec + + Convert from mermaid to FSM spec: + adev fsm from-file diagram.mmd testAbciApp --in-type mermaid --output fsm_spec + + Convert mermaid to mermaid (validation): + adev fsm from-file diagram.mmd testAbciApp --in-type mermaid """ fsm = INPUT_TO_FUNC[in_type](fsm_spec, label=fsm_name) diff --git a/auto_dev/commands/improve.py b/auto_dev/commands/improve.py index 56d93003..949657ad 100644 --- a/auto_dev/commands/improve.py +++ b/auto_dev/commands/improve.py @@ -49,7 +49,36 @@ ) @click.pass_context def improve(ctx, path, type_of_repo, author, name, yes) -> None: - """Improves downstream repos by verifying the context of scaffolded files.""" + """Verify and improve repository structure and files. + + Required Parameters: + type_of_repo: Type of repository to verify (autonomy, python) + author: Author of the repository + name: Name of the repository + + Optional Parameters: + path: Path to repository to verify. Default: current directory + yes: Auto-confirm all prompts. Default: False + + Usage: + Verify current directory: + adev improve -t autonomy --author myname --name myrepo + + Verify specific path: + adev improve -p /path/to/repo -t autonomy --author myname --name myrepo + + Auto-confirm fixes: + adev improve -t autonomy --author myname --name myrepo -y + + Notes + ----- + - Verifies repository structure against template + - Shows detailed verification results + - Can automatically fix differences if confirmed + - Reports pass/fail/modified/skipped counts + - Exits with error if files are modified or verification fails + + """ if path is None: path = Path.cwd() os.chdir(path) diff --git a/auto_dev/commands/lint.py b/auto_dev/commands/lint.py index bed4538f..d42a628f 100644 --- a/auto_dev/commands/lint.py +++ b/auto_dev/commands/lint.py @@ -36,7 +36,58 @@ ) @click.pass_context def lint(ctx, path, changed_only) -> None: - """Runs the linting tooling.""" + """Run linting checks on code. + + Optional Parameters: + path: Path to code to lint. Default: None + - If not provided, lints all packages + - Can be file or directory path + - Must exist in workspace + changed_only: Only lint files that have changed. Default: False + - Uses git to detect changes + - Only lints files with uncommitted changes + - Ignores untracked files + + Usage: + Lint all packages: + adev lint + + Lint specific path: + adev lint -p ./my_package + + Lint only changed files: + adev lint --changed-only + + Lint specific path and only changed files: + adev lint -p ./my_package --changed-only + + Lint with verbose output: + adev lint -v + + Notes + ----- + - Linting Tools: + - ruff: Fast Python linter + - pylint: Comprehensive code analysis + - mypy: Static type checking + - bandit: Security checks + - Features: + - Parallel linting for performance + - Configurable via pyproject.toml + - Auto-fixes for common issues + - Detailed error reporting + - Custom rule configuration + - Integration: + - Works with pre-commit hooks + - CI/CD pipeline support + - Editor/IDE integration + - Custom plugin support + - Configuration: + - Severity levels customization + - Rule enabling/disabling + - File/directory exclusions + - Line length settings + """ logger = ctx.obj["LOGGER"] verbose = ctx.obj["VERBOSE"] num_processes = ctx.obj["NUM_PROCESSES"] diff --git a/auto_dev/commands/metadata.py b/auto_dev/commands/metadata.py index 19b2e4af..3776dbb7 100644 --- a/auto_dev/commands/metadata.py +++ b/auto_dev/commands/metadata.py @@ -91,7 +91,12 @@ def get_metadata(root, name, hash_, target_id): @cli.group() def metadata() -> None: - """Commands for generating and printing metadata.""" + """Commands for generating and managing package metadata. + + Available Commands: + generate: Generate metadata JSON files for packages. + validate: Validate existing metadata files. + """ # we make a command called generate @@ -124,10 +129,33 @@ def metadata() -> None: default=False, ) def generate(root, target_name, target_id, strict, all) -> None: # pylint: disable=redefined-builtin - """Generate metadata for a package. + """Generate metadata JSON files for packages. + + Required Parameters: + root: Path to root directory containing packages.json. Default: current directory + target_name: Name of the package to generate metadata for (e.g., contract/author/name/version) + target_id: Identifier for the metadata file (used in output filename) + + Optional Parameters: + strict: Enable strict validation of metadata. Default: False + all: Generate metadata for all packages. Default: False + + Usage: + Generate for specific package: + adev metadata generate . contract/author/package/0.1.0 01 + + Generate for all packages: + adev metadata generate . contract/author/package/0.1.0 01 --all - example usage: - python ./metadata.py generate . contract/eightballer/cool_skill/0.1.0 01 + Generate with strict validation: + adev metadata generate . contract/author/package/0.1.0 01 --strict + + Notes + ----- + - Reads package information from packages.json + - Generates metadata files in mints/.json + - Strict mode enforces additional validation + - Can process single package or all packages """ if not target_id and not all: @@ -234,7 +262,24 @@ def build_dependency_tree_for_component(component) -> list[str]: ) @click.pass_context def validate(ctx, metadata_file) -> None: - """Print metadata for a package.""" + """Validate metadata files for packages. + + Required Parameters: + metadata_file: Path to the metadata JSON file to validate + + Usage: + Validate a metadata file: + adev metadata validate mints/01.json + + Notes + ----- + - Validates the metadata file format and content + - Checks if all dependencies are minted + - Verifies component status in mapping.txt + - Displays detailed validation results with verbose flag + - Exits with error if validation fails + + """ verbose = ctx.obj["VERBOSE"] metadata = read_json_file(metadata_file) valid = render_metadata(metadata, verbose=verbose) diff --git a/auto_dev/commands/publish.py b/auto_dev/commands/publish.py index dea9e9f1..e6bcf72a 100644 --- a/auto_dev/commands/publish.py +++ b/auto_dev/commands/publish.py @@ -1,6 +1,5 @@ """This module contains the logic for the publish command.""" - import rich_click as click from aea.configurations.base import PublicId @@ -30,17 +29,25 @@ def publish(ctx, public_id: PublicId = None, force: bool = False) -> None: """Publish an agent to the local registry. - Args: - ---- - public_id: The public_id of the agent in the open-autonmy format i.e. `author/agent`. - If not provided, assumes you're inside the agent directory. This will be the - name of the package published. - force: If True, will overwrite existing package. + Required Parameters: + public_id: The public ID of the agent (author/name format). + + Optional Parameters: + force: Force overwrite if package exists. Default: False + + Usage: + Basic publish: + adev publish author/new_agent + + Publish with force overwrite: + adev publish author/new_agent --force - Example usage: - From agent directory: `adev publish author/new_agent --force/--no-force` - With force: `adev publish --force` + Publish without force: + adev publish author/new_agent --no-force + Publish from agent directory: + cd my_agent + adev publish author/new_agent """ verbose = ctx.obj["VERBOSE"] logger = ctx.obj["LOGGER"] @@ -54,9 +61,7 @@ def publish(ctx, public_id: PublicId = None, force: bool = False) -> None: ) if not agent_runner.is_in_agent_dir(): msg = "Not in an agent directory (aea-config.yaml not found) Please enter the agent directory to publish" - raise OperationError( - msg - ) + raise OperationError(msg) package_manager = PackageManager(verbose=verbose) package_manager.publish_agent(force=force, new_public_id=public_id) click.secho(AGENT_PUBLISHED_SUCCESS_MSG, fg="green") diff --git a/auto_dev/commands/release.py b/auto_dev/commands/release.py index d3319f21..981f1d31 100644 --- a/auto_dev/commands/release.py +++ b/auto_dev/commands/release.py @@ -110,11 +110,30 @@ def release( dep_path: Path, verbose: bool = False, ) -> None: - """We release the package. - Automaticaly bump the version and create a new tag. - Push the tag to github. - Push the branch to github. - This will trigger a github action to publish the package to pypi. + """Release a new version of the package. + + Optional Parameters: + dep_path: Path to the dependency file (pyproject.toml). Default: pyproject.toml + verbose: Enable verbose output. Default: False + + Usage: + Release with default settings: + adev release + + Release with custom dependency file: + adev release -p ./custom/pyproject.toml + + Release with verbose output: + adev release --verbose + + Notes + ----- + - Automatically bumps version and creates a new tag + - Pushes tag and branch to GitHub + - Triggers GitHub action to publish to PyPI + - Requires clean git working tree + - Will prompt for confirmation before proceeding + """ logger = ctx.obj["LOGGER"] logger.info("Releasing the package... 🚀") diff --git a/auto_dev/commands/repo.py b/auto_dev/commands/repo.py index 128c19ea..85975553 100644 --- a/auto_dev/commands/repo.py +++ b/auto_dev/commands/repo.py @@ -180,7 +180,12 @@ def verify( # We create a new command group @cli.group() def repo() -> None: - """Repository management commands.""" + """Repository management commands. + + Available Commands: + scaffold: Create and initialize a new repository with template files + update_deps: Update and lock repository dependencies + """ @repo.command() @@ -192,7 +197,42 @@ def repo() -> None: @click.option("--initial-commit/--no-commit", is_flag=True, help="Add the initial commit. Requires git", default=True) @click.pass_context def scaffold(ctx, name, type_of_repo, force, auto_approve, install, initial_commit) -> None: - """Create a new repo and scaffold necessary files.""" + """Create a new repository and scaffold necessary files. + + Required Parameters: + name: Name of the repository to create + + Optional Parameters: + type_of_repo: Type of repository to scaffold (autonomy, python). Default: autonomy + force: Overwrite existing repository if it exists. Default: False + auto_approve: Skip confirmation prompts. Default: False + install: Install dependencies after scaffolding. Default: True + initial_commit: Create initial git commit. Default: True + + Usage: + Create basic autonomy repo: + adev repo scaffold my_repo + + Create Python repo: + adev repo scaffold my_repo -t python + + Force overwrite existing repo: + adev repo scaffold my_repo -f + + Skip dependency installation: + adev repo scaffold my_repo --no-install + + Notes + ----- + - Creates a new git repository in the specified directory + - For autonomy repos: + - Installs host dependencies via install.sh + - Initializes autonomy packages + - For Python repos: + - Creates src directory with __init__.py + - Adds sample main.py and cli.py files + + """ logger = ctx.obj["LOGGER"] verbose = ctx.obj["VERBOSE"] logger.info(f"Creating a new {type_of_repo} repo.") @@ -308,7 +348,27 @@ def update_against_version_set(logger, dry_run: bool = False) -> list[str]: ) @click.pass_context def update_deps(ctx, lock: bool) -> None: - """Update dependencies in the current repo.""" + """Update and lock repository dependencies. + + Optional Parameters: + lock: Lock dependencies after updating. Default: False + + Usage: + Update dependencies: + adev repo update-deps + + Update and lock dependencies: + adev repo update-deps --lock + + Notes + ----- + - Updates dependencies in packages.json + - Optionally locks dependency versions + - Checks for changes in dependency files + - Prompts to commit changes if detected + - Exits with error if uncommitted changes exist + + """ logger = ctx.obj["LOGGER"] verbose = ctx.obj["VERBOSE"] # We read in the pyproject.toml file diff --git a/auto_dev/commands/run.py b/auto_dev/commands/run.py index 4a6e5968..34ade780 100644 --- a/auto_dev/commands/run.py +++ b/auto_dev/commands/run.py @@ -318,9 +318,44 @@ def get_version(self) -> str: def run(ctx, agent_public_id: PublicId, verbose: bool, force: bool, fetch: bool) -> None: """Run an agent from the local packages registry or a local path. - Example usage: - adev run eightballer/my_agent # Fetch and run from registry - adev run eightballer/my_agent --no-fetch # Run local agent package named my_agent + Required Parameters: + agent_public_id: The public ID of the agent (author/name format). + If not provided, uses the current directory's agent. + + Optional Parameters: + verbose: Enable verbose logging. Shows detailed output during execution. Default: False + force: Force overwrite if agent exists locally. Default: False + fetch: Whether to fetch agent from registry or use local package. Default: True + - If True: Fetches agent from local registry + - If False: Uses agent from current directory or packages + + Usage: + Run from registry: + adev run eightballer/my_agent + + Run local agent: + adev run eightballer/my_agent --no-fetch + + Run with verbose output: + adev run eightballer/my_agent -v + + Run with force overwrite: + adev run eightballer/my_agent --force + + Run from current directory: + adev run + + Notes + ----- + - Automatically handles: + - Agent setup and key generation + - Dependency installation + - Certificate management + - Tendermint node management + - Requires Docker for Tendermint + - Validates agent configuration + - Supports multiple blockchain networks + - Can run agents in development or production mode """ if not agent_public_id: # We set fetch to false if the agent is not provided, as we assume the user wants to run the agent locally. diff --git a/auto_dev/commands/scaffold.py b/auto_dev/commands/scaffold.py index f6c3a36e..c9272137 100644 --- a/auto_dev/commands/scaffold.py +++ b/auto_dev/commands/scaffold.py @@ -40,7 +40,15 @@ # we have a new command group called scaffold. @cli.group() def scaffold() -> None: - """Scaffold a (set of) components.""" + """Commands for scaffolding new components. + + Available Commands: + contract: Scaffold a smart contract component + fsm: Scaffold a Finite State Machine (FSM) + protocol: Scaffold a protocol component + connection: Scaffold a connection component + handler: Generate an AEA handler from OpenAPI 3 specification + """ def validate_address(address: str, logger, contract_name: str | None = None) -> str | None: @@ -107,9 +115,35 @@ def _process_from_file(ctx, yaml_dict, network, read_functions, write_functions, @click.option("--write-functions", default=None, help="Comma separated list of write functions to scaffold.") @click.pass_context def contract(ctx, public_id, address, network, read_functions, write_functions, from_abi, from_file): - """Scaffold a contract. + """Scaffold a smart contract component. + + Required Parameters: + Either one of: + public_id: The public ID of the contract (author/name format). + from_file: Path to file containing contract addresses and names. + + Optional Parameters: + address: Contract address on the blockchain. Default: null address + from_abi: Path to ABI file to use for scaffolding. Default: None + network: Blockchain network to fetch ABI from. Default: ethereum + read_functions: Comma-separated list of read functions to include. Default: None (all) + write_functions: Comma-separated list of write functions to include. Default: None (all) + + Usage: + Scaffold from address: + adev scaffold contract author/contract_name --address 0x123... + + Scaffold from ABI file: + adev scaffold contract author/contract_name --from-abi ./contract.abi + + Scaffold from file with multiple contracts: + adev scaffold contract --from-file ./contracts.yaml + + Scaffold with specific network: + adev scaffold contract author/contract_name --address 0x123... --network polygon - :param public_id: the public_id of the contract in the open-autonomy format i.e. `author/contract_name` + Scaffold with specific functions: + adev scaffold contract author/contract_name --address 0x123... --read-functions "balanceOf,totalSupply" """ logger = ctx.obj["LOGGER"] @@ -182,9 +216,32 @@ def _log_contract_info(contract, contract_path, logger): @scaffold.command() @click.option("--spec", default=None, required=False) def fsm(spec) -> None: - """Scaffold a FSM. + """Scaffold a new Finite State Machine (FSM). + + Optional Parameters: + spec: Path to FSM specification YAML file. Default: None + + Usage: + Scaffold base FSM: + adev scaffold fsm + + Scaffold from specification: + adev scaffold fsm --spec fsm_specification.yaml + + Notes + ----- + - Requires aea_config.yaml in current directory + - Automatically adds required base FSM skills: + - abstract_abci + - abstract_round_abci + - registration_abci + - reset_pause_abci + - termination_abci + - When using spec file: + - Must be valid FSM specification in YAML format + - FSM label must end with 'App' suffix + - Creates FSM based on specification structure - usage: `adev scaffold fsm [--spec fsm_specification.yaml]` """ if not Path(DEFAULT_AEA_CONFIG_FILE).exists(): msg = f"No {DEFAULT_AEA_CONFIG_FILE} found in current directory" @@ -227,7 +284,29 @@ def fsm(spec) -> None: ) @click.pass_context def protocol(ctx, protocol_specification_path: str, language: str) -> None: - """Scaffold a protocol.""" + """Scaffold a new protocol component. + + Required Parameters: + protocol_specification_path: Path to protocol specification file + + Optional Parameters: + language: Programming language for protocol (default: python) + + Usage: + Basic protocol scaffolding: + adev scaffold protocol path/to/spec.yaml + + Specify language: + adev scaffold protocol path/to/spec.yaml --l python + + Notes + ----- + - Creates protocol package from specification + - Supports multiple programming languages + - Generates message classes and serialization + - Adds protocol to agent configuration + + """ logger = ctx.obj["LOGGER"] verbose = ctx.obj["VERBOSE"] scaffolder = ProtocolScaffolder(protocol_specification_path, language, logger=logger, verbose=verbose) @@ -244,7 +323,20 @@ def connection( # pylint: disable=R0914 name, protocol: PublicId, ) -> None: - """Scaffold a connection.""" + """Scaffold a new connection component. + + Required Parameters: + name: Name of the connection to create. + protocol: Public ID of the protocol to use (author/name format). + + Usage: + Create connection with protocol: + adev scaffold connection my_connection --protocol author/protocol_name + + Create connection in specific directory: + cd my_project + adev scaffold connection my_connection --protocol author/protocol_name + """ logger = ctx.obj["LOGGER"] if protocol not in ctx.aea_ctx.agent_config.protocols: @@ -265,7 +357,35 @@ def connection( # pylint: disable=R0914 @click.option("--auto-confirm", is_flag=True, default=False, help="Auto confirm all actions") @click.pass_context def handler(ctx, spec_file, public_id, new_skill, auto_confirm) -> int: - """Generate an AEA handler from an OpenAPI 3 specification.""" + """Generate an AEA handler from an OpenAPI 3 specification. + + Required Parameters: + spec_file: Path to OpenAPI 3 specification file + public_id: Public ID for the handler (author/name format) + + Optional Parameters: + new_skill: Create a new skill for the handler. Default: False + auto_confirm: Skip confirmation prompts. Default: False + + Usage: + Basic handler generation: + adev scaffold handler api_spec.yaml author/handler_name + + Create new skill: + adev scaffold handler api_spec.yaml author/handler_name --new-skill + + Skip confirmations: + adev scaffold handler api_spec.yaml author/handler_name --auto-confirm + + Notes + ----- + - Requires aea_config.yaml in current directory + - Generates handler code from OpenAPI endpoints + - Creates necessary message classes + - Can optionally create a new skill + - Shows changes and prompts for confirmation + + """ logger = ctx.obj["LOGGER"] verbose = ctx.obj["VERBOSE"] diff --git a/auto_dev/commands/test.py b/auto_dev/commands/test.py index fffad280..2413dd70 100644 --- a/auto_dev/commands/test.py +++ b/auto_dev/commands/test.py @@ -1,6 +1,5 @@ """Test command cli module.""" - import rich_click as click from rich.progress import track @@ -32,7 +31,55 @@ @click.option("-c", "--coverage-report", help="Run the coverage report", is_flag=True, default=True) @click.pass_context def test(ctx, path, watch, coverage_report) -> None: - """Runs the test tooling.""" + """Run tests for packages. + + Optional Parameters: + path: Path to directory to test. Default: None + - If not provided, tests all packages + - Must be a valid directory containing tests + - Can be package root or specific test directory + watch: Watch files for changes and re-run tests. Default: False + - Monitors file changes in real-time + - Re-runs tests when files are modified + - Useful for test-driven development + coverage_report: Generate test coverage report. Default: True + - Creates detailed coverage analysis + - Shows line-by-line coverage stats + - Generates HTML report for visualization + + Usage: + Test all packages: + adev test + + Test specific directory: + adev test -p ./my_package + + Test with file watching: + adev test -w + + Test without coverage report: + adev test --no-coverage-report + + Test specific directory with watching: + adev test -p ./my_package -w + + Notes + ----- + - Test Framework: + - Uses pytest as test runner + - Supports fixtures and markers + - Handles async tests + - Coverage: + - Tracks line and branch coverage + - Excludes test files from coverage + - Sets minimum coverage thresholds + - Features: + - Parallel test execution + - JUnit XML reports + - Integration with CI/CD + - Detailed failure reporting + - Test categorization with markers + """ verbose = ctx.obj["VERBOSE"] click.echo( f"Testing path: `{path or 'All dev packages/packages.json'}` ⌛", diff --git a/auto_dev/scripts/__init__.py b/auto_dev/scripts/__init__.py new file mode 100644 index 00000000..d83c74e9 --- /dev/null +++ b/auto_dev/scripts/__init__.py @@ -0,0 +1 @@ +"""Scripts package for auto_dev.""" diff --git a/auto_dev/scripts/generate_command_docs.py b/auto_dev/scripts/generate_command_docs.py new file mode 100644 index 00000000..230556be --- /dev/null +++ b/auto_dev/scripts/generate_command_docs.py @@ -0,0 +1,66 @@ +"""Script to generate command documentation.""" + +from pathlib import Path + + +COMMANDS = [ + "run", + "create", + "lint", + "publish", + "test", + "improve", + "release", + "metadata", + "fmt", + "scaffold", + "deps", + "convert", + "repo", + "fsm", + "augment", +] + +TEMPLATE = """# {command_title} Command + +::: auto_dev.commands.{command_name}.{command_name} + options: + show_root_heading: false + show_source: false + show_signature: true + show_signature_annotations: true + docstring_style: sphinx + show_docstring_parameters: true + show_docstring_returns: false + show_docstring_raises: false + show_docstring_examples: true + docstring_section_style: table + docstring_options: + heading_level: 2 + merge_init_into_class: false + show_docstring_attributes: false + show_docstring_description: true + show_docstring_examples: true + show_docstring_other_parameters: false + show_docstring_parameters: true + show_docstring_raises: false + show_docstring_returns: false + show_docstring_warns: false + show_docstring_yields: false + parameter_headings: + required: "Required Parameters" + optional: "Optional Parameters" +""" + + +def main(): + """Generate documentation for all commands.""" + # Get the package root directory + package_root = Path(__file__).parent.parent.parent + docs_dir = package_root / "docs" / "commands" + docs_dir.mkdir(parents=True, exist_ok=True) + + for command in COMMANDS: + doc_path = docs_dir / f"{command}.md" + with open(doc_path, "w", encoding="utf-8") as f: + f.write(TEMPLATE.format(command_title=command.title(), command_name=command)) diff --git a/coverage-report.txt b/coverage-report.txt index 963aa2db..c65c587d 100644 --- a/coverage-report.txt +++ b/coverage-report.txt @@ -1,17 +1,24 @@ -Name Stmts Miss Cover Missing --------------------------------------------------------------- -auto_dev/__init__.py 0 0 100% -auto_dev/base.py 60 60 0% 3-94 -auto_dev/check_dependencies.py 236 236 0% 28-452 -auto_dev/cli.py 4 4 0% 3-9 -auto_dev/cli_executor.py 73 73 0% 8-110 -auto_dev/constants.py 59 59 0% 3-167 -auto_dev/enums.py 40 40 0% 3-61 -auto_dev/exceptions.py 8 8 0% 4-32 -auto_dev/fmt.py 59 59 0% 3-112 -auto_dev/lint.py 7 7 0% 3-27 -auto_dev/local_fork.py 52 52 0% 3-95 -auto_dev/test.py 16 16 0% 3-39 -auto_dev/utils.py 275 275 0% 3-473 --------------------------------------------------------------- -TOTAL 889 889 0% +Name Stmts Miss Cover Missing +---------------------------------------------------------------- +auto_dev/__init__.py 0 0 100% +auto_dev/base.py 60 60 0% 3-98 +auto_dev/check_dependencies.py 229 229 0% 26-440 +auto_dev/cli.py 4 4 0% 3-9 +auto_dev/cli_executor.py 71 71 0% 8-108 +auto_dev/constants.py 58 58 0% 3-166 +auto_dev/enums.py 40 40 0% 3-62 +auto_dev/exceptions.py 8 8 0% 4-32 +auto_dev/fmt.py 59 59 0% 3-112 +auto_dev/lint.py 5 5 0% 3-26 +auto_dev/local_fork.py 52 52 0% 3-95 +auto_dev/scaffolder.py 19 19 0% 3-43 +auto_dev/test.py 15 15 0% 3-38 +auto_dev/utils.py 286 286 0% 3-494 +docs/__init__.py 0 0 100% +docs/hooks.py 35 35 0% 3-75 +scripts/__init__.py 0 0 100% +scripts/generate_command_docs.py 67 67 0% 8-202 +site/__init__.py 0 0 100% +site/hooks.py 35 35 0% 3-75 +---------------------------------------------------------------- +TOTAL 1043 1043 0% diff --git a/docs/__init__.py b/docs/__init__.py new file mode 100644 index 00000000..7d6c14cf --- /dev/null +++ b/docs/__init__.py @@ -0,0 +1 @@ +"""Documentation package.""" diff --git a/docs/api/auto_dev.md b/docs/api/auto_dev.md deleted file mode 100644 index 67c39990..00000000 --- a/docs/api/auto_dev.md +++ /dev/null @@ -1,5 +0,0 @@ -# API Reference - -## Auto Dev module - -::: auto_dev diff --git a/docs/api/commands.md b/docs/api/commands.md deleted file mode 100644 index 04ba2a51..00000000 --- a/docs/api/commands.md +++ /dev/null @@ -1,3 +0,0 @@ -# Connections - -::: connections \ No newline at end of file diff --git a/docs/api/connections.md b/docs/api/connections.md deleted file mode 100644 index 04ba2a51..00000000 --- a/docs/api/connections.md +++ /dev/null @@ -1,3 +0,0 @@ -# Connections - -::: connections \ No newline at end of file diff --git a/docs/api/constants.md b/docs/api/constants.md deleted file mode 100644 index 3887dbb9..00000000 --- a/docs/api/constants.md +++ /dev/null @@ -1,3 +0,0 @@ -# Constants - -::: constants \ No newline at end of file diff --git a/docs/api/contracts.md b/docs/api/contracts.md deleted file mode 100644 index f6de8ca3..00000000 --- a/docs/api/contracts.md +++ /dev/null @@ -1,3 +0,0 @@ -# Contracts - -::: contracts \ No newline at end of file diff --git a/docs/api/fsm.md b/docs/api/fsm.md deleted file mode 100644 index e3d842f5..00000000 --- a/docs/api/fsm.md +++ /dev/null @@ -1,3 +0,0 @@ -# FSM - -::: fsm \ No newline at end of file diff --git a/docs/api/handler.md b/docs/api/handler.md deleted file mode 100644 index a3d7a810..00000000 --- a/docs/api/handler.md +++ /dev/null @@ -1,3 +0,0 @@ -# Handler - -::: handler \ No newline at end of file diff --git a/docs/api/index.md b/docs/api/index.md deleted file mode 100644 index 754ccd44..00000000 --- a/docs/api/index.md +++ /dev/null @@ -1,15 +0,0 @@ -# API Reference Overview - -This section provides detailed information about the auto_dev API. Use the navigation menu to explore specific modules and components. - -## Main Modules - -- [auto_dev](auto_dev.md): Core functionality -- [Commands](commands.md): CLI commands -- [Connections](connections.md): Network connections -- [Contracts](contracts.md): Smart contract interactions -- [FSM](fsm.md): Finite State Machine implementation -- [Handler](handler.md): Request handling -- [Protocols](protocols.md): Communication protocols -- [Utils](utils.md): Utility functions -- [Constants](constants.md): Constant values used across the project \ No newline at end of file diff --git a/docs/api/protocols.md b/docs/api/protocols.md deleted file mode 100644 index 44c1218c..00000000 --- a/docs/api/protocols.md +++ /dev/null @@ -1,3 +0,0 @@ -# Protocols - -::: protocols \ No newline at end of file diff --git a/docs/api/utils.md b/docs/api/utils.md deleted file mode 100644 index 56822113..00000000 --- a/docs/api/utils.md +++ /dev/null @@ -1,3 +0,0 @@ -# Utils - -::: utils \ No newline at end of file diff --git a/docs/commands/augment.md b/docs/commands/augment.md new file mode 100644 index 00000000..1e7be2f4 --- /dev/null +++ b/docs/commands/augment.md @@ -0,0 +1,73 @@ +## Description + +::: auto_dev.commands.augment.augment + options: + show_root_heading: false + show_source: false + show_signature: true + show_signature_annotations: true + docstring_style: sphinx + show_docstring_parameters: true + show_docstring_returns: false + show_docstring_raises: false + show_docstring_examples: true + docstring_section_style: table + heading_level: 2 + +## Usage + +```bash +adev augment [OPTIONS] [ARGS] +``` + +Additionally, you can view the parameters for the command using: +```bash +adev augment --help +``` + + +## Connection + +::: auto_dev.commands.augment.connection + options: + show_root_heading: false + show_source: false + show_signature: true + show_signature_annotations: true + docstring_style: sphinx + show_docstring_parameters: true + show_docstring_returns: false + show_docstring_raises: false + show_docstring_examples: true + docstring_section_style: table + heading_level: 2 +## Customs + +::: auto_dev.commands.augment.customs + options: + show_root_heading: false + show_source: false + show_signature: true + show_signature_annotations: true + docstring_style: sphinx + show_docstring_parameters: true + show_docstring_returns: false + show_docstring_raises: false + show_docstring_examples: true + docstring_section_style: table + heading_level: 2 +## Logging + +::: auto_dev.commands.augment.logging + options: + show_root_heading: false + show_source: false + show_signature: true + show_signature_annotations: true + docstring_style: sphinx + show_docstring_parameters: true + show_docstring_returns: false + show_docstring_raises: false + show_docstring_examples: true + docstring_section_style: table + heading_level: 2 \ No newline at end of file diff --git a/docs/commands/convert.md b/docs/commands/convert.md new file mode 100644 index 00000000..2812bc69 --- /dev/null +++ b/docs/commands/convert.md @@ -0,0 +1,43 @@ +## Description + +::: auto_dev.commands.convert.convert + options: + show_root_heading: false + show_source: false + show_signature: true + show_signature_annotations: true + docstring_style: sphinx + show_docstring_parameters: true + show_docstring_returns: false + show_docstring_raises: false + show_docstring_examples: true + docstring_section_style: table + heading_level: 2 + +## Usage + +```bash +adev convert [OPTIONS] [ARGS] +``` + +Additionally, you can view the parameters for the command using: +```bash +adev convert --help +``` + + +## Agent To Service + +::: auto_dev.commands.convert.agent_to_service + options: + show_root_heading: false + show_source: false + show_signature: true + show_signature_annotations: true + docstring_style: sphinx + show_docstring_parameters: true + show_docstring_returns: false + show_docstring_raises: false + show_docstring_examples: true + docstring_section_style: table + heading_level: 2 \ No newline at end of file diff --git a/docs/commands/create.md b/docs/commands/create.md new file mode 100644 index 00000000..4d736922 --- /dev/null +++ b/docs/commands/create.md @@ -0,0 +1,27 @@ +## Description + +::: auto_dev.commands.create.create + options: + show_root_heading: false + show_source: false + show_signature: true + show_signature_annotations: true + docstring_style: sphinx + show_docstring_parameters: true + show_docstring_returns: false + show_docstring_raises: false + show_docstring_examples: true + docstring_section_style: table + heading_level: 2 + +## Usage + +```bash +adev create [OPTIONS] [ARGS] +``` + +Additionally, you can view the parameters for the command using: +```bash +adev create --help +``` + diff --git a/docs/commands/deps.md b/docs/commands/deps.md new file mode 100644 index 00000000..1c34338b --- /dev/null +++ b/docs/commands/deps.md @@ -0,0 +1,73 @@ +## Description + +::: auto_dev.commands.deps.deps + options: + show_root_heading: false + show_source: false + show_signature: true + show_signature_annotations: true + docstring_style: sphinx + show_docstring_parameters: true + show_docstring_returns: false + show_docstring_raises: false + show_docstring_examples: true + docstring_section_style: table + heading_level: 2 + +## Usage + +```bash +adev deps [OPTIONS] [ARGS] +``` + +Additionally, you can view the parameters for the command using: +```bash +adev deps --help +``` + + +## Generate Gitignore + +::: auto_dev.commands.deps.generate_gitignore + options: + show_root_heading: false + show_source: false + show_signature: true + show_signature_annotations: true + docstring_style: sphinx + show_docstring_parameters: true + show_docstring_returns: false + show_docstring_raises: false + show_docstring_examples: true + docstring_section_style: table + heading_level: 2 +## Update + +::: auto_dev.commands.deps.update + options: + show_root_heading: false + show_source: false + show_signature: true + show_signature_annotations: true + docstring_style: sphinx + show_docstring_parameters: true + show_docstring_returns: false + show_docstring_raises: false + show_docstring_examples: true + docstring_section_style: table + heading_level: 2 +## Verify + +::: auto_dev.commands.deps.verify + options: + show_root_heading: false + show_source: false + show_signature: true + show_signature_annotations: true + docstring_style: sphinx + show_docstring_parameters: true + show_docstring_returns: false + show_docstring_raises: false + show_docstring_examples: true + docstring_section_style: table + heading_level: 2 \ No newline at end of file diff --git a/docs/commands/fmt.md b/docs/commands/fmt.md new file mode 100644 index 00000000..7d79219a --- /dev/null +++ b/docs/commands/fmt.md @@ -0,0 +1,27 @@ +## Description + +::: auto_dev.commands.fmt.fmt + options: + show_root_heading: false + show_source: false + show_signature: true + show_signature_annotations: true + docstring_style: sphinx + show_docstring_parameters: true + show_docstring_returns: false + show_docstring_raises: false + show_docstring_examples: true + docstring_section_style: table + heading_level: 2 + +## Usage + +```bash +adev fmt [OPTIONS] [ARGS] +``` + +Additionally, you can view the parameters for the command using: +```bash +adev fmt --help +``` + diff --git a/docs/commands/fsm.md b/docs/commands/fsm.md new file mode 100644 index 00000000..ee7ea396 --- /dev/null +++ b/docs/commands/fsm.md @@ -0,0 +1,43 @@ +## Description + +::: auto_dev.commands.fsm.fsm + options: + show_root_heading: false + show_source: false + show_signature: true + show_signature_annotations: true + docstring_style: sphinx + show_docstring_parameters: true + show_docstring_returns: false + show_docstring_raises: false + show_docstring_examples: true + docstring_section_style: table + heading_level: 2 + +## Usage + +```bash +adev fsm [OPTIONS] [ARGS] +``` + +Additionally, you can view the parameters for the command using: +```bash +adev fsm --help +``` + + +## From File + +::: auto_dev.commands.fsm.from_file + options: + show_root_heading: false + show_source: false + show_signature: true + show_signature_annotations: true + docstring_style: sphinx + show_docstring_parameters: true + show_docstring_returns: false + show_docstring_raises: false + show_docstring_examples: true + docstring_section_style: table + heading_level: 2 \ No newline at end of file diff --git a/docs/commands/improve.md b/docs/commands/improve.md new file mode 100644 index 00000000..83bd3ebf --- /dev/null +++ b/docs/commands/improve.md @@ -0,0 +1,27 @@ +## Description + +::: auto_dev.commands.improve.improve + options: + show_root_heading: false + show_source: false + show_signature: true + show_signature_annotations: true + docstring_style: sphinx + show_docstring_parameters: true + show_docstring_returns: false + show_docstring_raises: false + show_docstring_examples: true + docstring_section_style: table + heading_level: 2 + +## Usage + +```bash +adev improve [OPTIONS] [ARGS] +``` + +Additionally, you can view the parameters for the command using: +```bash +adev improve --help +``` + diff --git a/docs/commands/lint.md b/docs/commands/lint.md new file mode 100644 index 00000000..8f39309a --- /dev/null +++ b/docs/commands/lint.md @@ -0,0 +1,27 @@ +## Description + +::: auto_dev.commands.lint.lint + options: + show_root_heading: false + show_source: false + show_signature: true + show_signature_annotations: true + docstring_style: sphinx + show_docstring_parameters: true + show_docstring_returns: false + show_docstring_raises: false + show_docstring_examples: true + docstring_section_style: table + heading_level: 2 + +## Usage + +```bash +adev lint [OPTIONS] [ARGS] +``` + +Additionally, you can view the parameters for the command using: +```bash +adev lint --help +``` + diff --git a/docs/commands/metadata.md b/docs/commands/metadata.md new file mode 100644 index 00000000..5254b1b0 --- /dev/null +++ b/docs/commands/metadata.md @@ -0,0 +1,58 @@ +## Description + +::: auto_dev.commands.metadata.metadata + options: + show_root_heading: false + show_source: false + show_signature: true + show_signature_annotations: true + docstring_style: sphinx + show_docstring_parameters: true + show_docstring_returns: false + show_docstring_raises: false + show_docstring_examples: true + docstring_section_style: table + heading_level: 2 + +## Usage + +```bash +adev metadata [OPTIONS] [ARGS] +``` + +Additionally, you can view the parameters for the command using: +```bash +adev metadata --help +``` + + +## Generate + +::: auto_dev.commands.metadata.generate + options: + show_root_heading: false + show_source: false + show_signature: true + show_signature_annotations: true + docstring_style: sphinx + show_docstring_parameters: true + show_docstring_returns: false + show_docstring_raises: false + show_docstring_examples: true + docstring_section_style: table + heading_level: 2 +## Validate + +::: auto_dev.commands.metadata.validate + options: + show_root_heading: false + show_source: false + show_signature: true + show_signature_annotations: true + docstring_style: sphinx + show_docstring_parameters: true + show_docstring_returns: false + show_docstring_raises: false + show_docstring_examples: true + docstring_section_style: table + heading_level: 2 \ No newline at end of file diff --git a/docs/commands/publish.md b/docs/commands/publish.md new file mode 100644 index 00000000..f01162dc --- /dev/null +++ b/docs/commands/publish.md @@ -0,0 +1,27 @@ +## Description + +::: auto_dev.commands.publish.publish + options: + show_root_heading: false + show_source: false + show_signature: true + show_signature_annotations: true + docstring_style: sphinx + show_docstring_parameters: true + show_docstring_returns: false + show_docstring_raises: false + show_docstring_examples: true + docstring_section_style: table + heading_level: 2 + +## Usage + +```bash +adev publish [OPTIONS] [ARGS] +``` + +Additionally, you can view the parameters for the command using: +```bash +adev publish --help +``` + diff --git a/docs/commands/release.md b/docs/commands/release.md new file mode 100644 index 00000000..8077152f --- /dev/null +++ b/docs/commands/release.md @@ -0,0 +1,27 @@ +## Description + +::: auto_dev.commands.release.release + options: + show_root_heading: false + show_source: false + show_signature: true + show_signature_annotations: true + docstring_style: sphinx + show_docstring_parameters: true + show_docstring_returns: false + show_docstring_raises: false + show_docstring_examples: true + docstring_section_style: table + heading_level: 2 + +## Usage + +```bash +adev release [OPTIONS] [ARGS] +``` + +Additionally, you can view the parameters for the command using: +```bash +adev release --help +``` + diff --git a/docs/commands/repo.md b/docs/commands/repo.md new file mode 100644 index 00000000..1302606d --- /dev/null +++ b/docs/commands/repo.md @@ -0,0 +1,58 @@ +## Description + +::: auto_dev.commands.repo.repo + options: + show_root_heading: false + show_source: false + show_signature: true + show_signature_annotations: true + docstring_style: sphinx + show_docstring_parameters: true + show_docstring_returns: false + show_docstring_raises: false + show_docstring_examples: true + docstring_section_style: table + heading_level: 2 + +## Usage + +```bash +adev repo [OPTIONS] [ARGS] +``` + +Additionally, you can view the parameters for the command using: +```bash +adev repo --help +``` + + +## Scaffold + +::: auto_dev.commands.repo.scaffold + options: + show_root_heading: false + show_source: false + show_signature: true + show_signature_annotations: true + docstring_style: sphinx + show_docstring_parameters: true + show_docstring_returns: false + show_docstring_raises: false + show_docstring_examples: true + docstring_section_style: table + heading_level: 2 +## Update Deps + +::: auto_dev.commands.repo.update_deps + options: + show_root_heading: false + show_source: false + show_signature: true + show_signature_annotations: true + docstring_style: sphinx + show_docstring_parameters: true + show_docstring_returns: false + show_docstring_raises: false + show_docstring_examples: true + docstring_section_style: table + heading_level: 2 \ No newline at end of file diff --git a/docs/commands/run.md b/docs/commands/run.md new file mode 100644 index 00000000..eb55ad44 --- /dev/null +++ b/docs/commands/run.md @@ -0,0 +1,27 @@ +## Description + +::: auto_dev.commands.run.run + options: + show_root_heading: false + show_source: false + show_signature: true + show_signature_annotations: true + docstring_style: sphinx + show_docstring_parameters: true + show_docstring_returns: false + show_docstring_raises: false + show_docstring_examples: true + docstring_section_style: table + heading_level: 2 + +## Usage + +```bash +adev run [OPTIONS] [ARGS] +``` + +Additionally, you can view the parameters for the command using: +```bash +adev run --help +``` + diff --git a/docs/commands/scaffold.md b/docs/commands/scaffold.md new file mode 100644 index 00000000..a1e05ff1 --- /dev/null +++ b/docs/commands/scaffold.md @@ -0,0 +1,178 @@ +## Description + +::: auto_dev.commands.scaffold.scaffold + options: + show_root_heading: false + show_source: false + show_signature: true + show_signature_annotations: true + docstring_style: sphinx + show_docstring_parameters: true + show_docstring_returns: false + show_docstring_raises: false + show_docstring_examples: true + docstring_section_style: table + heading_level: 2 + +## Usage + +```bash +adev scaffold [OPTIONS] [ARGS] +``` + +Additionally, you can view the parameters for the command using: +```bash +adev scaffold --help +``` + + +## Behaviour + +::: auto_dev.commands.scaffold.behaviour + options: + show_root_heading: false + show_source: false + show_signature: true + show_signature_annotations: true + docstring_style: sphinx + show_docstring_parameters: true + show_docstring_returns: false + show_docstring_raises: false + show_docstring_examples: true + docstring_section_style: table + heading_level: 2 +## Connection + +::: auto_dev.commands.scaffold.connection + options: + show_root_heading: false + show_source: false + show_signature: true + show_signature_annotations: true + docstring_style: sphinx + show_docstring_parameters: true + show_docstring_returns: false + show_docstring_raises: false + show_docstring_examples: true + docstring_section_style: table + heading_level: 2 +## Contract + +::: auto_dev.commands.scaffold.contract + options: + show_root_heading: false + show_source: false + show_signature: true + show_signature_annotations: true + docstring_style: sphinx + show_docstring_parameters: true + show_docstring_returns: false + show_docstring_raises: false + show_docstring_examples: true + docstring_section_style: table + heading_level: 2 +## Dao + +::: auto_dev.commands.scaffold.dao + options: + show_root_heading: false + show_source: false + show_signature: true + show_signature_annotations: true + docstring_style: sphinx + show_docstring_parameters: true + show_docstring_returns: false + show_docstring_raises: false + show_docstring_examples: true + docstring_section_style: table + heading_level: 2 +## Dialogues + +::: auto_dev.commands.scaffold.dialogues + options: + show_root_heading: false + show_source: false + show_signature: true + show_signature_annotations: true + docstring_style: sphinx + show_docstring_parameters: true + show_docstring_returns: false + show_docstring_raises: false + show_docstring_examples: true + docstring_section_style: table + heading_level: 2 +## Fsm + +::: auto_dev.commands.scaffold.fsm + options: + show_root_heading: false + show_source: false + show_signature: true + show_signature_annotations: true + docstring_style: sphinx + show_docstring_parameters: true + show_docstring_returns: false + show_docstring_raises: false + show_docstring_examples: true + docstring_section_style: table + heading_level: 2 +## Handler + +::: auto_dev.commands.scaffold.handler + options: + show_root_heading: false + show_source: false + show_signature: true + show_signature_annotations: true + docstring_style: sphinx + show_docstring_parameters: true + show_docstring_returns: false + show_docstring_raises: false + show_docstring_examples: true + docstring_section_style: table + heading_level: 2 +## Handlers + +::: auto_dev.commands.scaffold.handlers + options: + show_root_heading: false + show_source: false + show_signature: true + show_signature_annotations: true + docstring_style: sphinx + show_docstring_parameters: true + show_docstring_returns: false + show_docstring_raises: false + show_docstring_examples: true + docstring_section_style: table + heading_level: 2 +## Protocol + +::: auto_dev.commands.scaffold.protocol + options: + show_root_heading: false + show_source: false + show_signature: true + show_signature_annotations: true + docstring_style: sphinx + show_docstring_parameters: true + show_docstring_returns: false + show_docstring_raises: false + show_docstring_examples: true + docstring_section_style: table + heading_level: 2 +## Tests + +::: auto_dev.commands.scaffold.tests + options: + show_root_heading: false + show_source: false + show_signature: true + show_signature_annotations: true + docstring_style: sphinx + show_docstring_parameters: true + show_docstring_returns: false + show_docstring_raises: false + show_docstring_examples: true + docstring_section_style: table + heading_level: 2 \ No newline at end of file diff --git a/docs/commands/test.md b/docs/commands/test.md new file mode 100644 index 00000000..c3406245 --- /dev/null +++ b/docs/commands/test.md @@ -0,0 +1,27 @@ +## Description + +::: auto_dev.commands.test.test + options: + show_root_heading: false + show_source: false + show_signature: true + show_signature_annotations: true + docstring_style: sphinx + show_docstring_parameters: true + show_docstring_returns: false + show_docstring_raises: false + show_docstring_examples: true + docstring_section_style: table + heading_level: 2 + +## Usage + +```bash +adev test [OPTIONS] [ARGS] +``` + +Additionally, you can view the parameters for the command using: +```bash +adev test --help +``` + diff --git a/docs/contributing.md b/docs/contributing.md index e69de29b..9aa74ad2 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -0,0 +1,162 @@ +# Contributing + +Thanks for your interest in contributing to auto_dev! Please take a moment to review this document **before submitting a pull request.** + +If you want to contribute but aren't sure where to start, you can create a [new discussion](https://github.com/8ball030/auto_dev/discussions) or open an issue. + +## Get started + +This guide is intended to help you get started with contributing. By following these steps, you will understand the development process and workflow. + +- [Fork the repository](#fork-the-repository) +- [Install Python and Poetry](#install-python-and-poetry) +- [Install dependencies](#install-dependencies) +- [Build the project](#build-the-project) +- [Write documentation](#write-documentation) +- [Submit a pull request](#submit-a-pull-request) +- [That's it!](#thats-it) + +
+ +--- + +
+ +## Fork the repository + +To start contributing to the project, [create a fork](https://github.com/8ball030/auto_dev/fork) and clone it to your machine using `git clone`. + +Or, use the [GitHub CLI](https://cli.github.com) to create a fork and clone it in one command: + +```bash +gh repo fork 8ball030/auto_dev --clone +``` + +
+ ↑ back to top +
+ +## Install Python and Poetry + +auto_dev uses [Poetry](https://python-poetry.org/) for dependency management. You need to install **Python 3.9 or higher** and **Poetry < 2.0**. + +You can run the following commands in your terminal to check your local Python and Poetry versions: + +```bash +python --version +poetry --version +``` + +If the versions are not correct or you don't have Python or Poetry installed: + +- Install Python from the [official website](https://python.org) or using [pyenv](https://github.com/pyenv/pyenv) +- Install [Poetry](https://python-poetry.org/docs/#installation) + +
+ ↑ back to top +
+ +## Install dependencies + +In the root directory, run the following command to install the project's dependencies: + +```bash +poetry install +``` + +
+ ↑ back to top +
+ +## Build the project + +In the root directory, run the build command: + +```bash +pip install -e . +``` + +
+ ↑ back to top +
+ + +When adding new features or fixing bugs, it's important to add test cases in /tests to cover any new or updated behavior. + +### Code Quality Checks + +Before pushing your changes, make sure to run the following quality checks: + +```bash +# Format code +make fmt + +# Run linting checks +make lint + +# Run tests +make test +``` + +These commands will ensure your code: +- Follows the project's formatting standards +- Passes all linting rules +- Successfully runs all tests + +Running these checks locally before pushing will help catch issues early and speed up the review process. + +
+ ↑ back to top +
+ +## Write documentation + +auto_dev uses [MkDocs](https://www.mkdocs.org/) with Material theme for the documentation website. To start the docs website in dev mode, run: + +```bash +poetry run mkdocs serve +``` + +
+ ↑ back to top +
+ +## Submit a pull request + +When you're ready to submit a pull request, follow these naming conventions: + +- Pull request titles use the [imperative mood](https://en.wikipedia.org/wiki/Imperative_mood) (e.g., `Add something`, `Fix something`). +- Commit messages should be clear and descriptive. + +When you submit a pull request, GitHub Actions will automatically lint, build, and test your changes. If you see an ❌, it's most likely a problem with your code. Inspect the logs through the GitHub Actions UI to find the cause. + +
+ ↑ back to top +
+ +## That's it! + +If you still have questions, please create a [new issue](https://github.com/8ball030/auto_dev/issues). + + +## Project Contributors + +Thank you to all our contributors! + +
+ + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/docs/hooks.py b/docs/hooks.py new file mode 100644 index 00000000..9758ae97 --- /dev/null +++ b/docs/hooks.py @@ -0,0 +1,75 @@ +"""MkDocs hooks for documentation generation.""" + +import re +import shutil +from typing import Any +from pathlib import Path + +from mkdocs.config import Config +from mkdocs.structure.files import Files + + +def _clean_temp_files() -> None: + """Clean temporary files.""" + temp_files = [ + "docs/api/auto_dev.md", + "docs/api/fsm.md", + "docs/api/handler.md", + "docs/api/protocols.md", + "docs/api/dao.md", + ] + for file in temp_files: + path = Path(file) + if path.exists(): + path.unlink() + + +def _copy_readme() -> None: + """Copy README.md to docs/index.md.""" + readme_path = Path("README.md") + if not readme_path.exists(): + return + shutil.copy("README.md", "docs/index.md") + + +def _process_api_docs() -> None: + """Process API documentation files.""" + api_files = { + "docs/api/auto_dev.md": ( + "# Auto Dev API\n\n::: auto_dev.commands.create\n::: auto_dev.commands.deps\n" + "::: auto_dev.commands.fmt\n::: auto_dev.commands.improve\n::: auto_dev.commands.lint\n" + "::: auto_dev.commands.metadata\n::: auto_dev.commands.publish\n::: auto_dev.commands.release\n" + "::: auto_dev.commands.repo\n::: auto_dev.commands.run\n::: auto_dev.commands.scaffold\n" + "::: auto_dev.commands.test\n" + ), + "docs/api/fsm.md": "# FSM API\n\n::: auto_dev.fsm.fsm\n", + "docs/api/handler.md": "# Handler API\n\n::: auto_dev.handler.scaffolder\n", + "docs/api/protocols.md": "# Protocols API\n\n::: auto_dev.protocols.scaffolder\n", + "docs/api/dao.md": "# DAO API\n\n::: auto_dev.dao.scaffolder\n", + } + + for file_path, content in api_files.items(): + Path(file_path).write_text(content, encoding="utf-8") + + +def _process_command_docs() -> None: + """Process command documentation files.""" + command_files = Path("docs/commands").glob("*.md") + for file in command_files: + content = file.read_text() + processed_content = re.sub(r"```\n\n```", "```", content) + file.write_text(processed_content) + + +def on_config(config: Config, **_: Any) -> Config: + """Process configuration before running builds.""" + _clean_temp_files() + _copy_readme() + _process_api_docs() + _process_command_docs() + return config + + +def on_files(files: Files, **_: Any) -> Files: + """Process files before running builds.""" + return files diff --git a/docs/index.md b/docs/index.md index 925533ac..e8dccf40 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,3 +1,3 @@ -{% - include-markdown "../README.md" -%} +{% + include-markdown "../README.md" +%} \ No newline at end of file diff --git a/docs/usage.md b/docs/usage.md index 30ad787b..8ca9c39c 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -1,4 +1,74 @@ -# Usage +# Usage Overview + +Auto Dev provides a comprehensive set of tools for automating development tasks. This guide will help you understand how to use the main features effectively. + +## Basic Usage + +The basic command structure is: + +```bash +adev [options] [arguments] +``` + +For example: +```bash +# Create a new project +adev create my-project + +# Run development tasks +adev run + +# Format code +adev fmt +``` + +## Common Workflows + +### 1. Starting a New Project + +```bash +# Create a new project +adev repo scaffold my-project + +# Change to project directory +cd my-project + +# Initialize git repository + adev create -t eightballer/frontend_agent new_author/new_agent --no-clean-up + + + +# Set up development environment +adev scaffold +``` + +### 2. Development Workflow + +```bash +# Format code +adev fmt + +# Run linting +adev lint + +# Run tests +adev test +``` + +## Advanced Features + +For more advanced features, check out: +- [FSM](fsm.md) for Finite State Machine functionality +- [OpenAPI](openapi.md) for API development tools + +## Getting Help + +You can get help for any command using the `--help` flag: + +```bash +adev --help +adev --help +``` ## Installation diff --git a/mkdocs.yml b/mkdocs.yml index 54d6b0c4..291ca63f 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -3,6 +3,11 @@ site_url: https://8ball030.github.io/auto_dev repo_url: https://github.com/8ball030/auto_dev repo_name: 8ball030/auto_dev #strict: true + +hooks: + - scripts/generate_command_docs.py + +# Optimized navigation structure nav: - Home: index.md - Installation: installation.md @@ -10,30 +15,31 @@ nav: - Overview: usage.md - FSM: fsm.md - OpenAPI: openapi.md - - API Reference: - - Overview: api/index.md - - auto_dev: api/auto_dev.md - - Commands: api/commands.md - - Connections: api/connections.md - - Contracts: api/contracts.md - - FSM: api/fsm.md - - Handler: api/handler.md - - Protocols: api/protocols.md - - Utils: api/utils.md - - Constants: api/constants.md + - DAO: dao.md + - Commands: + - run: commands/run.md + - create: commands/create.md + - lint: commands/lint.md + - publish: commands/publish.md + - test: commands/test.md + - improve: commands/improve.md + - release: commands/release.md + - metadata: commands/metadata.md + - fmt: commands/fmt.md + - scaffold: commands/scaffold.md + - deps: commands/deps.md + - convert: commands/convert.md + - repo: commands/repo.md + - fsm: commands/fsm.md + - augment: commands/augment.md - Contributing: contributing.md - Changelog: changelog.md + theme: name: material language: en #logo: assets/logo.png palette: - # Automatic mode - - media: "(prefers-color-scheme)" - toggle: - icon: material/brightness-auto - name: Switch to light mode - # Light mode - media: "(prefers-color-scheme: light)" scheme: default accent: blue @@ -41,68 +47,67 @@ theme: toggle: icon: material/weather-night name: Switch to dark mode - # Dark mode - media: "(prefers-color-scheme: dark)" scheme: slate accent: blue primary: blue_grey toggle: icon: material/weather-sunny - name: Switch to system preference + name: Switch to light mode font: code: Roboto Mono text: Source Sans Pro features: - - navigation.indexes - navigation.instant - - navigation.tabs.sticky - navigation.expand + - navigation.sections + - navigation.top + - toc.follow + - navigation.indexes + - search.suggest + - search.highlight - content.code.copy + - content.tabs.link + markdown_extensions: - - pymdownx.emoji - - pymdownx.critic - - pymdownx.caret - - pymdownx.mark - - pymdownx.tilde - - pymdownx.tabbed - - attr_list - - pymdownx.arithmatex: - generic: true - pymdownx.highlight: - linenums: false anchor_linenums: true line_spans: __span pygments_lang_class: true - pymdownx.superfences - pymdownx.inlinehilite - - pymdownx.details - admonition - toc: - baselevel: 3 permalink: true - slugify: !!python/name:pymdownx.slugs.uslugify - - meta - - pymdownx.superfences: - # make exceptions to highlighting of code: - custom_fences: - - name: mermaid - class: mermaid - format: !!python/name:mermaid2.fence_mermaid_custom + toc_depth: 3 + baselevel: 1 + - attr_list + - pymdownx.snippets: + base_path: . + - pymdownx.details + - pymdownx.tabbed: + alternate_style: true + - pymdownx.caret + - pymdownx.mark + - pymdownx.tilde + plugins: + - search - include-markdown - - search: - lang: en - - autorefs - mkdocstrings: default_handler: python handlers: python: - paths: [auto_dev] - options: + selection: + docstring_style: sphinx + rendering: show_root_heading: true show_source: false - show_submodules: true - docstring_style: sphinx + show_signature_annotations: true + members_order: source + docstring_section_style: list + paths: [auto_dev] + extra_css: - stylesheets/extra.css extra: diff --git a/pyproject.toml b/pyproject.toml index a7a8e65c..396570fc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -108,3 +108,4 @@ doc = [ [tool.poetry.scripts] adev = "auto_dev.cli:cli" +gen-docs = "scripts.generate_command_docs:main" diff --git a/scripts/__init__.py b/scripts/__init__.py new file mode 100644 index 00000000..d83c74e9 --- /dev/null +++ b/scripts/__init__.py @@ -0,0 +1 @@ +"""Scripts package for auto_dev.""" diff --git a/scripts/generate_command_docs.py b/scripts/generate_command_docs.py new file mode 100644 index 00000000..40f71d5b --- /dev/null +++ b/scripts/generate_command_docs.py @@ -0,0 +1,202 @@ +"""Script to generate command documentation. + +This module handles the automatic generation of documentation for all CLI commands +in the auto_dev project. It uses introspection to discover commands and their +subcommands, then generates markdown documentation with proper formatting. +""" + +import logging +from pathlib import Path +from importlib import import_module +from dataclasses import dataclass + +import click + + +# Configure logging +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + +# Command configuration +COMMANDS = [ + "run", + "create", + "lint", + "publish", + "test", + "improve", + "release", + "metadata", + "fmt", + "scaffold", + "deps", + "convert", + "repo", + "fsm", + "augment", +] + + +@dataclass +class DocTemplates: + """Templates for documentation generation.""" + + COMMAND = """## Description + +::: auto_dev.commands.{command_name}.{command_name} + options: + show_root_heading: false + show_source: false + show_signature: true + show_signature_annotations: true + docstring_style: sphinx + show_docstring_parameters: true + show_docstring_returns: false + show_docstring_raises: false + show_docstring_examples: true + docstring_section_style: table + heading_level: 2 + +## Usage + +```bash +adev {command_name} [OPTIONS] [ARGS] +``` + +Additionally, you can view the parameters for the command using: +```bash +adev {command_name} --help +``` + +{subcommands}""" + + SUBCOMMAND = """ +## {subcommand_title} + +::: auto_dev.commands.{command_name}.{subcommand_func} + options: + show_root_heading: false + show_source: false + show_signature: true + show_signature_annotations: true + docstring_style: sphinx + show_docstring_parameters: true + show_docstring_returns: false + show_docstring_raises: false + show_docstring_examples: true + docstring_section_style: table + heading_level: 2""" + + +class CommandDocGenerator: + """Handles the generation of command documentation.""" + + def __init__(self, docs_dir: Path): + """Initialize the generator with output directory.""" + self.docs_dir = docs_dir + self.templates = DocTemplates() + + def find_function_name(self, module, cmd_name: str) -> str | None: + """Find the actual function name in the module for a given command name. + + Args: + ---- + module: The imported module to search + cmd_name: The command name to find + + Returns: + ------- + The function name if found, None otherwise + + """ + for attr_name, attr_value in module.__dict__.items(): + if isinstance(attr_value, click.Command) and attr_value.name == cmd_name: + return attr_name + return None + + def get_subcommands(self, command_name: str) -> list[tuple[str, str]]: + """Discover subcommands for a given command by inspecting its module. + + Args: + ---- + command_name: Name of the command to inspect + + Returns: + ------- + List of tuples containing (command_name, function_name) + + """ + try: + module = import_module(f"auto_dev.commands.{command_name}") + except ImportError as e: + logger.warning(f"Could not import command module {command_name}: {e}") + return [] + + # Get the command group function + group_func = getattr(module, command_name, None) + if not group_func or not isinstance(group_func, click.Group): + return [] + + # Get commands directly from the Click group + subcommands = [] + for cmd_name, cmd in group_func.commands.items(): + if not isinstance(cmd, click.Command) or isinstance(cmd, click.Group): + continue + + func_name = self.find_function_name(module, cmd_name) + if func_name: + subcommands.append((cmd_name, func_name)) + + return sorted(subcommands) + + def generate_command_doc(self, command: str) -> None: + """Generate documentation for a single command. + + Args: + ---- + command: Name of the command to document + + """ + doc_path = self.docs_dir / f"{command}.md" + subcommands = self.get_subcommands(command) + + # Generate subcommand documentation + subcommands_text = "" + for cmd_name, func_name in subcommands: + subcommands_text += self.templates.SUBCOMMAND.format( + subcommand_title=cmd_name.replace("-", " ").title(), command_name=command, subcommand_func=func_name + ) + + try: + doc_path.write_text( + self.templates.COMMAND.format(command_name=command, subcommands=subcommands_text), encoding="utf-8" + ) + logger.info(f"Generated documentation for {command}") + except OSError as e: + logger.exception(f"Failed to write documentation for {command}: {e}") + + +def main() -> None: + """Generate documentation for all commands.""" + docs_dir = Path("docs/commands") + assets_dir = Path("docs/assets") + + # Preserve assets directory if it exists + if assets_dir.exists(): + logger.info("Preserving existing docs/assets directory") + try: + docs_dir.mkdir(parents=True, exist_ok=True) + except OSError as e: + logger.exception(f"Failed to create docs directory: {e}") + return + + generator = CommandDocGenerator(docs_dir) + for command in COMMANDS: + try: + generator.generate_command_doc(command) + except Exception as e: + logger.exception(f"Failed to generate documentation for {command}: {e}") + + +if __name__ == "__main__": + main() diff --git a/tests/conftest.py b/tests/conftest.py index dcdf3256..e625318c 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -15,9 +15,21 @@ AUTONOMY_PACKAGES_FILE, ) from auto_dev.cli_executor import CommandExecutor +from scripts.generate_command_docs import main as generate_docs from auto_dev.services.package_manager.index import PackageManager +@pytest.fixture +def generated_docs(test_filesystem): + """Fixture to ensure documentation is generated before tests.""" + # Generate the documentation + (Path(test_filesystem) / "docs").mkdir(parents=True, exist_ok=True) + generate_docs() + + # Return the docs directory path + return Path("docs/commands") + + OPENAPI_TEST_CASES = [ ("uspto.yaml", ["handle_get_", "handle_get_dataset_version_fields", "handle_post_dataset_version_records"]), ("petstore.yaml", ["handle_get_pets", "handle_post_pets", "handle_get_pets_petId"]), diff --git a/tests/test_doc_generation.py b/tests/test_doc_generation.py new file mode 100644 index 00000000..10065b57 --- /dev/null +++ b/tests/test_doc_generation.py @@ -0,0 +1,37 @@ +"""Test documentation generation.""" + +from pathlib import Path + + +def check_documentation_exists(source_files: list[Path], docs_dir: Path, file_type: str): + """Check that documentation exists and is valid for given source files.""" + for source_file in source_files: + doc_file = docs_dir / f"{source_file.stem}.md" + assert doc_file.exists(), f"Documentation missing for {file_type} {source_file.stem}" + + # Check that the documentation file is not empty + assert doc_file.stat().st_size > 0, f"Documentation is empty for {file_type} {source_file.stem}" + + # Read the doc file and check for basic content + content = doc_file.read_text() + assert "# " in content, f"Documentation lacks title for {file_type} {source_file.stem}" + assert "## " in content, f"Documentation lacks sections for {file_type} {source_file.stem}" + + +def test_all_endpoints_documented(generated_docs): + """Test that all command and API endpoints are documented.""" + # Get all Python files in the commands directory + commands_dir = Path("auto_dev/commands") + command_files = list(commands_dir.glob("*.py")) + command_files = [f for f in command_files if f.stem not in {"__init__", "__pycache__"}] + + # Get all Python files in the API directory + api_dir = Path("auto_dev/api") + api_files = list(api_dir.glob("*.py")) + api_files = [f for f in api_files if f.stem not in {"__init__", "__pycache__"}] + + # Check command documentation + check_documentation_exists(command_files, generated_docs, "command") + + # Check API documentation + check_documentation_exists(api_files, Path("docs/api"), "API endpoint")