### Install go-yamlvalidator Source: https://github.com/yakwilik/go-yamlvalidator/blob/master/README.md Use 'go get' to install the library. ```bash go get github.com/Yakwilik/go-yamlvalidator ``` -------------------------------- ### CLI Tool Installation and Schema Creation Source: https://context7.com/yakwilik/go-yamlvalidator/llms.txt Install the bundled CLI tool using 'go install' and create a schema file in YAML format. The CLI validates YAML files against this schema, with options for input files and validation settings. ```bash # Install go install github.com/Yakwilik/go-yamlvalidator/cmd/yamlvalidator@latest # Create schema file (YAML-serialized FieldSchema) cat > /tmp/schema.yaml << 'EOF' type: map required: true unknownKeyPolicy: warn allowedKeys: name: type: string required: true validators: - name: regex pattern: "^[a-z][a-z0-9-]*$" message: "must be lowercase with dashes" replicas: type: int validators: - name: range min: 1 max: 100 EOF ``` -------------------------------- ### Quick Start: Validate YAML with Go Source: https://github.com/yakwilik/go-yamlvalidator/blob/master/README.md Demonstrates basic YAML validation using a defined schema and validating a byte slice. Requires importing the validator package. ```go package main import ( "fmt" "regexp" v "github.com/Yakwilik/go-yamlvalidator" valv "github.com/Yakwilik/go-yamlvalidator/pkg/valuevalidator" ) func main() { schema := &v.FieldSchema{ Type: v.TypeMap, AllowedKeys: map[string]*v.FieldSchema{ "name": { Type: v.TypeString, Required: true, Validators: []v.ValueValidator{ valv.RegexValidator{ Pattern: regexp.MustCompile(`^[a-z][a-z0-9-]*$`), Message: "must be lowercase with dashes", }, }, }, "replicas": { Type: v.TypeInt, Validators: []v.ValueValidator{ valv.RangeValidator{Min: v.Ptr[float64](1), Max: v.Ptr[float64](100)}, }, }, }, } yaml := []byte(` name: my-app replicas: 50 `) validator := v.NewValidator(schema) result := validator.ValidateBytes(yaml) if result.HasErrors() { fmt.Println(result.FormatAll(true)) } } ``` -------------------------------- ### Custom Key Validator Implementation Source: https://github.com/yakwilik/go-yamlvalidator/blob/master/README.md Implement a custom key validator by creating a struct that satisfies the ValidateKey method. This example flags keys that start with an underscore, issuing a warning. ```go type MyKeyValidator struct{} func (v MyKeyValidator) ValidateKey(key string, keyNode *yaml.Node, path string, ctx *ValidationContext) { if strings.HasPrefix(key, "_") { ctx.AddError(ValidationError{ Level: LevelWarning, Path: path, Line: keyNode.Line, Column: keyNode.Column, Message: "keys starting with underscore are reserved", Got: key, }) } } ``` -------------------------------- ### Multi-Document YAML Example Source: https://github.com/yakwilik/go-yamlvalidator/blob/master/README.md Demonstrates a YAML file containing multiple documents separated by '---'. The validator handles these documents individually, prefixing errors with 'doc[N].' for subsequent documents. ```yaml name: first --- name: second --- name: third ``` -------------------------------- ### Go YAML Validator Key Validators Source: https://github.com/yakwilik/go-yamlvalidator/blob/master/README.md Examples of key validators for enforcing regex patterns, forbidding specific keys, and validating key lengths. ```go // Regex key validation RegexKeyValidator{ Pattern: regexp.MustCompile(`^[a-z][a-z0-9._-]*$`), Message: "invalid key format", } ``` ```go // Forbidden keys ForbiddenKeyValidator{Forbidden: []string{"password", "secret"}} ``` ```go // Key length LengthKeyValidator{Min: v.Ptr[int](1), Max: v.Ptr[int](63)} ``` -------------------------------- ### CLI Validation Source: https://github.com/yakwilik/go-yamlvalidator/blob/master/README.md Instructions and examples for using the command-line interface to validate YAML files against a schema. Covers specifying schema and file paths, and various validation flags. ```APIDOC ## CLI The repository ships a small CLI to validate any YAML file using a schema described in YAML or JSON (a serialized `FieldSchema`). Provide the schema file with `-schema` and the YAML to validate with `-file` (or stdin). Minimal schema example (`/tmp/schema.yaml`): ```yaml type: map required: true unknownKeyPolicy: warn allowedKeys: name: type: string required: true replicas: type: int validators: - name: range min: 1 max: 10 ``` Validate a file: ```bash go run ./cmd/yamlvalidator \ -schema /tmp/schema.yaml \ -file ./path/to/config.yaml \ -strict-keys \ -yaml11-bools ``` Flags: `-schema` (required), `-file` (defaults to stdin), `-strict-keys`, `-stop-on-first`, `-strict-types`, `-yaml11-bools`, and `-sort`. ``` -------------------------------- ### Ptr Helper for Creating Pointer Values Source: https://context7.com/yakwilik/go-yamlvalidator/llms.txt The generic Ptr[T] helper simplifies creating pointer values inline, which is crucial for fields like Min/Max where nil signifies an unset state distinct from a zero value. This example demonstrates its use in defining schema constraints. ```go import v "github.com/Yakwilik/go-yamlvalidator" _ = v.Ptr[int](1) // *int = 1 _ = v.Ptr[float64](100.0) // *float64 = 100.0 _ = v.Ptr[int](0) // *int = 0 (distinct from nil = no limit) schema := &v.FieldSchema{ Type: v.TypeSequence, MinItems: v.Ptr[int](1), // at least 1 item MaxItems: v.Ptr[int](50), // at most 50 items ItemSchema: &v.FieldSchema{ Type: v.TypeInt, Validators: []v.ValueValidator{ valv.RangeValidator{Min: v.Ptr[float64](0), Max: v.Ptr[float64](255)}, }, }, } ``` -------------------------------- ### Example Validation Error Output Source: https://github.com/yakwilik/go-yamlvalidator/blob/master/README.md Illustrates typical error messages from the validator, showing the error level, line and column number, the specific issue, and the path within the YAML structure. ```text [ERROR] line 2:13: invalid value "v3" (expected one of [v1 v1beta1 apps/v1], got v3) (path: apiVersion) 1 | > 2 | apiVersion: v3 | ^ 3 | kind: Deployment [ERROR] line 5:9: must be lowercase DNS-compatible name (got MyApp) (path: metadata.name) 4 | metadata: > 5 | name: MyApp | ^ 6 | namespace: production ``` -------------------------------- ### Error Formatting Source: https://github.com/yakwilik/go-yamlvalidator/blob/master/README.md Shows how to retrieve and format validation errors using the `ValidationResult` object. Includes examples of accessing all errors, warnings, and formatting output with source context. ```APIDOC ## Error Formatting ```go result := validator.ValidateBytes(yaml) // Get all errors for _, err := range result.Collector.Errors() { fmt.Println(err) } // Format with source context fmt.Println(result.FormatAll(true)) // true = sort by position ``` ### Example Output ``` [ERROR] line 2:13: invalid value "v3" (expected one of [v1 v1beta1 apps/v1], got v3) (path: apiVersion) 1 | > 2 | apiVersion: v3 | ^ 3 | kind: Deployment [ERROR] line 5:9: must be lowercase DNS-compatible name (got MyApp) (path: metadata.name) 4 | > 5 | name: MyApp | ^ 6 | namespace: production ``` ``` -------------------------------- ### Custom Value Validator Source: https://github.com/yakwilik/go-yamlvalidator/blob/master/README.md Provides an example of creating a custom value validator by implementing the `Validate` method. This allows for specific value checks beyond standard types. ```APIDOC ### Value Validator ```go type MyValidator struct{} func (v MyValidator) Validate(node *yaml.Node, path string, ctx *ValidationContext) { if node.Value != "expected" { ctx.AddError(ValidationError{ Level: LevelError, Path: path, Line: node.Line, Column: node.Column, Message: "value is not expected", Got: node.Value, }) } } ``` ``` -------------------------------- ### Go YAML Validator Inter-field Logic: ExactlyOneOf Source: https://github.com/yakwilik/go-yamlvalidator/blob/master/README.md Example of 'ExactlyOneOf' logic, ensuring exactly one of the listed fields is present. ```go // Exactly one of inline/file/url ExactlyOneOf: []string{"inline", "file", "url"} ``` -------------------------------- ### Minimal Schema Example for CLI Validation Source: https://github.com/yakwilik/go-yamlvalidator/blob/master/README.md Define a basic schema for YAML validation using the CLI. This schema specifies a map with a required string 'name' and an integer 'replicas' within a specific range. ```yaml type: map required: true unknownKeyPolicy: warn allowedKeys: name: type: string required: true replicas: type: int validators: - name: range min: 1 max: 10 ``` -------------------------------- ### Go YAML Validator Inter-field Logic: AnyOf Source: https://github.com/yakwilik/go-yamlvalidator/blob/master/README.md Example of 'AnyOf' logic, requiring at least one of the specified field groups to be present. ```go // Either configFile, OR both host AND port AnyOf: [][]string{{"configFile"}, {"host", "port"}} ``` -------------------------------- ### Go YAML Validator Value Validators Source: https://github.com/yakwilik/go-yamlvalidator/blob/master/README.md Provides examples of built-in value validators for checking enums, regex patterns, numeric ranges, non-empty values, and lengths. ```go // Enum validation EnumValidator{Allowed: []string{"v1", "v2", "v3"}} ``` ```go // Regex validation RegexValidator{ Pattern: regexp.MustCompile(`^[a-z]+$`), Message: "must be lowercase letters", } ``` ```go // Numeric range RangeValidator{Min: v.Ptr[float64](1), Max: v.Ptr[float64](100)} ``` ```go // Non-empty check NonEmptyValidator{} ``` ```go // Length validation LengthValidator{Min: v.Ptr[int](1), Max: v.Ptr[int](255)} ``` ```go // URL validation URLValidator{RequireScheme: true, AllowedSchemes: []string{"http", "https"}} ``` -------------------------------- ### Custom Value Validator Implementation Source: https://github.com/yakwilik/go-yamlvalidator/blob/master/README.md Implement a custom validator by creating a struct that satisfies the Validate method. This example checks if a node's value is exactly 'expected', adding an error otherwise. ```go type MyValidator struct{} func (v MyValidator) Validate(node *yaml.Node, path string, ctx *ValidationContext) { if node.Value != "expected" { ctx.AddError(ValidationError{ Level: LevelError, Path: path, Line: node.Line, Column: node.Column, Message: "value is not expected", Got: node.Value, }) } } ``` -------------------------------- ### Go YAML Validator Inter-field Logic: MutuallyExclusive Source: https://github.com/yakwilik/go-yamlvalidator/blob/master/README.md Example of 'MutuallyExclusive' logic, ensuring that no more than one of the listed fields is present. ```go // debug and quiet cannot both be present MutuallyExclusive: []string{"debug", "quiet"} ``` -------------------------------- ### Define Conditional Rules for YAML Validation Source: https://github.com/yakwilik/go-yamlvalidator/blob/master/README.md Use ConditionalRule to define rules that depend on specific field values. This example shows how to make 'endpoint' required and 'local' forbidden when 'type' is 'external'. ```go Conditions: []ConditionalRule{ { ConditionField: "type", ConditionValue: "external", ThenRequired: []string{"endpoint"}, ThenForbidden: []string{"local"}, }, } ``` -------------------------------- ### Resolve YAML Anchors and Aliases Source: https://context7.com/yakwilik/go-yamlvalidator/llms.txt The validator automatically resolves YAML anchors (&anchor) and aliases (*alias), including merge keys (<<), before applying schema validation. This example shows overriding an anchor value in a production environment. ```go data := []byte(` defaults: &defaults timeout: 30 retries: 3 production: <<: *defaults timeout: 60 # overrides anchor value `) schema := &v.FieldSchema{ Type: v.TypeMap, AllowedKeys: map[string]*v.FieldSchema{ "defaults": {Type: v.TypeMap, AdditionalProperties: &v.FieldSchema{Type: v.TypeAny}}, "production": { Type: v.TypeMap, AllowedKeys: map[string]*v.FieldSchema{ "timeout": {Type: v.TypeInt}, "retries": {Type: v.TypeInt}, }, }, }, } result := v.NewValidator(schema).ValidateBytes(data) fmt.Println(result.HasErrors()) // false — merge resolved correctly ``` -------------------------------- ### Create and Use Validator Instance Source: https://github.com/yakwilik/go-yamlvalidator/blob/master/README.md Instantiate a validator with a schema and use its methods to validate YAML data. ValidateBytes processes raw byte slices, while ValidateWithOptions allows fine-grained control. ```go // Create validator v := NewValidator(schema) // Validate bytes result := v.ValidateBytes(yamlData) // Validate with options result := v.ValidateWithOptions(yamlData, ValidationContext{...}) ``` -------------------------------- ### Configure Validation Options Source: https://github.com/yakwilik/go-yamlvalidator/blob/master/README.md Set validation options like StrictKeys, StopOnFirst, StrictTypes, and YAML11Booleans to control validation behavior. StrictKeys treats unknown keys as errors, while StopOnFirst halts validation after the first error. ```go result := validator.ValidateWithOptions(yaml, ValidationContext{ StrictKeys: true, // Unknown keys are errors StopOnFirst: false, // Continue after first error StrictTypes: false, // Parse values for type inference YAML11Booleans: false, // Don't treat YAML 1.1 boolean literals (yes/no/on/off/true/false/y/n) as booleans; when true, quoted forms are also treated as booleans }) ``` -------------------------------- ### Helper Functions for Pointer Values Source: https://github.com/yakwilik/go-yamlvalidator/blob/master/README.md Utilize helper functions like Ptr to create pointers to basic types, often required for optional or nullable fields in schema definitions. ```go MinItems: Ptr[int](1) Max: Ptr[float64](100) ``` -------------------------------- ### Validation Options Source: https://github.com/yakwilik/go-yamlvalidator/blob/master/README.md Demonstrates how to use `ValidateWithOptions` to customize the validation process. Options include strict key checking, stopping on the first error, type inference, and handling of YAML 1.1 boolean literals. ```APIDOC ## Validation Options ```go result := validator.ValidateWithOptions(yaml, ValidationContext{ StrictKeys: true, // Unknown keys are errors StopOnFirst: false, // Continue after first error StrictTypes: false, // Parse values for type inference YAML11Booleans: false, // Don't treat YAML 1.1 boolean literals (yes/no/on/off/true/false/y/n) as booleans; when true, quoted forms are also treated as booleans }) ``` ``` -------------------------------- ### Custom Key Validator Source: https://github.com/yakwilik/go-yamlvalidator/blob/master/README.md Demonstrates how to create a custom key validator by implementing the `ValidateKey` method. This is useful for enforcing naming conventions or other key-specific rules. ```APIDOC ### Key Validator ```go type MyKeyValidator struct{} func (v MyKeyValidator) ValidateKey(key string, keyNode *yaml.Node, path string, ctx *ValidationContext) { if strings.HasPrefix(key, "_") { ctx.AddError(ValidationError{ Level: LevelWarning, Path: path, Line: keyNode.Line, Column: keyNode.Column, Message: "keys starting with underscore are reserved", Got: key, }) } } ``` ``` -------------------------------- ### Implement Custom Key Validation Logic Source: https://context7.com/yakwilik/go-yamlvalidator/llms.txt Define custom key validation rules by implementing the KeyValidator interface. The ValidateKey method allows for checks on key names, providing warnings or errors. ```go import ( v "github.com/Yakwilik/go-yamlvalidator" "gopkg.in/yaml.v3" "strings" ) type NoUnderscoreKeyValidator struct{} func (NoUnderscoreKeyValidator) ValidateKey(key string, keyNode *yaml.Node, path string, ctx *v.ValidationContext) { if strings.HasPrefix(key, "_") { ctx.AddError(v.ValidationError{ Level: v.LevelWarning, Path: path, Line: keyNode.Line, Column: keyNode.Column, Message: "keys starting with underscore are reserved", Got: key, }) } } schema := &v.FieldSchema{ Type: v.TypeMap, AdditionalProperties: &v.FieldSchema{Type: v.TypeAny}, KeyValidators: []v.KeyValidator{NoUnderscoreKeyValidator{}}, } // YAML key "_internal" → [WARNING] keys starting with underscore are reserved (got _internal) ``` -------------------------------- ### Validate YAML File using CLI Source: https://github.com/yakwilik/go-yamlvalidator/blob/master/README.md Use the go-yamlvalidator CLI to validate a YAML file against a schema. This command validates './path/to/config.yaml' using '/tmp/schema.yaml' and enables strict key checking and YAML 1.1 boolean parsing. ```bash go run ./cmd/yamlvalidator \ -schema /tmp/schema.yaml \ -file ./path/to/config.yaml \ -strict-keys \ -yaml11-bools ``` -------------------------------- ### Create Validator and Validate YAML Bytes Source: https://context7.com/yakwilik/go-yamlvalidator/llms.txt Create a validator with a root FieldSchema and use ValidateBytes to validate raw YAML data. This method supports multi-document YAML streams. ```go package main import ( "fmt" v "github.com/Yakwilik/go-yamlvalidator" valv "github.com/Yakwilik/go-yamlvalidator/pkg/valuevalidator" ) func main() { schema := &v.FieldSchema{ Type: v.TypeMap, AllowedKeys: map[string]*v.FieldSchema{ "name": { Type: v.TypeString, Required: true, Validators: []v.ValueValidator{ valv.RegexValidator{ Pattern: regexp.MustCompile(`^[a-z][a-z0-9-]*$`), Message: "must be lowercase with dashes", }, }, }, "replicas": { Type: v.TypeInt, Validators: []v.ValueValidator{ valv.RangeValidator{Min: v.Ptr[float64](1), Max: v.Ptr[float64](100)}, }, }, }, } data := []byte(` name: my-app replicas: 50 `) validator := v.NewValidator(schema) result := validator.ValidateBytes(data) if result.HasErrors() { fmt.Println(result.FormatAll(true)) } else { fmt.Println("valid") // Output: valid } } ``` -------------------------------- ### Allowing Arbitrary String Values for Unknown Keys Source: https://github.com/yakwilik/go-yamlvalidator/blob/master/README.md Configure a map schema to allow any string values for keys not explicitly defined using AdditionalProperties. This is useful for flexible key-value pairs like labels. ```go // Allow any string values for unknown keys labels: { Type: TypeMap, AdditionalProperties: &FieldSchema{Type: TypeString}, } ``` -------------------------------- ### Map Key Restrictions with FieldSchema Source: https://context7.com/yakwilik/go-yamlvalidator/llms.txt Define allowed keys, schemas for additional properties, and policies for unknown keys in a map. Use `AllowedKeys` for known fields, `AdditionalProperties` for a schema applied to all other keys, and `UnknownKeyPolicy` to control behavior for keys not explicitly defined or covered by `AdditionalProperties`. ```go schema := &v.FieldSchema{ Type: v.TypeMap, // Known keys with their own schemas AllowedKeys: map[string]*v.FieldSchema{ "name": {Type: v.TypeString, Required: true}, }, // Validate any unknown key's value against this schema AdditionalProperties: &v.FieldSchema{Type: v.TypeString}, // When AdditionalProperties is nil, control unknown key behavior: // UnknownKeyInherit (default), UnknownKeyError, UnknownKeyWarn, UnknownKeyIgnore UnknownKeyPolicy: v.UnknownKeyWarn, } // Example YAML: // name: foo // extra-key: bar <- validated as TypeString via AdditionalProperties // unknown: 123 <- UnknownKeyPolicy applies if no AdditionalProperties ``` -------------------------------- ### Format Validation Errors with Source Context Source: https://github.com/yakwilik/go-yamlvalidator/blob/master/README.md Retrieve and format validation errors, optionally including source code context. The FormatAll method can sort errors by their position in the YAML document. ```go result := validator.ValidateBytes(yaml) // Get all errors for _, err := range result.Collector.Errors() { fmt.Println(err) } // Format with source context fmt.Println(result.FormatAll(true)) // true = sort by position ``` -------------------------------- ### Define FieldSchema Options Source: https://context7.com/yakwilik/go-yamlvalidator/llms.txt Define a FieldSchema to specify type, required status, nullability, deprecation warnings, and default values for YAML fields. ```go schema := &v.FieldSchema{ Type: v.TypeMap, AllowedKeys: map[string]*v.FieldSchema{ "apiVersion": { Type: v.TypeString, Required: true, // error if absent }, "timeout": { Type: v.TypeInt, Nullable: true, // allows: timeout: null Default: 30, // warning if missing }, "legacyField": { Type: v.TypeString, Deprecated: "use 'newField' instead", // warning on use }, "count": { Type: v.TypeInt, // TypeAny, TypeNull, TypeString, TypeInt, // TypeFloat, TypeBool, TypeMap, TypeSequence }, }, } ``` -------------------------------- ### Validate YAML File with go-yamlvalidator CLI Source: https://context7.com/yakwilik/go-yamlvalidator/llms.txt Use this command to validate a YAML file against a schema using the CLI tool. It supports options like strict key checking and YAML 1.1 boolean recognition. ```bash go run ./cmd/yamlvalidator \ -schema /tmp/schema.yaml \ -file ./config.yaml \ -strict-keys \ -yaml11-bools ``` -------------------------------- ### Validate YAML with Custom Options Source: https://context7.com/yakwilik/go-yamlvalidator/llms.txt Use ValidateWithOptions to validate YAML bytes with a custom ValidationContext. This allows control over strict key enforcement, error collection, type inference, and YAML 1.1 boolean handling. ```go import v "github.com/Yakwilik/go-yamlvalidator" result := validator.ValidateWithOptions(data, v.ValidationContext{ StrictKeys: true, // unknown keys are errors (not warnings) StopOnFirst: false, // collect all errors StrictTypes: false, // infer types from values, not only YAML tags YAML11Booleans: true, // treat yes/no/on/off as booleans }) if result.HasErrors() { // FormatAll(true) sorts by line/column and prints source context fmt.Print(result.FormatAll(true)) // Example output: // [ERROR] line 2:13: invalid value "v3" (expected one of [v1 v1beta1], got v3) (path: apiVersion) // 1 | // > 2 | apiVersion: v3 // | ^ // 3 | kind: Deployment } for _, warn := range result.Collector.Warnings() { fmt.Println(warn) // [WARNING] line 5:3: field "namespace" not set, will use default: default (path: metadata.namespace) } ``` -------------------------------- ### Go YAML Validator Unknown Key Policies Source: https://github.com/yakwilik/go-yamlvalidator/blob/master/README.md Defines policies for handling keys not explicitly defined in the schema. ```go type UnknownKeyInherit type UnknownKeyError type UnknownKeyWarn type UnknownKeyIgnore ``` -------------------------------- ### FieldSchema Options Source: https://context7.com/yakwilik/go-yamlvalidator/llms.txt Defines core scalar field options including type, required/nullable flags, deprecation warnings, and default value hints. ```APIDOC ## FieldSchema — Type, Required, Nullable, Deprecated, Default Core scalar field options control presence requirements, null allowance, deprecation warnings, and default-value hints. ```go schema := &v.FieldSchema{ Type: v.TypeMap, AllowedKeys: map[string]*v.FieldSchema{ "apiVersion": { Type: v.TypeString, Required: true, // error if absent }, "timeout": { Type: v.TypeInt, Nullable: true, // allows: timeout: null Default: 30, // warning if missing }, "legacyField": { Type: v.TypeString, Deprecated: "use 'newField' instead", // warning on use }, "count": { Type: v.TypeInt, // TypeAny, TypeNull, TypeString, TypeInt, // TypeFloat, TypeBool, TypeMap, TypeSequence }, }, } ``` ``` -------------------------------- ### Implement Custom Value Validation Logic Source: https://context7.com/yakwilik/go-yamlvalidator/llms.txt Create a custom struct implementing the ValueValidator interface to define domain-specific validation rules for node values. The Validate method receives the node, its path, and the validation context. ```go import ( v "github.com/Yakwilik/go-yamlvalidator" "gopkg.in/yaml.v3" "strings" ) type SemverValidator struct{} func (SemverValidator) Validate(node *yaml.Node, path string, ctx *v.ValidationContext) { parts := strings.Split(node.Value, ".") if len(parts) != 3 { ctx.AddError(v.ValidationError{ Level: v.LevelError, Path: path, Line: node.Line, Column: node.Column, Message: "must be a valid semantic version (MAJOR.MINOR.PATCH)", Got: node.Value, Expected: "e.g. 1.2.3", }) } } schema := &v.FieldSchema{ Type: v.TypeMap, AllowedKeys: map[string]*v.FieldSchema{ "version": { Type: v.TypeString, Required: true, Validators: []v.ValueValidator{SemverValidator{}}, }, }, } // YAML: version: "1.2" // [ERROR] must be a valid semantic version (MAJOR.MINOR.PATCH) (got 1.2) (path: version) ``` -------------------------------- ### Multi-Document Support Source: https://github.com/yakwilik/go-yamlvalidator/blob/master/README.md Explains how the validator handles multi-document YAML files, where documents are separated by `---`. Errors in subsequent documents are prefixed with `doc[N].`. ```APIDOC ## Multi-Document Support The validator automatically handles multi-document YAML (separated by `---`): ```yaml name: first --- name: second --- name: third ``` Errors in subsequent documents are prefixed with `doc[N].`: ``` [ERROR] line 5:1: required field "name" is missing (path: doc[2].name) ``` ``` -------------------------------- ### Sequence Validation with FieldSchema Source: https://context7.com/yakwilik/go-yamlvalidator/llms.txt Validate items within a sequence and enforce cardinality constraints. `ItemSchema` defines the validation rules for each element, while `MinItems` and `MaxItems` set the allowed number of elements. ```go schema := &v.FieldSchema{ Type: v.TypeMap, AllowedKeys: map[string]*v.FieldSchema{ "containers": { Type: v.TypeSequence, Required: true, MinItems: v.Ptr[int](1), MaxItems: v.Ptr[int](10), ItemSchema: &v.FieldSchema{ Type: v.TypeMap, AllowedKeys: map[string]*v.FieldSchema{ "name": {Type: v.TypeString, Required: true}, "image": {Type: v.TypeString, Required: true}, "port": { Type: v.TypeInt, Validators: []v.ValueValidator{ valv.RangeValidator{Min: v.Ptr[float64](1), Max: v.Ptr[float64](65535)}, }, }, }, }, }, }, } // Errors if containers is absent, empty, or has >10 items. // Each item must be a map with required name and image fields. ``` -------------------------------- ### Validator API Source: https://github.com/yakwilik/go-yamlvalidator/blob/master/README.md Reference for the main `Validator` type, including how to create a new validator instance with a schema and perform validation using `ValidateBytes` or `ValidateWithOptions`. ```APIDOC ## API Reference ### Validator ```go // Create validator v := NewValidator(schema) // Validate bytes result := v.ValidateBytes(yamlData) // Validate with options result := v.ValidateWithOptions(yamlData, ValidationContext{...}) ``` ``` -------------------------------- ### ValidateWithOptions Source: https://context7.com/yakwilik/go-yamlvalidator/llms.txt Validates YAML bytes using a custom ValidationContext to control strict key enforcement, stop-on-first-error, strict type inference, and YAML 1.1 boolean recognition. ```APIDOC ## ValidateWithOptions `ValidateWithOptions` validates YAML bytes using a custom `ValidationContext` that controls strict key enforcement, stop-on-first-error, strict type inference, and YAML 1.1 boolean recognition. ```go import v "github.com/Yakwilik/go-yamlvalidator" result := validator.ValidateWithOptions(data, v.ValidationContext{ StrictKeys: true, // unknown keys are errors (not warnings) StopOnFirst: false, // collect all errors StrictTypes: false, // infer types from values, not only YAML tags YAML11Booleans: true, // treat yes/no/on/off as booleans }) if result.HasErrors() { // FormatAll(true) sorts by line/column and prints source context fmt.Print(result.FormatAll(true)) // Example output: // [ERROR] line 2:13: invalid value "v3" (expected one of [v1 v1beta1], got v3) (path: apiVersion) // 1 | // > 2 | apiVersion: v3 // | ^ // 3 | kind: Deployment } for _, warn := range result.Collector.Warnings() { fmt.Println(warn) // [WARNING] line 5:3: field "namespace" not set, will use default: default (path: metadata.namespace) } ``` ``` -------------------------------- ### Validate YAML from Stdin with go-yamlvalidator CLI Source: https://context7.com/yakwilik/go-yamlvalidator/llms.txt Pipe YAML content to the validator via stdin for validation against a schema. This is useful for integrating with other command-line tools. ```bash cat config.yaml | go run ./cmd/yamlvalidator -schema /tmp/schema.yaml ``` -------------------------------- ### Validate Multi-Document YAML Streams Source: https://context7.com/yakwilik/go-yamlvalidator/llms.txt Use ValidateBytes or ValidateWithOptions to process YAML streams containing multiple documents separated by '---'. Errors in subsequent documents are prefixed with their document index. ```go data := []byte(` name: first --- name: second --- # missing name field foo: bar `) schema := &v.FieldSchema{ Type: v.TypeMap, AllowedKeys: map[string]*v.FieldSchema{ "name": {Type: v.TypeString, Required: true}, }, } result := v.NewValidator(schema).ValidateBytes(data) fmt.Println(result.FormatAll(true)) // [ERROR] line 8:1: required field "name" is missing (path: doc[2].name) // > 8 | foo: bar // | ^ ``` -------------------------------- ### Combining AdditionalProperties with Key Validators Source: https://github.com/yakwilik/go-yamlvalidator/blob/master/README.md Enhance map validation by using AdditionalProperties for value types and KeyValidators to enforce naming conventions on all keys, including additional ones. ```go labels: { Type: TypeMap, AdditionalProperties: &FieldSchema{Type: TypeString}, KeyValidators: []KeyValidator{ RegexKeyValidator{Pattern: regexp.MustCompile(`^[a-z][a-z0-9._-]*$`)}, }, } ``` -------------------------------- ### Ensure Non-Empty Values with NonEmptyValidator Source: https://context7.com/yakwilik/go-yamlvalidator/llms.txt Utilize NonEmptyValidator to verify that a scalar string is not empty, a sequence has at least one item, or a map has at least one key. This validator takes no arguments. ```go import valv "github.com/Yakwilik/go-yamlvalidator/pkg/valuevalidator" schema := &v.FieldSchema{ Type: v.TypeMap, AllowedKeys: map[string]*v.FieldSchema{ "kind": { Type: v.TypeString, Validators: []v.ValueValidator{ valv.NonEmptyValidator{}, }, }, }, } // YAML: kind: "" // [ERROR] line 1:7: value cannot be empty (path: kind) ``` -------------------------------- ### NewValidator / ValidateBytes Source: https://context7.com/yakwilik/go-yamlvalidator/llms.txt Creates a Validator and validates raw YAML bytes against a root FieldSchema. Supports multi-document YAML streams. ```APIDOC ## NewValidator / ValidateBytes `NewValidator` creates a `Validator` bound to a root `FieldSchema`. `ValidateBytes` parses and validates raw YAML bytes (including multi-document streams separated by `---`) against that schema using default context settings, returning a `*ValidationResult`. ```go package main import ( "fmt" v "github.com/Yakwilik/go-yamlvalidator" valv "github.com/Yakwilik/go-yamlvalidator/pkg/valuevalidator" ) func main() { schema := &v.FieldSchema{ Type: v.TypeMap, AllowedKeys: map[string]*v.FieldSchema{ "name": { Type: v.TypeString, Required: true, Validators: []v.ValueValidator{ valv.RegexValidator{ Pattern: regexp.MustCompile(`^[a-z][a-z0-9-]*$`), Message: "must be lowercase with dashes", }, }, }, "replicas": { Type: v.TypeInt, Validators: []v.ValueValidator{ valv.RangeValidator{Min: v.Ptr[float64](1), Max: v.Ptr[float64](100)}, }, }, }, } data := []byte(` name: my-app replicas: 50 `) validator := v.NewValidator(schema) result := validator.ValidateBytes(data) if result.HasErrors() { fmt.Println(result.FormatAll(true)) } else { fmt.Println("valid") // Output: valid } } ``` ``` -------------------------------- ### Conditional Field Logic with Conditions Source: https://context7.com/yakwilik/go-yamlvalidator/llms.txt Implement conditional validation rules where fields become required or forbidden based on the value of another field. `ConditionalRule` specifies the `ConditionField`, its `ConditionValue`, and the fields that become `ThenRequired` or `ThenForbidden`. ```go schema := &v.FieldSchema{ Type: v.TypeMap, AllowedKeys: map[string]*v.FieldSchema{ "type": {Type: v.TypeString}, "endpoint": {Type: v.TypeString}, "local": {Type: v.TypeString}, }, Conditions: []v.ConditionalRule{ { ConditionField: "type", ConditionValue: "external", ThenRequired: []string{"endpoint"}, // required when type=external ThenForbidden: []string{"local"}, // forbidden when type=external }, }, } // YAML triggering errors: // type: external // local: /tmp/data <- forbidden // (endpoint missing <- required) // // [ERROR] field "endpoint" is required when type="external" (path: endpoint) // [ERROR] field "local" is forbidden when type="external" (path: local) ``` -------------------------------- ### Validate URLs with URLValidator Source: https://context7.com/yakwilik/go-yamlvalidator/llms.txt Use URLValidator to check if a string represents a valid URL. It supports requiring a specific scheme and allowing only a list of permitted schemes. ```go import valv "github.com/Yakwilik/go-yamlvalidator/pkg/valuevalidator" schema := &v.FieldSchema{ Type: v.TypeMap, AllowedKeys: map[string]*v.FieldSchema{ "webhook": { Type: v.TypeString, Validators: []v.ValueValidator{ valv.URLValidator{ RequireScheme: true, AllowedSchemes: []string{"https"}, }, }, }, }, } // YAML: webhook: http://example.com // [ERROR] URL scheme not allowed (expected one of [https], got http) (path: webhook) ``` -------------------------------- ### ErrorCollector for Accumulating Errors and Warnings Source: https://context7.com/yakwilik/go-yamlvalidator/llms.txt The ErrorCollector separates errors and warnings, providing methods to access and iterate through them. Errors are collected first, followed by warnings. The collector also supports sorting errors by their position in the source file. ```go result := validator.ValidateBytes(data) // Separate error and warning slices errs := result.Collector.Errors() // []ValidationError (LevelError only) warns := result.Collector.Warnings() // []ValidationError (LevelWarning only) all := result.Collector.All() // errors first, then warnings fmt.Printf("%d error(s), %d warning(s)\n", len(errs), len(warns)) for _, e := range all { // e.Level: LevelError or LevelWarning // e.Path: dot-path like "spec.containers[0].image" // e.Line, e.Column: 1-based source position // e.Message, e.Got, e.Expected fmt.Println(e) // uses Error() string representation } // Sort result in place by file position result.SortByPosition() ``` -------------------------------- ### Validate Key Length with LengthKeyValidator Source: https://context7.com/yakwilik/go-yamlvalidator/llms.txt Utilize LengthKeyValidator to enforce minimum and maximum length constraints on map key names. This ensures keys are neither too short nor excessively long. ```go import keyv "github.com/Yakwilik/go-yamlvalidator/pkg/keyvalidator" schema := &v.FieldSchema{ Type: v.TypeMap, AdditionalProperties: &v.FieldSchema{Type: v.TypeString}, KeyValidators: []v.KeyValidator{ keyv.LengthKeyValidator{ Min: v.Ptr[int](1), Max: v.Ptr[int](63), }, }, } // Key with 64 characters → [ERROR] key too long (expected <= 63 characters, got 64 characters) ``` -------------------------------- ### Restrict to Allowed Strings with EnumValidator Source: https://context7.com/yakwilik/go-yamlvalidator/llms.txt Use EnumValidator to restrict a string value to a predefined set of allowed strings. Ensure the import path is correct. ```go import valv "github.com/Yakwilik/go-yamlvalidator/pkg/valuevalidator" schema := &v.FieldSchema{ Type: v.TypeMap, AllowedKeys: map[string]*v.FieldSchema{ "apiVersion": { Type: v.TypeString, Required: true, Validators: []v.ValueValidator{ valv.EnumValidator{ Allowed: []string{"v1", "v1beta1", "apps/v1"}, Message: "unsupported API version", // optional custom message }, }, }, }, } // YAML: apiVersion: v3 // [ERROR] line 1:13: unsupported API version (expected one of [v1 v1beta1 apps/v1], got v3) (path: apiVersion) ``` -------------------------------- ### Format Validation Errors with Source Context Source: https://context7.com/yakwilik/go-yamlvalidator/llms.txt Use FormatErrorWithSource to display a single ValidationError with a two-line source context and a caret pointing to the error column. This function correctly handles tabs and multi-byte Unicode characters. ```go import v "github.com/Yakwilik/go-yamlvalidator" err := v.ValidationError{ Level: v.LevelError, Path: "metadata.name", Line: 5, Column: 9, Message: "must be lowercase DNS-compatible name", Got: "MyApp", } lines := []string{"metadata:", " name: MyApp", " namespace: production"} // Simulated source lines for line 5 context fmt.Print(v.FormatErrorWithSource(err, lines)) // [ERROR] line 5:9: must be lowercase DNS-compatible name (got MyApp) (path: metadata.name) // 4 | metadata: // > 5 | name: MyApp // | ^ // 6 | namespace: production // Low-level helper for custom formatters: rendered, visualCol, totalLen := v.RenderLineWithCaret("\tname: value", 6) // rendered = " name: value", visualCol = 9 (tab expanded to 4 spaces) ``` -------------------------------- ### Inter-field Logic with AnyOf, ExactlyOneOf, MutuallyExclusive Source: https://context7.com/yakwilik/go-yamlvalidator/llms.txt Enforce relationships between sibling keys in a map using schema-level constraints. `AnyOf` requires at least one group of fields to be present, `ExactlyOneOf` ensures only one field from a list is present, and `MutuallyExclusive` prevents a specific set of fields from appearing together. ```go schema := &v.FieldSchema{ Type: v.TypeMap, AllowedKeys: map[string]*v.FieldSchema{ "configFile": {Type: v.TypeString}, "host": {Type: v.TypeString}, "port": {Type: v.TypeInt}, "inline": {Type: v.TypeString}, "file": {Type: v.TypeString}, "url": {Type: v.TypeString}, "debug": {Type: v.TypeBool}, "quiet": {Type: v.TypeBool}, }, // At least one group must be fully present: // either configFile alone, or both host AND port AnyOf: [][]string{{"configFile"}, {"host", "port"}}, // Exactly one of inline/file/url must be present ExactlyOneOf: []string{"inline", "file", "url"}, // debug and quiet cannot both be present (zero is OK) MutuallyExclusive: []string{"debug", "quiet"} } // [ERROR] at least one of "configFile" or ("host" and "port") is required (path: ) // [ERROR] exactly one of [inline file url] is required, none found (path: ) // [ERROR] fields [debug quiet] are mutually exclusive (path: ) ``` -------------------------------- ### Validate String/Collection Length with LengthValidator Source: https://context7.com/yakwilik/go-yamlvalidator/llms.txt Apply LengthValidator to constrain the character length of strings, the item count of sequences, or the key count of maps. Min and Max bounds are inclusive. ```go import valv "github.com/Yakwilik/go-yamlvalidator/pkg/valuevalidator" schema := &v.FieldSchema{ Type: v.TypeMap, AllowedKeys: map[string]*v.FieldSchema{ "description": { Type: v.TypeString, Validators: []v.ValueValidator{ valv.LengthValidator{ Min: v.Ptr[int](1), Max: v.Ptr[int](255), }, }, }, "tags": { Type: v.TypeSequence, Validators: []v.ValueValidator{ valv.LengthValidator{Max: v.Ptr[int](10)}, // at most 10 items }, ItemSchema: &v.FieldSchema{Type: v.TypeString}, }, }, } // YAML: description: "" // [ERROR] length below minimum (expected >= 1, got 0) (path: description) ``` -------------------------------- ### Go YAML Validator Node Types Source: https://github.com/yakwilik/go-yamlvalidator/blob/master/README.md Lists the available node types for schema validation, specifying the expected data type. ```go type Any type Null type String type Int type Float type Bool type Map type Sequence ``` -------------------------------- ### FieldSchema Definition in Go Source: https://github.com/yakwilik/go-yamlvalidator/blob/master/README.md Defines the structure for validating YAML fields, including type, required status, allowed keys, and custom validators. ```go type FieldSchema struct { // Basic properties Type NodeType // Expected type (TypeString, TypeInt, etc.) Required bool // Field must be present Nullable bool // Allow null values Deprecated string // Deprecation message (empty = not deprecated) Default interface{} // Default value (warning if missing) // Map-specific AllowedKeys map[string]*FieldSchema // Known keys AdditionalProperties *FieldSchema // Schema for unknown keys UnknownKeyPolicy UnknownKeyPolicy // How to handle unknown keys KeyValidators []KeyValidator // Key name validators // Sequence-specific ItemSchema *FieldSchema // Schema for items MinItems *int MaxItems *int // Value validators Validators []ValueValidator // Inter-field logic AnyOf [][]string // At least one group must be present ExactlyOneOf []string // Exactly one field must be present MutuallyExclusive []string // At most one field can be present Conditions []ConditionalRule // Conditional validation } ``` -------------------------------- ### Validate String Format with RegexValidator Source: https://context7.com/yakwilik/go-yamlvalidator/llms.txt Employ RegexValidator to ensure a string conforms to a specific regular expression pattern. The pattern is compiled using `regexp.MustCompile`. ```go import ( "regexp" valv "github.com/Yakwilik/go-yamlvalidator/pkg/valuevalidator" ) schema := &v.FieldSchema{ Type: v.TypeMap, AllowedKeys: map[string]*v.FieldSchema{ "name": { Type: v.TypeString, Validators: []v.ValueValidator{ valv.RegexValidator{ Pattern: regexp.MustCompile(`^[a-z][a-z0-9-]*[a-z0-9]$`), Message: "must be lowercase DNS-compatible name", }, }, }, }, } // YAML: name: MyApp // [ERROR] line 1:7: must be lowercase DNS-compatible name (got MyApp) (path: name) ``` -------------------------------- ### Validate Map Keys with RegexKeyValidator Source: https://context7.com/yakwilik/go-yamlvalidator/llms.txt Employ RegexKeyValidator to enforce a regular expression pattern on all map keys. This ensures keys adhere to specific naming conventions. ```go import keyv "github.com/Yakwilik/go-yamlvalidator/pkg/keyvalidator" schema := &v.FieldSchema{ Type: v.TypeMap, AdditionalProperties: &v.FieldSchema{Type: v.TypeString}, KeyValidators: []v.KeyValidator{ keyv.RegexKeyValidator{ Pattern: regexp.MustCompile(`^[a-z][a-z0-9._-]*$`), Message: "keys must be lowercase and start with a letter", }, }, } // YAML key "123-bad" → [ERROR] keys must be lowercase and start with a letter (got 123-bad) (path: 123-bad) ``` -------------------------------- ### Accessing Validation Results Source: https://github.com/yakwilik/go-yamlvalidator/blob/master/README.md Inspect the ValidationResult object to determine if errors occurred, retrieve lists of errors and warnings, and format the output. The Collector provides access to different error categories. ```go result.HasErrors() // bool result.Collector.Errors() // []ValidationError result.Collector.Warnings() // []ValidationError result.Collector.All() // []ValidationError (errors then warnings) result.SortByPosition() // Sort by line/column result.FormatAll(sortByPos) // Format with source context ``` -------------------------------- ### Allowing Explicit Null Values for Fields Source: https://github.com/yakwilik/go-yamlvalidator/blob/master/README.md Use the Nullable field in a schema definition to permit a field to be explicitly set to null. This is distinct from a field being optional and absent. ```go timeout: { Type: TypeInt, Nullable: true, // Allows: timeout: null } ```