mirror of
https://github.com/ChristianLempa/boilerplates.git
synced 2026-08-24 02:24:14 -05:00
chore: ignore local documentation symlinks
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
# Ignore local development files
|
||||
**/.vscode
|
||||
**/.DS_Store
|
||||
/AGENTS.md
|
||||
/docs
|
||||
|
||||
# Docker Secrets, Environment Files
|
||||
**/secret.*
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
# AGENTS.md
|
||||
|
||||
Guidance for AI coding agents working in this repository.
|
||||
|
||||
## Project
|
||||
|
||||
Project name: Boilerplates CLI
|
||||
|
||||
A Python CLI for managing infrastructure boilerplates, template libraries, template rendering, and validation. Built with Typer and Jinja2.
|
||||
|
||||
## Scope and precedence
|
||||
|
||||
- This file applies to the repository tree rooted at the directory containing this `AGENTS.md` file.
|
||||
- More deeply nested `AGENTS.md` files may add or override instructions for their subtrees.
|
||||
- Before GitHub-facing work such as issues, branches, PRs, merges, tags, or releases, read this file and the relevant docs listed below.
|
||||
- For release-related work, always read `RELEASE.md` first.
|
||||
|
||||
## Repository map
|
||||
|
||||
- Source: `cli/` - main CLI application and core runtime code.
|
||||
- Tests: `tests/` - automated tests, fixtures, and test utilities.
|
||||
- Contribution guide: `CONTRIBUTING.md` - setup, validation, GitHub workflow, and command overview.
|
||||
- Docs: `docs/` - developer documentation and architecture notes.
|
||||
- Release process: `RELEASE.md` - release PR, version, changelog, tag, and publish workflow.
|
||||
- Scripts: `scripts/` - installer and helper scripts.
|
||||
- GitHub automation: `.github/` - workflows, issue/PR templates, and repository scripts.
|
||||
- Legacy library: `library/` - backward-compatibility template content for versions older than `0.2.0`; not the canonical modern template library.
|
||||
|
||||
## Documentation
|
||||
|
||||
Project documentation lives in `docs/`.
|
||||
|
||||
Agents should read the relevant docs before making changes and update docs when behavior, configuration, or workflows change.
|
||||
|
||||
### Documentation map
|
||||
|
||||
- `docs/architecture.md` - repository layout, module system, and core runtime components
|
||||
- `docs/templates.md` - template format, variables, rendering, and validation behavior
|
||||
- `docs/libraries.md` - library configuration and canonical external template library guidance
|
||||
- `docs/display.md` - DisplayManager and CLI output rules
|
||||
|
||||
## Validation
|
||||
|
||||
Default checks before finishing code changes:
|
||||
|
||||
```bash
|
||||
ruff check --fix .
|
||||
ruff format .
|
||||
python3 -m pytest
|
||||
```
|
||||
|
||||
See `CONTRIBUTING.md` for setup and workflow details.
|
||||
|
||||
## Project conventions
|
||||
|
||||
- Follow existing project structure, naming, and patterns before introducing new ones.
|
||||
- Keep changes focused on the requested task; avoid unrelated refactors or broad rewrites.
|
||||
- When adding or changing behavior, update relevant docs and tests where practical.
|
||||
- Do not commit secrets, tokens, private keys, or environment-specific credentials.
|
||||
- Use custom exceptions from `cli/core/exceptions.py` for user-facing errors where applicable.
|
||||
- Use `DisplayManager` for user-facing command output; never print directly from command, module, config, repository, validation, or template-rendering code. See `docs/display.md`.
|
||||
- Do not treat `library/` as the canonical source for current template work. For `0.2.0+`, active templates live in the separate `boilerplates-library` repository. See `docs/libraries.md`.
|
||||
- When answering which template kinds are supported, prefer registered modules in `cli/modules/` over legacy library contents.
|
||||
@@ -1,93 +0,0 @@
|
||||
# Architecture Notes
|
||||
|
||||
## Repository layout
|
||||
|
||||
- `cli/` - Python CLI application source code
|
||||
- `cli/core/` - core runtime packages
|
||||
- `cli/modules/` - technology-specific module registrations
|
||||
- `cli/__main__.py` - CLI entry point; discovers modules and registers commands
|
||||
- `tests/` - automated tests
|
||||
- `docs/` - developer documentation
|
||||
- `scripts/` - helper scripts, including installer tooling
|
||||
- `library/` - legacy in-repo template content for versions older than `0.2.0`; do not treat it as the canonical template library for modern work
|
||||
- `.github/` - workflows, templates, and repository automation
|
||||
|
||||
## Supported kinds
|
||||
|
||||
The supported kinds are the registered modules in `cli/modules/`. Prefer this code-level list over legacy content in `library/`.
|
||||
|
||||
Current kinds:
|
||||
|
||||
- `ansible`
|
||||
- `bash`
|
||||
- `compose`
|
||||
- `helm`
|
||||
- `kubernetes`
|
||||
- `packer`
|
||||
- `python`
|
||||
- `static`
|
||||
- `swarm`
|
||||
- `terraform`
|
||||
|
||||
## Module system
|
||||
|
||||
Modules subclass `Module` from `cli/core/module/` and register themselves with the central registry.
|
||||
|
||||
Minimal module example:
|
||||
|
||||
```python
|
||||
from ...core.module import Module
|
||||
from ...core.registry import registry
|
||||
|
||||
|
||||
class ExampleModule(Module):
|
||||
name = "example"
|
||||
description = "Manage example templates"
|
||||
|
||||
|
||||
registry.register(ExampleModule)
|
||||
```
|
||||
|
||||
Discovery and registration flow:
|
||||
|
||||
1. `cli/__main__.py` imports module packages/files from `cli/modules/`.
|
||||
2. Each module calls `registry.register(ModuleClass)` at import time.
|
||||
3. The registry stores module classes by module name.
|
||||
4. The CLI framework creates standard commands for every registered module.
|
||||
5. Modules are instantiated on demand when commands run.
|
||||
|
||||
Benefits:
|
||||
|
||||
- No central manual registration for new kinds
|
||||
- Modules are self-contained
|
||||
- Registry validation catches invalid module classes early
|
||||
|
||||
## Core components
|
||||
|
||||
Important packages/files:
|
||||
|
||||
- `cli/core/module/` - base module class and standard command implementations
|
||||
- `cli/core/template/` - template manifest parsing, variable normalization, rendering, and validation
|
||||
- `cli/core/config/` - user configuration loading, saving, validation, and migration
|
||||
- `cli/core/library.py` - template discovery across git/static libraries
|
||||
- `cli/core/repo.py` - repository/library management commands
|
||||
- `cli/core/registry.py` - module registry
|
||||
- `cli/core/display/` - centralized CLI output rendering; see `docs/display.md`
|
||||
- `cli/core/validation/` - dependency matrix and kind-specific rendered-file validators
|
||||
- `cli/core/validators.py` - generic content validators such as YAML and Docker Compose validation
|
||||
- `cli/core/exceptions.py` - custom exceptions; prefer these for user-facing errors
|
||||
|
||||
## Prompt/input flow
|
||||
|
||||
Interactive prompting is implemented with Rich-based input helpers under `cli/core/input/`.
|
||||
|
||||
Prompt support includes:
|
||||
|
||||
- text input
|
||||
- password/secret input
|
||||
- yes/no confirmation
|
||||
- numbered choice selection
|
||||
- defaults from template/config/CLI sources
|
||||
- autogenerated secret placeholders
|
||||
|
||||
Use `--no-interactive` to skip prompts and use defaults, config values, CLI overrides, or empty values as appropriate.
|
||||
@@ -1,56 +0,0 @@
|
||||
# Display and Output Rules
|
||||
|
||||
## Critical rule
|
||||
|
||||
User-facing command output should go through `DisplayManager` or one of the display classes under `cli/core/display/`.
|
||||
|
||||
Do not:
|
||||
|
||||
- call `console.print()` from command, module, config, repository, validation, or template-rendering code
|
||||
- import `Console` from `rich.console` for general command output outside display classes or `cli/__main__.py`
|
||||
- use direct emojis or icons in feature code
|
||||
- bypass display helpers for status, errors, warnings, tables, or template output
|
||||
|
||||
Do:
|
||||
|
||||
- use `module_instance.display` in module/command code
|
||||
- use `DisplayManager()` when standalone core command code needs output
|
||||
- add or adjust display helpers in `cli/core/display/` when new output patterns are needed
|
||||
- add shortcode/icon mappings in the display/icon layer
|
||||
|
||||
## Rationale
|
||||
|
||||
Centralized display handling keeps CLI output consistent and makes it easier to manage:
|
||||
|
||||
- formatting standards
|
||||
- quiet/verbose behavior
|
||||
- stderr/stdout routing
|
||||
- icon and Nerd Font usage
|
||||
- table rendering
|
||||
- error/warning/success styles
|
||||
|
||||
## Display architecture
|
||||
|
||||
`DisplayManager` acts as a facade over focused display components.
|
||||
|
||||
Current responsibilities include:
|
||||
|
||||
- variable rendering and variable tables
|
||||
- template metadata and file-tree rendering
|
||||
- status, error, warning, success, and info messages
|
||||
- data/status/config tables
|
||||
- markdown/description rendering
|
||||
|
||||
External code should call facade methods on `DisplayManager`. Internally, the facade delegates to specialized display classes.
|
||||
|
||||
Example:
|
||||
|
||||
```python
|
||||
display = DisplayManager()
|
||||
display.success("Template generated")
|
||||
display.error("Validation failed", details="Missing variable")
|
||||
```
|
||||
|
||||
If a needed display method does not exist, add one to the display layer instead of printing directly from feature code.
|
||||
|
||||
Prompt/input internals under `cli/core/input/` may use Rich prompt primitives directly when implementing interactive input behavior. Keep regular command output in the display layer.
|
||||
@@ -1,109 +0,0 @@
|
||||
# Library and Configuration Notes
|
||||
|
||||
## Canonical template library
|
||||
|
||||
The canonical template library does **not** live in this repository for modern development.
|
||||
|
||||
- The checked-in `library/` directory is legacy/backward-compatibility content for versions older than `0.2.0`.
|
||||
- For `0.2.0+`, active template work belongs in the separate GitHub repository `boilerplates-library`.
|
||||
|
||||
When answering questions about supported kinds or current template behavior, prefer code under `cli/modules/` and runtime logic under `cli/core/` over legacy `library/` content.
|
||||
|
||||
## LibraryManager
|
||||
|
||||
`LibraryManager` loads configured libraries and discovers templates by kind.
|
||||
|
||||
Responsibilities:
|
||||
|
||||
- load library configuration
|
||||
- resolve git and static library paths
|
||||
- discover template directories containing `template.json`
|
||||
- normalize template IDs from manifest slugs
|
||||
- handle duplicate template IDs
|
||||
- preserve library priority order
|
||||
|
||||
Git libraries are stored under:
|
||||
|
||||
```text
|
||||
~/.config/boilerplates/libraries/{name}/
|
||||
```
|
||||
|
||||
Git-based libraries use sparse checkout to avoid cloning unrelated repository content where possible.
|
||||
|
||||
## Library types
|
||||
|
||||
### Git libraries
|
||||
|
||||
Git libraries require:
|
||||
|
||||
- `name`
|
||||
- `type: git`
|
||||
- `url`
|
||||
- `branch`
|
||||
- `directory`
|
||||
|
||||
### Static libraries
|
||||
|
||||
Static libraries require:
|
||||
|
||||
- `name`
|
||||
- `type: static`
|
||||
- `path`
|
||||
|
||||
Static library paths may be absolute or relative to the config file location. Some config entries may include backward-compatible dummy `url`, `branch`, and `directory` fields.
|
||||
|
||||
## Priority and duplicate handling
|
||||
|
||||
Library priority is determined by config order. Earlier entries have higher priority.
|
||||
|
||||
Duplicate behavior:
|
||||
|
||||
- duplicate IDs within the same library raise a duplicate-template error
|
||||
- duplicate IDs across libraries can be addressed with qualified IDs
|
||||
- simple IDs resolve to the highest-priority library
|
||||
- qualified IDs target a specific library, for example `alloy.default` or `alloy.local`
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
boilerplates compose show alloy
|
||||
boilerplates compose show alloy.local
|
||||
```
|
||||
|
||||
## Config location
|
||||
|
||||
User config is stored at:
|
||||
|
||||
```text
|
||||
~/.config/boilerplates/config.yaml
|
||||
```
|
||||
|
||||
Example library config:
|
||||
|
||||
```yaml
|
||||
libraries:
|
||||
- name: default
|
||||
type: git
|
||||
url: https://github.com/user/templates.git
|
||||
branch: main
|
||||
directory: library
|
||||
- name: local
|
||||
type: static
|
||||
path: ~/my-templates
|
||||
url: ''
|
||||
branch: main
|
||||
directory: .
|
||||
```
|
||||
|
||||
## Repository commands
|
||||
|
||||
Common library commands:
|
||||
|
||||
```bash
|
||||
boilerplates repo list
|
||||
boilerplates repo update
|
||||
boilerplates repo add local --type static --path ~/my-templates
|
||||
boilerplates repo remove local
|
||||
```
|
||||
|
||||
Use `DisplayManager` for all output in repository/config code. Do not print directly.
|
||||
@@ -1,157 +0,0 @@
|
||||
# Template Authoring Notes
|
||||
|
||||
Templates are directory-based. Each template directory contains `template.json` plus a required `files/` directory with renderable content.
|
||||
|
||||
## Template loading and rendering flow
|
||||
|
||||
1. `LibraryManager` finds template directories containing `template.json`.
|
||||
2. `Template` loads and validates manifest metadata.
|
||||
3. Manifest variables are normalized into the runtime variable collection shape.
|
||||
4. Defaults are merged from template, user config, var-files, and CLI overrides.
|
||||
5. Sections are sorted and dependency constraints are validated.
|
||||
6. Variables are resolved dynamically according to `needs` constraints.
|
||||
7. Files under `files/` render through the custom-delimiter Jinja environment.
|
||||
8. Rendered output is sanitized.
|
||||
9. Optional semantic or kind-specific validation runs.
|
||||
|
||||
## Template structure
|
||||
|
||||
Minimal `template.json` shape:
|
||||
|
||||
```json
|
||||
{
|
||||
"slug": "my-template",
|
||||
"kind": "compose",
|
||||
"metadata": {
|
||||
"name": "My Template",
|
||||
"description": "A template description.",
|
||||
"version": {
|
||||
"name": "v1.0.0"
|
||||
}
|
||||
},
|
||||
"variables": [
|
||||
{
|
||||
"name": "general",
|
||||
"title": "General",
|
||||
"items": [
|
||||
{
|
||||
"name": "service_name",
|
||||
"type": "str",
|
||||
"title": "Service name",
|
||||
"default": "demo"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Template delimiters
|
||||
|
||||
For `0.2.0+`, templates use custom Jinja-like delimiters:
|
||||
|
||||
- Variables: `<< variable_name >>`
|
||||
- Blocks: `<% if condition %> ... <% endif %>`
|
||||
- Comments: `<# comment #>`
|
||||
|
||||
Default Jinja delimiters such as `{{ variable }}` are intentionally left untouched so downstream tools like Ansible can use them literally.
|
||||
|
||||
Legacy `.j2` behavior is no longer supported for new `template.json` templates. Renderable content lives under `files/`, and output paths match the relative paths under `files/`.
|
||||
|
||||
## Metadata versioning
|
||||
|
||||
`metadata.version` is a structured object and may be partial. Supported fields include:
|
||||
|
||||
- `name`
|
||||
- `source_dep_name`
|
||||
- `source_dep_version`
|
||||
- `source_dep_digest`
|
||||
- `upstream_ref`
|
||||
- `notes`
|
||||
|
||||
This separates the user-facing template version label from tracked upstream dependency metadata.
|
||||
|
||||
## Application versions
|
||||
|
||||
Application/image versions should generally be hardcoded in template files, for example:
|
||||
|
||||
```yaml
|
||||
image: nginx:1.25.3
|
||||
```
|
||||
|
||||
Do not create variables such as `nginx_version` unless there is a strong technical reason, such as multi-component version pinning. Hardcoding tested versions avoids mismatches between variables and validated template output.
|
||||
|
||||
## Variables
|
||||
|
||||
Variable precedence, lowest to highest:
|
||||
|
||||
1. Template defaults from `template.json`
|
||||
2. User config defaults
|
||||
3. Var-file values
|
||||
4. CLI `--var` overrides
|
||||
|
||||
Variable types:
|
||||
|
||||
- `str`
|
||||
- `int`
|
||||
- `float`
|
||||
- `bool`
|
||||
- `email`
|
||||
- `url`
|
||||
- `hostname`
|
||||
- `enum`
|
||||
- `secret`
|
||||
|
||||
Common variable properties:
|
||||
|
||||
- `default` - default value
|
||||
- `title` - prompt/display title
|
||||
- `description` - description/help text
|
||||
- `required` - require non-empty value
|
||||
- `needs` - conditional visibility constraint
|
||||
- `config.options` - enum options
|
||||
- `config.placeholder` - input placeholder
|
||||
- `config.autogenerated` - secret autogeneration settings
|
||||
|
||||
## Sections and dependencies
|
||||
|
||||
Variable groups become sections. Sections can define:
|
||||
|
||||
- `toggle` - auto-created boolean variable that enables/disables the section
|
||||
- `needs` - section dependency by section key
|
||||
|
||||
Variable-level `needs` constraints use this format:
|
||||
|
||||
- `var_name=value`
|
||||
- `var_name!=value`
|
||||
- `var1=value1;var2=value2`
|
||||
- `network_mode=bridge,macvlan` where comma means OR
|
||||
|
||||
Dependency validation detects missing dependencies, circular dependencies, and self-dependencies.
|
||||
|
||||
## Validation
|
||||
|
||||
Template validation includes:
|
||||
|
||||
- manifest shape validation
|
||||
- custom-delimiter Jinja syntax validation
|
||||
- undeclared variable detection
|
||||
- rendering validation
|
||||
|
||||
Generic semantic validation is provided by `cli/core/validators.py`, including YAML and Docker Compose-oriented checks where applicable.
|
||||
|
||||
Kind-specific validation lives under `cli/core/validation/` and can be enabled with module validation options such as `--kind` or matrix validation where supported.
|
||||
|
||||
## Docker Compose notes
|
||||
|
||||
When using Traefik with Docker Compose and multiple networks, include the Traefik network label so Traefik routes through the intended network:
|
||||
|
||||
```yaml
|
||||
traefik.docker.network: << traefik_network >>
|
||||
```
|
||||
|
||||
For Swarm/Compose-specific label placement, follow existing template patterns before introducing new ones.
|
||||
|
||||
## Shortcodes
|
||||
|
||||
Template descriptions may use emoji-style shortcodes such as `:warning:`, `:info:`, or `:docker:`. Display code maps these to Nerd Font icons. Add new shortcodes in the display/icon layer, not directly in template rendering code.
|
||||
Reference in New Issue
Block a user