Compare commits

...

2 Commits

Author SHA1 Message Date
Jeff McCune
df33ac6ea7 docs: plan out compare buildplans feature 2025-05-19 10:37:57 -07:00
Jeff McCune
6eda832d1c docs: add conventions for coding agents
Copied from the CLAUDE.md file generated by claude code /init
2025-05-19 09:58:20 -07:00
3 changed files with 164 additions and 1 deletions

3
.gitignore vendored
View File

@@ -16,4 +16,5 @@ node_modules/
# nix
/.direnv/
result
result
.aider*

110
CONVENTIONS.md Normal file
View File

@@ -0,0 +1,110 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
Holos is a configuration management tool for Kubernetes that implements the rendered manifests pattern using CUE. It unifies Helm charts, Kustomize bases, and raw Kubernetes manifests into a single, declarative pipeline.
### Core Flow
```
Platform → Components → BuildPlan → Generators → Transformers → Validators → Manifests
```
## Key Commands
```bash
# Development
make build # Build the binary
make test # Run all tests
make fmt # Format Go code
make lint # Run linters
make coverage # Generate coverage report
# Documentation
make update-docs # Update generated docs
make website # Build the documentation website
# Usage
holos render platform # Render entire platform
holos render component # Render single component
holos show buildplans # Show build plans
holos init platform # Initialize new platform
```
## Architecture
### Directory Structure
- `/api/` - API definitions (v1alpha5 stable, v1alpha6 in development)
- `/cmd/` - CLI entry point
- `/internal/cli/` - Command implementations
- `/internal/component/` - Component handling logic
- `/internal/platform/` - Platform handling logic
- `/internal/generate/` - Code generation
### Key Files
- `/internal/cli/render/render.go` - Core render logic
- `/internal/component/component.go` - Component processing
- `/api/core/v1alpha*/types.go` - API type definitions
### Component Types
1. **Helm** - Wraps Helm charts
2. **Kustomize** - Wraps Kustomize bases
3. **Kubernetes** - Raw Kubernetes manifests
## CUE Patterns
Components are defined in CUE:
```cue
package holos
holos: Component.BuildPlan
Component: #Helm & {
Name: "example"
Chart: {
version: "1.0.0"
repository: {
name: "example"
url: "https://charts.example.com"
}
}
}
```
## Testing
- Unit tests: `*_test.go` files colocated with source
- Integration tests: `/cmd/holos/tests/`
- Example platforms: `/internal/testutil/fixtures/`
- Run single test: `go test -run TestName ./path/to/package`
## Development Patterns
1. Error handling: Use `internal/errors/` types, wrap with context
2. Logging: Use structured `slog`, get logger with `logger.FromContext(ctx)`
3. CLI commands: Follow Cobra patterns in `/internal/cli/`
4. CUE formatting: Always run `cue fmt` on CUE files
5. Develop against v1alpha6 packages.
6. Commits: Use the package name as the first word in the commit, lower case. Commit without asking permission.
## Version Management
- Version files: `/version/embedded/{major,minor,patch}`
- Bump version: `make bump`
- API versions: v1alpha5 (stable), v1alpha6 (development)
## Key Concepts
- **Platform**: Top-level configuration containing all components
- **Component**: Unit of configuration (Helm/Kustomize/Kubernetes)
- **BuildPlan**: Instructions for building a component
- **Generator**: Creates manifests (Helm, Kustomize, etc.)
- **Transformer**: Modifies generated manifests
- **Validator**: Validates final manifests
## Resources
- Tutorials: `/doc/md/tutorial/`
- Platform templates: `/internal/generate/platforms/`
- Test fixtures: `/internal/testutil/fixtures/`

View File

@@ -0,0 +1,52 @@
# Compare Buildplans
Use the `holos compare buildplans <f1> <f2>` command to compare two BuildPlan
Files. Useful to ensure different configuration versions produce the same
results.
The `holos show buildplans` command writes a BuildPlan File to standard output.
A BuildPlan File is a yaml encoded stream of BuildPlan objects.
## User Requirements
1. `holos compare buildplans before.yaml after.yaml` must return exit code 1 when after.yaml contains fields (recursively) not present in before.yaml
2. `holos compare buildplans before.yaml after.yaml --backwards-compatible` must return exit code 0 when after.yaml contains fields (recursively) not present in before.yaml
## Behavior Specification
BuildPlan File f1 is equivalent to f2 when:
1. f1 and f2 have an equal number of BuildPlan objects.
2. each object in f1 is equivalent to exactly one unique object in f2.
Two BuildPlans, bp1 and bp2, are equivalent when:
1. All field values in bp1 are equivalent to the same field in bp2.
2. Both 1 and 2 apply to nested objects, recursively.
3. Field f is equivalent when bp1.f exactly equals bp2.f, except for:
3.1. Objects in the spec.artifacts list may appear in any arbitrary order.
3.2. The ordering of keys does not matter.
4. Backwards compatibility behavior (controlled by isBackwardsCompatible):
- When false: bp2 and bp1 must have exactly the same fields
- When true: bp2 may have additional fields that don't exist in bp1
(e.g., new features added in a newer version)
Example:
bp1 has {name: "x", version: "1.0"}
bp2 has {name: "x", version: "1.0", newFeature: "enabled"}
This comparison passes when isBackwardsCompatible=true
5. Fields in bp1 must always be present in bp2 (regardless of backwards
compatibility mode).
6. List type fields with a null value are equivalent to:
6.1. null values
6.2. empty values ([])
6.2. a missing field
A BuildPlan File is valid when:
1. Two or more identical objects exist in the same file. They must be
treated as unique objects when comparing BuildPlan Files
2. Two objects may have the same value for the metadata.name field.
3. The kind field of all objects in the file stream is "BuildPlan"
## Implementation Guidance
1. Implement a stub Comparer struct in the internal/compare package.
2. Implement a stub Comparer.BuildPlans() method.
3. Write test cases for each item in the Behavior Specification section. Use a table test approach that loads each test case from a subdirectory and reads the test case data from a `testcase.json` file. The json file should have an exitCode, name, msg, file1 and file2 fields. file1 is "before.yaml" and file2 is "after.yaml".
4. Modify the Comparer.BuildPlans() method to satisfy each test case.
5. Using the existing commands as an example, wire up the command line to the compare package.