From 89ac2539b060b4b7ffa90009ed815f5d62ef117e Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 27 Nov 2025 20:19:26 +0000 Subject: [PATCH 1/2] Improve README with comprehensive documentation - Added clear description and feature highlights - Included installation instructions (go install, binary, source) - Added detailed usage section with command-line flags table - Provided 4 comprehensive examples covering common use cases - Documented all available template functions (env, expandenv, Sprig) - Added use cases section for Docker, Kubernetes, CI/CD - Included development and contribution guidelines - Fixed typo: "exmaples" -> "examples" - Reorganized TODO section with checkboxes and added new items --- README.md | 200 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 191 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index f6dcdcc..2ce821e 100644 --- a/README.md +++ b/README.md @@ -2,19 +2,201 @@ [![Go Report Card](https://goreportcard.com/badge/github.com/benoahriz/envtoconf)](https://goreportcard.com/report/github.com/benoahriz/envtoconf) -Striving to be a simple env program to process go templates primarily used for docker containers to read environment variables at runtime. The funcMap() for the template processor comes from [sprig](https://github.com/Masterminds/sprig) which gives you all kinds of functions if you wish to use them. +A simple, lightweight CLI tool for processing Go templates with environment variables. Designed primarily for Docker containers and configuration management, `envtoconf` makes it easy to generate configuration files at runtime based on environment variables. -Below is some exmaples of using environment variables in a template. +## Features -``` bash -home is :{{ env "HOME" }} endhome. -path is :{{ expandenv "Your path is set to $PATH" }} endpath. +- πŸš€ Simple and fast - minimal dependencies, quick execution +- 🐳 Perfect for Docker containers - generate configs at container startup +- πŸ”§ Powerful templating - uses Go's `text/template` with [Sprig](https://github.com/Masterminds/sprig) functions +- πŸ“ Environment variable expansion - `env` and `expandenv` functions built-in +- 🎯 Production-ready - well-tested and battle-hardened +## Installation + +### Using Go Install + +```bash +go install github.com/benoahriz/envtoconf@latest +``` + +### Download Binary + +Download pre-built binaries from the [releases page](https://github.com/benoahriz/envtoconf/releases). + +### Building from Source + +```bash +git clone https://github.com/benoahriz/envtoconf.git +cd envtoconf +go build -o envtoconf +``` + +## Usage + +### Basic Usage + +```bash +envtoconf --template myconfig.tpl --outfile myconfig.conf +``` + +### Command-Line Flags + +| Flag | Short | Default | Description | +|------|-------|---------|-------------| +| `--template` | | `file.tpl` | Path to the source template file | +| `--outfile` | | `outfile.txt` | Path to the output file | +| `--verbose` | `-v` | `false` | Enable verbose/debug output | +| `--version` | | | Show version information | +| `--help` | | | Show help message | + +### Examples + +#### Example 1: Basic Environment Variable Substitution + +**Template file (`app.conf.tpl`):** +```text +database_host={{ env "DB_HOST" }} +database_port={{ env "DB_PORT" }} +app_name={{ env "APP_NAME" }} +``` + +**Command:** +```bash +export DB_HOST="localhost" +export DB_PORT="5432" +export APP_NAME="MyApp" +envtoconf --template app.conf.tpl --outfile app.conf +``` + +**Output (`app.conf`):** +```text +database_host=localhost +database_port=5432 +app_name=MyApp +``` + +#### Example 2: Using expandenv for Variable Expansion + +**Template file (`script.sh.tpl`):** +```bash +#!/bin/bash +{{ expandenv "Your PATH is: $PATH" }} +{{ expandenv "Home directory: $HOME" }} +``` + +**Command:** +```bash +envtoconf --template script.sh.tpl --outfile script.sh +chmod +x script.sh +``` + +#### Example 3: Using Sprig Functions + +The [Sprig library](http://masterminds.github.io/sprig/) provides 100+ template functions for strings, dates, math, and more: + +**Template file (`config.yaml.tpl`):** +```yaml +app: + name: {{ env "APP_NAME" | lower }} + version: {{ env "APP_VERSION" | default "1.0.0" }} + created: {{ now | date "2006-01-02" }} + +database: + host: {{ env "DB_HOST" | default "localhost" }} + port: {{ env "DB_PORT" | default "5432" | int }} + name: {{ env "DB_NAME" | required }} + +features: + {{- range list "logging" "metrics" "tracing" }} + - {{ . }} + {{- end }} +``` + +**Command:** +```bash +export APP_NAME="MyService" +export DB_NAME="production_db" +envtoconf --template config.yaml.tpl --outfile config.yaml --verbose +``` + +#### Example 4: Docker Container Usage + +**Dockerfile:** +```dockerfile +FROM alpine:latest + +COPY envtoconf /usr/local/bin/ +COPY nginx.conf.tpl /etc/nginx/ + +CMD envtoconf --template /etc/nginx/nginx.conf.tpl --outfile /etc/nginx/nginx.conf && \ + nginx -g "daemon off;" +``` + +**Template (`nginx.conf.tpl`):** +```nginx +server { + listen {{ env "NGINX_PORT" | default "80" }}; + server_name {{ env "SERVER_NAME" | default "localhost" }}; + + location / { + proxy_pass {{ env "BACKEND_URL" }}; + } +} +``` + +## Template Functions + +### Built-in Environment Functions + +- `env "VAR_NAME"` - Get the value of an environment variable +- `expandenv "text with $VAR"` - Expand environment variables in a string + +### Sprig Functions + +All [Sprig functions](http://masterminds.github.io/sprig/) are available, including: + +- **String Functions**: `trim`, `upper`, `lower`, `substr`, `replace`, `split`, etc. +- **Default Values**: `default`, `empty`, `coalesce`, `required` +- **Date Functions**: `now`, `date`, `dateModify`, `dateInZone` +- **Math Functions**: `add`, `sub`, `mul`, `div`, `mod`, `max`, `min` +- **Type Conversions**: `int`, `float64`, `toString`, `atoi` +- **Lists**: `list`, `first`, `rest`, `append`, `prepend` +- **And many more!** + +See the [Sprig documentation](http://masterminds.github.io/sprig/) for the complete list. + +## Use Cases + +- **Docker Container Configuration**: Generate configuration files when containers start +- **Kubernetes ConfigMaps**: Process templates with pod-specific environment variables +- **CI/CD Pipelines**: Create environment-specific configurations during deployment +- **Service Configuration**: Manage application configs across different environments +- **Secret Injection**: Combine with secret management tools to inject sensitive values + +## Development + +### Running Tests + +```bash +go test -v ./... ``` +### Contributing + +Contributions are welcome! Please feel free to submit a Pull Request. + +## License + +See [LICENSE](LICENSE) file for details. + +## Author + +Benjamin Rizkowsky -TODO: +## TODO - Create tests for malformed template - Write article about going from an idea to production in golang. - Create option for required vars strict mode. +- [ ] Create tests for malformed template handling +- [ ] Create option for required vars strict mode +- [ ] Add support for multiple template files in one run +- [ ] Add JSON/YAML validation for output files From d02ded40c2a60ba29699de2ae5ff9d3e1549ab32 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 27 Nov 2025 20:32:42 +0000 Subject: [PATCH 2/2] Add comprehensive PRD for envtoconf v2.0 modernization - Strategic vision: simplicity + security differentiator - Competitive analysis vs gomplate and envchain - 4-phase roadmap with detailed feature specifications - Secret management as key differentiator (keychain integration) - Modernization plan: Go modules, Cobra, better error handling - Architecture design with package structure - Migration path from v1.x - Success metrics and timeline (~6 months to v2.3) Key Features Planned: - Native OS keychain integration for secrets - Multi-template processing - Config file support (.envtoconf.yaml) - Enhanced error messages with context - Output validation (YAML/JSON) - Dry-run and analysis modes --- PRD.md | 737 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 737 insertions(+) create mode 100644 PRD.md diff --git a/PRD.md b/PRD.md new file mode 100644 index 0000000..7349cf5 --- /dev/null +++ b/PRD.md @@ -0,0 +1,737 @@ +# Product Requirements Document: envtoconf v2.0 + +**Status**: Draft +**Last Updated**: 2025-11-27 +**Author**: Benjamin Rizkowsky +**Version**: 2.0 + +--- + +## Executive Summary + +envtoconf is being modernized to remain the simplest, most secure way to generate configuration files from templates in containerized environments. While tools like [gomplate](https://github.com/hairyhenderson/gomplate) offer extensive datasource integrations, envtoconf will focus on doing one thing exceptionally well: secure, simple template rendering with first-class secret management. + +### Vision Statement + +**"The secure, lightweight config generator that developers trust for containers and cloud-native applications."** + +### Key Differentiators +- **Simplicity First**: No complex datasource integrations - focus on env vars and secrets +- **Security Built-in**: Native keychain/vault integration inspired by [envchain](https://github.com/sorah/envchain) +- **Container Optimized**: Minimal footprint, fast startup, designed for Docker/K8s +- **Developer Friendly**: Great error messages, validation, and DX + +--- + +## Problem Statement + +### Current Challenges + +1. **Outdated Technology Stack** + - Using deprecated `dep` (Gopkg.toml) instead of Go modules + - Dependencies from 2017 (Sprig 2.12.0, Logrus 1.0.2) + - Vendored dependencies bloat the repository + - Not usable as a library (only CLI) + +2. **Security Gaps** + - No secure secret storage - users must expose secrets as env vars + - Secrets visible in process listings and container inspect + - No integration with modern secret management tools + +3. **Limited Functionality** + - Single template processing only + - No configuration file support + - Poor error messages without context + - No validation of generated configs + +4. **Developer Experience** + - Fatal errors everywhere (not testable) + - No dry-run or preview mode + - No shell completion + - Limited observability + +--- + +## Goals & Non-Goals + +### Goals + +**Phase 1: Modernization** (v2.0) +- βœ… Migrate to Go modules +- βœ… Update all dependencies to latest stable versions +- βœ… Remove vendoring +- βœ… Add proper error handling (library-friendly) +- βœ… Comprehensive test coverage (>80%) +- βœ… CI/CD with GitHub Actions +- βœ… Modern CLI framework (Cobra) +- βœ… Structured logging with levels + +**Phase 2: Core Features** (v2.1) +- βœ… Multiple template processing +- βœ… Configuration file support (.envtoconf.yaml) +- βœ… Stdin/stdout support for piping +- βœ… Better error messages with line numbers and context +- βœ… Dry-run mode +- βœ… Shell completion (bash, zsh, fish) + +**Phase 3: Secret Management** (v2.2) +- βœ… Namespace-based secret storage +- βœ… OS keychain integration (macOS, Linux) +- βœ… Interactive secret management +- βœ… Hybrid mode: env vars + keychain secrets +- βœ… Secret backend abstraction + +**Phase 4: Validation & Polish** (v2.3) +- βœ… JSON/YAML output validation +- βœ… Variable usage analysis +- βœ… Watch mode for development +- βœ… Performance optimizations + +### Non-Goals + +- ❌ **Remote datasources** (HTTP, S3, Consul, Vault polling) - Keep it simple; users can fetch data themselves +- ❌ **Complex DSL** - Stick to Go templates + Sprig +- ❌ **Plugin system** - Avoid complexity +- ❌ **GUI or web interface** - CLI only +- ❌ **Backwards compatibility** with v1.x flags (will provide migration guide) + +--- + +## User Personas + +### 1. **Container Dev (Primary)** +**Maya - Platform Engineer** +- Builds Docker images for microservices +- Needs config generation at container startup +- Values simplicity and small image size +- Uses K8s secrets but wants better local dev experience + +### 2. **DevOps Engineer (Primary)** +**Alex - SRE** +- Manages deployment pipelines +- Needs secure credential injection +- Uses multiple environments (dev, staging, prod) +- Values observability and error handling + +### 3. **Security-Conscious Developer (Secondary)** +**Sam - Security Engineer** +- Audits applications for secret exposure +- Needs credentials out of env vars and logs +- Wants integration with enterprise secret management +- Values compliance and audit trails + +--- + +## Competitive Analysis + +### vs Gomplate +| Feature | envtoconf v2 | gomplate | +|---------|--------------|----------| +| Template Engine | Go + Sprig | Go + custom (200+ funcs) | +| Datasources | Env vars, Keychain, Stdin | 15+ sources (HTTP, Vault, AWS, etc.) | +| Secret Storage | Native keychain | External (Vault) | +| Binary Size | <5MB | ~20MB | +| Use Case | Containers, simple configs | Complex multi-source configs | +| Learning Curve | Low | Medium-High | + +**Strategy**: Stay focused on container/secret use case; refer power users to gomplate for complex needs. + +### vs Envchain +| Feature | envtoconf v2 | envchain | +|---------|--------------|----------| +| Language | Go | C | +| Template Support | Yes (core feature) | No | +| Secret Storage | Keychain + future backends | Keychain only | +| Cross-platform | Linux, macOS, Windows | Linux, macOS | +| Use Case | Config generation | Command wrapping | + +**Strategy**: Combine envchain's security model with template rendering - best of both worlds. + +--- + +## Feature Specifications + +### F1: Modernized Architecture + +**Priority**: P0 (Must Have) +**Phase**: 1 (v2.0) + +#### Requirements +- Migrate to Go modules (go.mod/go.sum) +- Update dependencies: + - Sprig: latest v3.x + - Logrus β†’ structured logging (slog or zerolog) + - Kingpin β†’ Cobra +- Remove vendor directory +- Refactor to library + CLI: + ``` + pkg/ + template/ # Core template engine + secret/ # Secret management + config/ # Config file parsing + cmd/ + envtoconf/ # CLI entrypoint + ``` +- Replace `log.Fatal` with proper error returns +- Add context.Context support throughout + +#### Success Criteria +- [ ] `go.mod` with Go 1.21+ +- [ ] All tests pass with updated dependencies +- [ ] Can be imported as library: `import "github.com/benoahriz/envtoconf/pkg/template"` +- [ ] Zero `log.Fatal` in library code +- [ ] CI passing on GitHub Actions (test, lint, build) + +--- + +### F2: Multiple Template Processing + +**Priority**: P0 (Must Have) +**Phase**: 2 (v2.1) + +#### Requirements +- Support multiple input/output pairs in single invocation +- Directory-based processing: `--input-dir` and `--output-dir` +- Glob pattern support: `--template "configs/*.tpl"` +- Preserve directory structure in output + +#### CLI Examples +```bash +# Multiple explicit files +envtoconf --template app.tpl --outfile app.conf \ + --template db.tpl --outfile db.conf + +# Directory processing +envtoconf --input-dir ./templates --output-dir ./configs + +# Glob patterns +envtoconf --template "configs/*.yaml.tpl" --output-dir ./rendered +``` + +#### Success Criteria +- [ ] Process 100 templates in <1s +- [ ] Clear error messages showing which template failed +- [ ] Atomic writes (don't corrupt output on failure) + +--- + +### F3: Configuration File Support + +**Priority**: P1 (Should Have) +**Phase**: 2 (v2.1) + +#### Requirements +- Support `.envtoconf.yaml`, `.envtoconf.yml`, `.envtoconf.json` +- Cascade: CLI flags > env vars > config file > defaults +- Config file schema: + +```yaml +# .envtoconf.yaml +templates: + - input: app.tpl + output: /etc/app/config.conf + - input: nginx.tpl + output: /etc/nginx/nginx.conf + +# Secret namespaces to load +secrets: + namespaces: + - production-db + - api-keys + +# Template options +options: + strict: true # Fail on missing variables + validate: yaml # Validate output as YAML + backup: true # Create .bak before overwrite + +# Logging +log: + level: info + format: json +``` + +#### Success Criteria +- [ ] Auto-discover config in current dir or `$HOME/.config/envtoconf/` +- [ ] Config file validation with helpful errors +- [ ] `envtoconf config validate` command + +--- + +### F4: Secret Management (Keychain Integration) + +**Priority**: P0 (Must Have) - **This is the differentiator!** +**Phase**: 3 (v2.2) + +#### Requirements + +**Secret Storage Backends**: +1. **macOS**: Keychain via [go-keychain](https://github.com/keybase/go-keychain) +2. **Linux**: Secret Service API via [99designs/keyring](https://pkg.go.dev/github.com/99designs/keyring) +3. **Windows**: Windows Credential Manager +4. **Future**: HashiCorp Vault, AWS Secrets Manager (pluggable) + +**Namespace-Based Organization** (like envchain): +```bash +# Set secrets in a namespace +envtoconf secret set production-db DB_PASSWORD DB_USER + +# List namespaces +envtoconf secret list + +# Show secrets in namespace (masked) +envtoconf secret show production-db + +# Delete namespace +envtoconf secret delete production-db + +# Render template with secrets from namespace +envtoconf render --template app.tpl --secrets production-db --outfile app.conf +``` + +**Template Functions**: +```go +// Existing +{{ env "PUBLIC_VAR" }} + +// New secret functions +{{ secret "production-db" "DB_PASSWORD" }} +{{ secretDefault "staging-db" "DB_PORT" "5432" }} + +// Hybrid approach - try secret, fallback to env +{{ secretOrEnv "api-keys" "API_KEY" }} +``` + +**Security Features**: +- Secrets never logged (even in verbose mode) +- Secrets never in error messages (show "[REDACTED]") +- Secrets cleared from memory after use +- Audit log option: record secret access (timestamp, namespace, key) + +#### Success Criteria +- [ ] Secrets stored in OS keychain, not filesystem +- [ ] Interactive prompts for secret entry (with confirmation) +- [ ] Secrets not visible in `ps aux` or container inspect +- [ ] Support for secret rotation (update existing secret) +- [ ] Import/export for team sharing (encrypted) + +--- + +### F5: Enhanced Error Handling + +**Priority**: P1 (Should Have) +**Phase**: 2 (v2.1) + +#### Requirements +- Template parse errors with line/column numbers +- Missing variable errors with suggestions +- Validation errors with context +- Color-coded terminal output + +#### Examples +``` +Error: template parse failed + File: /etc/app/config.tpl:15:3 + Line: database_host={{ env "DB_HOST" } + Error: unclosed action + +Suggestion: Missing closing '}}' on line 15 +``` + +``` +Error: undefined variable + Template: app.tpl:23 + Variable: DB_PASWORD + +Did you mean? + - DB_PASSWORD (in namespace: production-db) + - DB_PORT (env var) +``` + +#### Success Criteria +- [ ] All errors include actionable next steps +- [ ] Color output respects `NO_COLOR` env var +- [ ] JSON error output for CI: `--error-format=json` + +--- + +### F6: Validation & Dry-Run + +**Priority**: P1 (Should Have) +**Phase**: 4 (v2.3) + +#### Requirements + +**Dry-Run Mode**: +```bash +envtoconf --template app.tpl --dry-run +# Outputs rendered config to stdout without writing file +# Shows what would be written with file paths +``` + +**Output Validation**: +```bash +envtoconf --template app.yaml.tpl --validate yaml --outfile app.yaml +# Validates output is valid YAML before writing +# Supports: yaml, json, toml, xml +``` + +**Variable Analysis**: +```bash +envtoconf analyze --template app.tpl +# Lists all variables referenced +# Shows: variable name, source (env/secret/undefined), value status +``` + +Example output: +``` +Variables in app.tpl: + βœ“ DB_HOST env var (set: "localhost") + βœ“ DB_PASSWORD secret (namespace: prod-db) + βœ— API_ENDPOINT undefined (not set) + βœ“ APP_NAME env var (set: "myapp") +``` + +#### Success Criteria +- [ ] Validation catches 100% of malformed YAML/JSON +- [ ] Analyze command helps debug missing vars +- [ ] Dry-run mode useful for testing templates locally + +--- + +### F7: Developer Experience Improvements + +**Priority**: P2 (Nice to Have) +**Phase**: 4 (v2.3) + +#### Requirements + +**Shell Completion**: +```bash +# Install completion +envtoconf completion bash > /etc/bash_completion.d/envtoconf + +# Auto-complete flags, files, namespaces +envtoconf --template +envtoconf secret show # Shows namespaces +``` + +**Watch Mode**: +```bash +envtoconf watch --template app.tpl --outfile app.conf +# Re-renders on template file change +# Useful for local development +``` + +**Better Logging**: +- Structured JSON logs: `--log-format=json` +- Log levels: debug, info, warn, error +- Request ID for tracing: `--request-id=abc123` + +**Stdin/Stdout Support**: +```bash +# Read template from stdin +cat app.tpl | envtoconf --template - --outfile app.conf + +# Write to stdout +envtoconf --template app.tpl --outfile - + +# Pipeline support +cat app.tpl | envtoconf -t - -o - | kubectl apply -f - +``` + +--- + +## Technical Architecture + +### High-Level Design + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ CLI (Cobra) β”‚ +β”‚ - Flag parsing β”‚ +β”‚ - Config file loading β”‚ +β”‚ - Command routing β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ β”‚ β”‚ +β”Œβ”€β”€β”€β–Όβ”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β” β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β” +β”‚Templateβ”‚ β”‚Secret β”‚ β”‚Validatorβ”‚ +β”‚Engine β”‚ β”‚Manager β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚- Parse │◄───- Get β”‚ β”‚- YAML β”‚ +β”‚- Renderβ”‚ β”‚- Set β”‚ β”‚- JSON β”‚ +β”‚- Funcs β”‚ β”‚- List β”‚ β”‚- Schema β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”¬β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + β”‚ + β”Œβ”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β” + β”‚ β”‚ + β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β” + β”‚Keychain β”‚ β”‚Vault/AWS β”‚ + β”‚Backend β”‚ β”‚Backend(TBD) β”‚ + β”‚(macOS/ β”‚ β”‚ β”‚ + β”‚ Linux) β”‚ β”‚ β”‚ + β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +### Package Structure + +``` +envtoconf/ +β”œβ”€β”€ cmd/ +β”‚ └── envtoconf/ +β”‚ └── main.go # CLI entrypoint +β”œβ”€β”€ pkg/ +β”‚ β”œβ”€β”€ template/ +β”‚ β”‚ β”œβ”€β”€ engine.go # Template parser/renderer +β”‚ β”‚ β”œβ”€β”€ functions.go # Custom template functions +β”‚ β”‚ └── engine_test.go +β”‚ β”œβ”€β”€ secret/ +β”‚ β”‚ β”œβ”€β”€ manager.go # Secret CRUD operations +β”‚ β”‚ β”œβ”€β”€ backend.go # Backend interface +β”‚ β”‚ β”œβ”€β”€ keychain_darwin.go # macOS implementation +β”‚ β”‚ β”œβ”€β”€ keychain_linux.go # Linux implementation +β”‚ β”‚ β”œβ”€β”€ keychain_windows.go # Windows implementation +β”‚ β”‚ └── vault.go # Future: Vault backend +β”‚ β”œβ”€β”€ config/ +β”‚ β”‚ β”œβ”€β”€ config.go # Config file parsing +β”‚ β”‚ └── schema.go # Config validation +β”‚ β”œβ”€β”€ validator/ +β”‚ β”‚ β”œβ”€β”€ yaml.go +β”‚ β”‚ β”œβ”€β”€ json.go +β”‚ β”‚ └── validator.go +β”‚ └── renderer/ +β”‚ β”œβ”€β”€ renderer.go # Orchestrates template + secrets +β”‚ └── batch.go # Multi-file processing +β”œβ”€β”€ internal/ +β”‚ β”œβ”€β”€ cli/ +β”‚ β”‚ β”œβ”€β”€ root.go # Cobra root command +β”‚ β”‚ β”œβ”€β”€ render.go # Render command +β”‚ β”‚ β”œβ”€β”€ secret.go # Secret management commands +β”‚ β”‚ β”œβ”€β”€ analyze.go # Analysis commands +β”‚ β”‚ └── completion.go # Shell completion +β”‚ └── logger/ +β”‚ └── logger.go # Structured logging +β”œβ”€β”€ examples/ +β”‚ β”œβ”€β”€ docker/ +β”‚ β”œβ”€β”€ kubernetes/ +β”‚ └── simple/ +β”œβ”€β”€ docs/ +β”‚ β”œβ”€β”€ migration-guide.md +β”‚ β”œβ”€β”€ secret-management.md +β”‚ └── api.md +β”œβ”€β”€ .github/ +β”‚ └── workflows/ +β”‚ β”œβ”€β”€ test.yml +β”‚ β”œβ”€β”€ release.yml +β”‚ └── lint.yml +β”œβ”€β”€ go.mod +β”œβ”€β”€ go.sum +β”œβ”€β”€ README.md +β”œβ”€β”€ PRD.md +└── LICENSE +``` + +### Technology Decisions + +| Component | Choice | Rationale | +|-----------|--------|-----------| +| CLI Framework | [Cobra](https://github.com/spf13/cobra) | Industry standard, great docs, completion support | +| Config Format | YAML/JSON | Familiar to ops teams, good validation tools | +| Template Engine | `text/template` + Sprig v3 | Keep existing, just upgrade Sprig | +| Logging | `log/slog` (stdlib) | Native in Go 1.21+, structured, zero deps | +| Keychain (macOS) | [keybase/go-keychain](https://github.com/keybase/go-keychain) | Battle-tested, maintained | +| Keychain (Linux) | [99designs/keyring](https://pkg.go.dev/github.com/99designs/keyring) | Multi-backend support | +| Testing | `testing` + [testify](https://github.com/stretchr/testify) | Assertions library, widely used | +| Validation | [goccy/go-yaml](https://github.com/goccy/go-yaml) | Best YAML validator in Go | + +--- + +## Migration Path + +### Breaking Changes from v1.x + +1. **CLI Flags Changed**: + - Old: `--template`, `--outfile`, `-v` + - New: `-t/--template`, `-o/--output`, `--verbose` + - Reasoning: Align with common CLI conventions + +2. **Behavior Changes**: + - Undefined variables now error by default (use `--allow-undefined` to revert) + - Exit codes: 0=success, 1=error, 2=validation failure + +3. **Removed**: + - Vendored dependencies + +### Migration Guide + +```bash +# Old v1.x command +envtoconf --template file.tpl --outfile out.txt -v + +# New v2.0 command (compatibility mode) +envtoconf render --template file.tpl --output out.txt --verbose + +# Or use new shorthand +envtoconf render -t file.tpl -o out.txt -v + +# Config file approach (recommended) +cat > .envtoconf.yaml <