code/go/internal/specpatch/spec_patch.go (37 lines of code) (raw):

// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one // or more contributor license agreements. Licensed under the Elastic License; // you may not use this file except in compliance with the Elastic License. package specpatch import ( "encoding/json" "fmt" "github.com/Masterminds/semver/v3" jsonpatch "github.com/evanphx/json-patch/v5" ) // Version represents the JSON patches to be applied in each version type Version struct { // Before is the first version that didn't include this change. Before string `json:"before" yaml:"before"` // Patch is a list of JSON patch operations as defined by RFC6902. Patch []interface{} `json:"patch" yaml:"patch"` } // PatchForVersion obtains the JSON patch to be applied given a specific version (e.g. 2.0.0) // and a list of patches per version (Version struct) func PatchForVersion(target semver.Version, versions []Version) ([]byte, error) { var patch []any for _, version := range versions { if sv, err := semver.NewVersion(version.Before); err != nil { return nil, err } else if !target.LessThan(sv) { continue } patch = append(patch, version.Patch...) } if len(patch) == 0 { return nil, nil } return json.Marshal(patch) } // ResolvePatch applies the JSON patch to the given spec func ResolvePatch(spec any, patchJSON []byte) ([]byte, error) { patch, err := jsonpatch.DecodePatch(patchJSON) if err != nil { return nil, fmt.Errorf("failed to decode patch: %w", err) } specBytes, err := json.Marshal(spec) if err != nil { return nil, fmt.Errorf("failed to unmarshal spec for patching: %w", err) } return patch.Apply(specBytes) }