Architecture

The scaffolder converts a compact JSON description into a complete Octopus widget repository by coordinating three concerns: input handling, generation logic, and templated assets. Understanding how the layers interact makes it easier to extend the system or debug generation failures.

High-Level Flow

  1. Entry points (octopus_widget_scaffolder.py, app.py) validate the request, normalise widget metadata, and assemble the generator context.

  2. Generator services in scaffolder.generator orchestrate filesystem writes, GraphQL document preparation, and archive creation.

  3. Template assets under templates/ define the React widget skeleton, Octopus configuration schema, and CI workflows.

UI / CLI request → context building → template rendering → output directory + zip

Entry Points

  • The CLI parses flags with argparse, supports inline GraphQL definitions, and accepts JSON payloads from either files or the command line. When running in automation, the exit code reflects success or failure of the generation step.

  • The FastAPI UI exposes /generate and /download/<zip>. Streaming responses allow the browser to surface progress messages immediately, making the UI feel responsive even while templates are rendering on disk.

Generation Services

scaffold_widget is the central coordinator:

  • Applies naming strategies (Pascal, kebab, camel, screaming snake) so every template placeholder resolves consistently.

  • Invokes widget_generator.generate_widget to build the React component with the correct mix of hooks, configuration types, and mutation helpers.

  • Calls utils.render_templates to walk the template tree, substitute placeholders, and write files atomically. Failed renders do not leave partial files behind, reducing cleanup work during development.

  • Compresses the output folder into a downloadable zip using shutil.make_archive.

Tip

Test Auto-Build Widget Step shows the resulting widget being loaded by the Octopus dashboard frontend if you want to see the generator output in context.

GraphQL Operation Preparation

Helper functions in scaffolder.utils enrich the operations supplied in JSON:

  • Automatically injects header and variable definitions so the generated TypeScript compiles without manual tweaks.

  • Normalises indentation and quoting to produce readable GraphQL documents.

  • Derives TypeScript typings used by the widget state and configuration forms.

Template Rendering

Templates rely on Jinja-style placeholders:

  • {{ PASCAL }}, {{ CAMEL }}, {{ KEBAB }}: naming schemes.

  • {{ DEFAULT_CFG }}: serialised JSON providing default configuration values.

  • {{ SCHEMA }}: Ajv-compatible JSON schema for dashboard validation.

  • {{ APP_ID }}: the downstream GitLab project identifier for CI integration.

Keep templates version-controlled. Unit tests assert that every expected file is rendered and that placeholder maps are complete, so template changes often require corresponding test updates under tests/test_templates.py.

Extending the System

  • Add shared utilities to scaffolder.utils to reuse logic across both generators and future tooling.

  • Introduce new CLI arguments by extending the JSON schema consumed by both the CLI and UI. This keeps the interfaces aligned and avoids drift.

  • When adding files to the template tree, provide representative fixtures so the tests and the documentation remain accurate.

Tip

Treat the generated widget as an external contract. Changes in templates should be reflected in the README snippet, example commands, and any screenshots you capture for these docs.