feat(cli): add shell completions and detailed command help#26
Conversation
- Deno 2.x project structure with deno.json and task definitions - JSR dependencies: @cliffy/command, @std/assert, @std/testing, @std/yaml, @std/dotenv, @std/fs, @std/path - Full CLI command tree with stubs for all 15 issues - Shared interfaces (ProcessRunner, config types, ExitCode) for parallel work - FakeProcessRunner with recording, pre-programmed responses, and dry-run support - CI pipeline: fmt, lint, typecheck, test, coverage, and cross-platform build - .gitignore for generated and environment-specific files
- Default config values with sensible defaults - Deep merge for 5-layer config resolution (defaults -> base -> profile -> local -> local-profile) - Filesystem discovery (.stackctl, .stackctl.<profile>, .stackctl.local, .stackctl.local.<profile>) - Post-merge validation returning all errors at once - Template generation with inline comments, --detect, --preset, --profile, --force, --dry-run - STACKCTL_PROFILE env var support - 43 config tests + existing 15 = 58 passing - CLI init command wired to real implementation
Port of tools/generate_stacks.py from AniTrend/local-stack to idiomatic Deno TypeScript: - File discovery: walks repo root, finds docker-compose.yml/yaml files with x-stack metadata - Fragment loading: optional swarm.fragment.yml deep-merge per service - Compose deep merge (dict recursive, array replacement, scalar override) - Service transforms: strip compose-only keys (container_name, restart, build), inject logging defaults, rewrite env_file and bind-mount paths to repo-root relative - Named volume collection (external: true), default traefik-public overlay network - YAML output with header comment, --dry-run support - CLI generate command wired to real implementation - 60 compose tests + 58 existing = 118 passing
- composeOverrideMerge: scalars replace, maps merge, sequences append (distinct from fragment merge which replaces arrays) - loadOverrideFile: load YAML override from relative/absolute path - applyOverrides: load and apply chain of override files to base compose - Override integration in generateStacks via GenerateOptions.overrides - 26 tests covering all merge rules, file loading, edge cases - CLI generate command accepts --override flag
- Variable interpolation: ${VAR}, ${VAR-default}, ${VAR:-default}, $VAR, $$
- Variable scope resolution: shell env -> env_file(s) -> service.environment
- Deep interpolation through all string values in compose structures
- Path absolutization for env_file and bind-mount paths
- Strict mode (fail on unresolved) and non-strict mode (leave as-is with warnings)
- CLI pipeline: resolveConfig -> generateStacks -> renderStack -> output
- 49 comprehensive tests covering all interpolation forms and edge cases
Covers config migration, command mapping, profiles, overrides, rollback, troubleshooting, and behavior differences.
- Add composite action at .github/actions/setup-stackctl/action.yml - Support linux-x64, linux-arm64, macos-x64, macos-arm64 - Download from GitHub Releases, verify SHA256, cache in tool cache - Resolve latest version via GitHub API, accept explicit versions - Add PATH integration for subsequent workflow steps - Document CI usage in docs/migration.md Closes #11
- Add RealProcessRunner using Deno.Command with dry-run and signal forwarding - Add Docker CLI integration module (deploy, rm, services, ps, logs, info, swarm) - Add full sync pipeline: config -> discover -> generate -> render -> deploy - Wire CLI commands: up, down, status, logs, doctor, sync - Replace all issue #6 stubs with real implementations - Add 31 new tests (22 docker + 9 sync) all using FakeProcessRunner
- deno.json: add build:* tasks with Deno.compile for 4 targets - .github/workflows/release.yml: build matrix, SHA256 checksums, GitHub Releases - .github/workflows/ci.yml: update build stage to use renamed tasks
wax911
left a comment
There was a problem hiding this comment.
Review notes against #10:
This looks directionally aligned, but verify the acceptance criteria explicitly:
-
The required shells are bash, zsh, and fish. PowerShell support is fine as an addition, but it should not replace or weaken those three.
-
Completion generation must not require Docker or a
.stackctlfile. If config cannot be loaded, completion generation should still work for static commands/flags. -
When config is available, stack-name completion should be best-effort only. It must not fail the completion command if the config is invalid or missing.
-
Each destructive or external-tool command needs detailed help text:
down,secrets,reload, andsyncwere specifically called out in the issue.
Please ensure tests cover stackctl completions bash|zsh|fish and global/per-command help output.
- Add DRAFT / In Progress header noting evolving CLI and action contracts - Reference tarball naming format from release workflow (stackctl-v<version>-<target-triple>.tar.gz) - Split command table into parity commands and new capabilities - Update setup action path to .github/actions/setup-stackctl@v1 in consumer snippet - Add warning that committed/generated stacks are not safe to deploy raw without rendering
- Make SHA-256 checksum comparison opt-in via --skip-unchanged flag - Default always redeploys selected stacks (no checksum skip) - Add --force-service-update / --no-force-service-update CLI flags - Document option precedence: CLI > profile config > base config > default - Add dry-run logging for each step (generate, render, checksum, deploy) - Ensure reload never schedules docker stack rm/network rm/volume rm - Add 27 tests covering defaults, opt-in skip, force-update, safety, dry-run Ref: #9
Closes #10