Add lint-package debug command for engines, runtimes and models#394
Add lint-package debug command for engines, runtimes and models#394mrmara wants to merge 4 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a modelctl debug lint-package <snap-directory> command to lint/validate manifest YAMLs across an entire snap package layout (engines/models/runtimes), and introduces dedicated validators + tests for model and runtime manifests.
Changes:
- Add YAML manifest validators for
pkg/modelsandpkg/runtimes(unknown-field detection, required-field checks, directory-name consistency checks). - Add test suites to validate real manifests under
test_data/and validate key error cases (empty YAML, unknown fields, missing required fields). - Update
cmd/modelctl debugcommand fromvalidate-enginestolint-package, scanning a snap directory for manifests and reporting per-file results.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| cmd/modelctl/commands/debug/validate.go | Implements lint-package command to discover and validate manifests under engines/models/runtimes. |
| pkg/models/validate.go | Adds model manifest YAML validation and directory-name matching logic. |
| pkg/models/validate_test.go | Adds tests for model manifest validation and required fields. |
| pkg/runtimes/validate.go | Adds runtime manifest YAML validation and directory-name matching logic. |
| pkg/runtimes/validate_test.go | Adds tests for runtime manifest validation and required fields. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
farshidtz
left a comment
There was a problem hiding this comment.
Great to have the validation coverage gap reduced.
| for _, v := range validators { | ||
| pattern := filepath.Join(snapDir, v.subdir, "*", v.manifestFilename) | ||
| manifestPaths, err := filepath.Glob(pattern) | ||
| if err != nil { | ||
| return fmt.Errorf("invalid glob pattern %s: %w", pattern, err) | ||
| } | ||
|
|
||
| if len(manifestPaths) == 0 { | ||
| allManifestsValid = false | ||
| fmt.Printf("❌ %s: %s\n", manifestPath, err) | ||
| } else { | ||
| fmt.Printf("✅ %s\n", manifestPath) | ||
| fmt.Printf("❌ %s: no manifests found\n", filepath.Join(snapDir, v.subdir)) | ||
| continue | ||
| } |
There was a problem hiding this comment.
I would consider both runtimes and models optional. There could be an engine without a runtime, delivering just optimized weights or an engine with a combined runtime+model, using llamafiles. I see runtimes and models treated as an expected fields for engines elsewhere in the code so there has been an architectural regression. In this case, let's leave this for now.
| if manifest.ModelCardUrl == "" { | ||
| return fmt.Errorf("required field is not set: model-card-url") | ||
| } |
|
|
||
| if manifest.DiskSize == "" { | ||
| return fmt.Errorf("required field is not set: disk-size") | ||
| } |
There was a problem hiding this comment.
Validate input format / suffix.
| return fmt.Errorf("required field is not set: capabilities") | ||
| } else { | ||
| for _, cap := range manifest.Capabilities { | ||
| if !slices.Contains(webui.SupportedCapabilities(), cap) { |
There was a problem hiding this comment.
Make SupportedCapabilities() a private method of the model manifest. This is now used beyond webui
| return fmt.Errorf("required field is not set: environment") | ||
| } | ||
|
|
||
| return nil |
| return fmt.Errorf("required field is not set: components") | ||
| } | ||
|
|
||
| return nil |
| if err == nil { | ||
| t.Fatal("Empty yaml should fail") | ||
| } | ||
| t.Log(err) |
There was a problem hiding this comment.
Won't this just produce noise in verbose test logs. It should only print if there is something unexpected.
Same in several tests, also in models package.
| } | ||
|
|
||
| if !allManifestsValid { | ||
| return fmt.Errorf("not all manifests are valid") |
There was a problem hiding this comment.
DE013 / CLI Copy and Tone of Voice:
| return fmt.Errorf("some manifests are invalid") |
lint-packagecommand checks and validate manifests file for engines, runtimes and modelsExample usage:
go run ./cmd/modelctl debug lint-package <snap-directory>Test:
Succesful
Fail since
models,runtimesnorenginesdirectories are found:Fail since
modelsdirectory is not found:Fail because of validation error on a manifest:
Fail because of webui unsupported model capabilities:
Suggested change in workflows:
go run . debug validate-engines ../../../engines/**/*.yamlgo run . debug lint-package ../../../