refactor(config): implement three-phase Parse → Validate → Complete architecture (#2696)
* refactor(config): implement three-phase Parse → Validate → Complete architecture
This refactors the config system to use a cleaner three-phase architecture:
1. **Parse**: YAML → ConfigFile (raw representation with pointer fields)
2. **Validate**: Pure validation with no mutations, returns structured errors
3. **Complete**: ConfigFile → Config with defaults and CUDA resolution
- errors.go: Structured error types (ParseError, SchemaError, ValidationError, etc.)
- config_file.go: Raw ConfigFile type mirroring YAML with pointer fields
- parse.go: Parse(), ParseBytes(), ParseReader(), FromYAML() functions
- validate.go: ValidateConfigFile() with functional options pattern
- complete.go: CompleteConfig() for transforming ConfigFile → Config
- schema.go: GenerateSchema() using github.com/invopop/jsonschema
- build_options.go: BuildOptions struct for CLI flags (alternative to globals)
- validator.go: Old schema validation (replaced by validate.go)
- validator_test.go: Old tests (replaced by validate_test.go)
- Load() returns LoadResult with Config, Warnings, and RootDir
- Complete() replaces ValidateAndComplete() for programmatic configs
- FromYAML() is now a test helper that doesn't run completion
- Removed GetConfig(), GetRawConfig(), loadConfigFromFile()
- Renamed JSON files for consistency (*_matrix.json → *_compatibility.json)
- Renamed env_variables.go → env.go
- Updated callers to use new APIs
* chore: unexport, remove deadcode
Signed-off-by: Mark Phelps <mphelps@cloudflare.com>
* fix: address code review issues and clean up config package
Bug fixes:
- Fix major version check in validateConcurrency using splitPythonVersion
- Use filepath.Join instead of path.Join for OS-specific path handling
- Remove dead code (empty if !found block) in validateFrameworkCompatibility
- Remove unused schemaVersion constant
Dead code removal:
- Remove unused Version, Image, Stats structs from version.go
- Remove unused Example struct from config.go
Unexport internal code:
- ValidateCudaVersion → validateCudaVersion
- CUDABaseImageFor → cudaBaseImageFor
- ConfigFile/BuildFile/RunItemFile/etc → lowercase versions
- EnvironmentVariableDenyList → environmentVariableDenyList
* fix: address go-expert review feedback
- Use filepath.Join instead of path.Join in load.go for OS-specific paths
- Fix ValidateModelPythonVersion to check major version for concurrency
- Remove unused getter methods from config_file.go (GetPythonVersion,
GetPythonRequirements, GetCUDA, GetCuDNN, GetMax)
- Standardize error messages to lowercase per Go conventions
- Use %w for error wrapping in findConfigPathInDirectory
* fix: consolidate Python version validation and fix lint issues
- Fix golangci-lint issues: rename shadowed 'max' variable, use type conversion
- Remove duplicate ValidateModelPythonVersion function from config.go
- Remove redundant validation call from build.go (Load already validates)
- Update integration tests to match new ValidationError message format
* chore: rm confusing comments
Signed-off-by: Mark Phelps <mphelps@cloudflare.com>
* chore: modernize
Signed-off-by: Mark Phelps <mphelps@cloudflare.com>
* chore: refactor to use io.Reader
Signed-off-by: Mark Phelps <mphelps@cloudflare.com>
* chore: remove internal slices package and use stdlib pkg
Signed-off-by: Mark Phelps <mphelps@cloudflare.com>
---------
Signed-off-by: Mark Phelps <mphelps@cloudflare.com>