mirror of https://github.com/knative/func.git
feat: generate json schema for func.yaml (#460)
Signed-off-by: Zbynek Roubalik <zroubali@redhat.com>
This commit is contained in:
parent
85683ea933
commit
8939f89bea
|
@ -6,7 +6,7 @@ on:
|
|||
- "main"
|
||||
jobs:
|
||||
test:
|
||||
runs-on: 'ubuntu-latest'
|
||||
runs-on: "ubuntu-latest"
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-go@v2
|
||||
|
@ -39,6 +39,8 @@ jobs:
|
|||
PKGER: "./pkger"
|
||||
- name: Lint
|
||||
run: make check
|
||||
- name: Check that 'func.yaml schema' is up-to-date
|
||||
run: make schema-check
|
||||
outputs:
|
||||
pkger: ${{ steps.pkger-download-url.outputs.result }}
|
||||
|
||||
|
@ -80,10 +82,10 @@ jobs:
|
|||
run: |
|
||||
curl -s -L -o pkger.tgz ${{ needs.test.outputs.pkger }}
|
||||
tar xvzf pkger.tgz
|
||||
|
||||
|
||||
# Standard build tasks
|
||||
- name: Build
|
||||
run: make cross-platform
|
||||
run: make cross-platform
|
||||
env:
|
||||
PKGER: "./pkger"
|
||||
# NOTE:
|
||||
|
|
|
@ -7,7 +7,7 @@ jobs:
|
|||
build:
|
||||
strategy:
|
||||
matrix:
|
||||
os: ['ubuntu-latest', 'windows-latest', 'macos-latest']
|
||||
os: ["ubuntu-latest", "windows-latest", "macos-latest"]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
@ -58,25 +58,27 @@ jobs:
|
|||
run: |
|
||||
curl -s -L -o pkger.tgz ${{ steps.pkger-download-url.outputs.result }}
|
||||
tar xvzf pkger.tgz
|
||||
|
||||
- name: Unit Test
|
||||
run: make test
|
||||
run: make test
|
||||
env:
|
||||
PKGER: "./${{ steps.pkger-binaries.outputs.binary }}"
|
||||
- name: Template Unit Tests
|
||||
run: make test-templates
|
||||
run: make test-templates
|
||||
env:
|
||||
PKGER: "./${{ steps.pkger-binaries.outputs.binary }}"
|
||||
- name: Build
|
||||
run: make build
|
||||
run: make build
|
||||
env:
|
||||
PKGER: "./${{ steps.pkger-binaries.outputs.binary }}"
|
||||
- name: Lint
|
||||
run: make check
|
||||
- name: Check that 'func.yaml schema' is up-to-date
|
||||
if: matrix.os != 'windows-latest'
|
||||
run: make schema-check
|
||||
|
||||
integration-test:
|
||||
needs: build
|
||||
runs-on: 'ubuntu-latest'
|
||||
runs-on: "ubuntu-latest"
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
@ -106,14 +108,14 @@ jobs:
|
|||
|
||||
e2e-test:
|
||||
needs: integration-test
|
||||
runs-on: 'ubuntu-latest'
|
||||
runs-on: "ubuntu-latest"
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: '^1.16'
|
||||
go-version: "^1.16"
|
||||
- name: Determine download URL for latest pkger
|
||||
id: pkger-download-url
|
||||
uses: actions/github-script@v2
|
||||
|
|
15
Makefile
15
Makefile
|
@ -42,6 +42,7 @@ help:
|
|||
@echo 'Available targets are:'
|
||||
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z0-9_-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
|
||||
|
||||
|
||||
###############
|
||||
##@ Development
|
||||
###############
|
||||
|
@ -109,11 +110,11 @@ test-typescript: ## Test Typescript templates
|
|||
cd templates/typescript/events && npm ci && npm test && rm -rf node_modules build
|
||||
cd templates/typescript/http && npm ci && npm test && rm -rf node_modules build
|
||||
|
||||
|
||||
###################
|
||||
##@ Extended Testing (cluster required)
|
||||
###################
|
||||
|
||||
|
||||
test-integration: ## Run integration tests using an available cluster.
|
||||
go test -tags integration ./... -v
|
||||
|
||||
|
@ -142,3 +143,15 @@ windows: $(BIN_WINDOWS) ## Build for Windows
|
|||
$(BIN_WINDOWS): pkged.go
|
||||
env CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build -o $(BIN_WINDOWS) -ldflags $(LDFLAGS) ./cmd/$(BIN)
|
||||
|
||||
######################
|
||||
##@ Schemas
|
||||
######################
|
||||
schema-generate: ## Generate func.yaml schema
|
||||
go run schema/generator/main.go
|
||||
|
||||
schema-check: ## Check that func.yaml schema is up-to-date
|
||||
mv schema/func_yaml-schema.json schema/func_yaml-schema-previous.json
|
||||
make schema-generate
|
||||
diff schema/func_yaml-schema.json schema/func_yaml-schema-previous.json ||\
|
||||
(echo "\n\nFunction config schema 'schema/func_yaml-schema.json' is obsolete, please run 'make schema-generate'.\n\n"; rm -rf schema/func_yaml-schema-previous.json; exit 1)
|
||||
rm -rf schema/func_yaml-schema-previous.json
|
||||
|
|
36
config.go
36
config.go
|
@ -27,8 +27,8 @@ var (
|
|||
|
||||
type Volumes []Volume
|
||||
type Volume struct {
|
||||
Secret *string `yaml:"secret,omitempty"`
|
||||
ConfigMap *string `yaml:"configMap,omitempty"`
|
||||
Secret *string `yaml:"secret,omitempty" jsonschema:"oneof_required=secret"`
|
||||
ConfigMap *string `yaml:"configMap,omitempty" jsonschema:"oneof_required=configmap"`
|
||||
Path *string `yaml:"path"`
|
||||
}
|
||||
|
||||
|
@ -83,11 +83,11 @@ type Options struct {
|
|||
}
|
||||
|
||||
type ScaleOptions struct {
|
||||
Min *int64 `yaml:"min,omitempty"`
|
||||
Max *int64 `yaml:"max,omitempty"`
|
||||
Metric *string `yaml:"metric,omitempty"`
|
||||
Target *float64 `yaml:"target,omitempty"`
|
||||
Utilization *float64 `yaml:"utilization,omitempty"`
|
||||
Min *int64 `yaml:"min,omitempty" jsonschema_extras:"minimum=0"`
|
||||
Max *int64 `yaml:"max,omitempty" jsonschema_extras:"minimum=0"`
|
||||
Metric *string `yaml:"metric,omitempty" jsonschema:"enum=concurrency,enum=rps"`
|
||||
Target *float64 `yaml:"target,omitempty" jsonschema_extras:"minimum=0.01"`
|
||||
Utilization *float64 `yaml:"utilization,omitempty" jsonschema:"minimum=1,maximum=100"`
|
||||
}
|
||||
|
||||
type ResourcesOptions struct {
|
||||
|
@ -96,20 +96,20 @@ type ResourcesOptions struct {
|
|||
}
|
||||
|
||||
type ResourcesLimitsOptions struct {
|
||||
CPU *string `yaml:"cpu,omitempty"`
|
||||
Memory *string `yaml:"memory,omitempty"`
|
||||
Concurrency *int64 `yaml:"concurrency,omitempty"`
|
||||
CPU *string `yaml:"cpu,omitempty" jsonschema:"pattern=^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$"`
|
||||
Memory *string `yaml:"memory,omitempty" jsonschema:"pattern=^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$"`
|
||||
Concurrency *int64 `yaml:"concurrency,omitempty" jsonschema_extras:"minimum=0"`
|
||||
}
|
||||
|
||||
type ResourcesRequestsOptions struct {
|
||||
CPU *string `yaml:"cpu,omitempty"`
|
||||
Memory *string `yaml:"memory,omitempty"`
|
||||
CPU *string `yaml:"cpu,omitempty" jsonschema:"pattern=^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$"`
|
||||
Memory *string `yaml:"memory,omitempty" jsonschema:"pattern=^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$"`
|
||||
}
|
||||
|
||||
// Config represents the serialized state of a Function's metadata.
|
||||
// See the Function struct for attribute documentation.
|
||||
type config struct {
|
||||
Name string `yaml:"name"`
|
||||
type Config struct {
|
||||
Name string `yaml:"name" jsonschema:"pattern=^[a-z0-9]([-a-z0-9]*[a-z0-9])?$"`
|
||||
Namespace string `yaml:"namespace"`
|
||||
Runtime string `yaml:"runtime"`
|
||||
Image string `yaml:"image"`
|
||||
|
@ -129,7 +129,7 @@ type config struct {
|
|||
// errors accessing an extant config file, or the contents of the file do not
|
||||
// unmarshall. A missing file at a valid path does not error but returns the
|
||||
// empty value of Config.
|
||||
func newConfig(root string) (c config, err error) {
|
||||
func newConfig(root string) (c Config, err error) {
|
||||
filename := filepath.Join(root, ConfigFile)
|
||||
if _, err = os.Stat(filename); err != nil {
|
||||
// do not consider a missing config file an error. Just return.
|
||||
|
@ -217,7 +217,7 @@ func newConfig(root string) (c config, err error) {
|
|||
|
||||
// fromConfig returns a Function populated from config.
|
||||
// Note that config does not include ancillary fields not serialized, such as Root.
|
||||
func fromConfig(c config) (f Function) {
|
||||
func fromConfig(c Config) (f Function) {
|
||||
return Function{
|
||||
Name: c.Name,
|
||||
Namespace: c.Namespace,
|
||||
|
@ -235,8 +235,8 @@ func fromConfig(c config) (f Function) {
|
|||
}
|
||||
|
||||
// toConfig serializes a Function to a config object.
|
||||
func toConfig(f Function) config {
|
||||
return config{
|
||||
func toConfig(f Function) Config {
|
||||
return Config{
|
||||
Name: f.Name,
|
||||
Namespace: f.Namespace,
|
||||
Runtime: f.Runtime,
|
||||
|
|
1
go.mod
1
go.mod
|
@ -4,6 +4,7 @@ go 1.15
|
|||
|
||||
require (
|
||||
github.com/AlecAivazis/survey/v2 v2.2.14
|
||||
github.com/alecthomas/jsonschema v0.0.0-20210526225647-edb03dcab7bc
|
||||
github.com/buildpacks/pack v0.19.0
|
||||
github.com/cloudevents/sdk-go/v2 v2.4.1
|
||||
github.com/containers/image/v5 v5.10.6
|
||||
|
|
5
go.sum
5
go.sum
|
@ -118,6 +118,8 @@ github.com/ahmetb/gen-crd-api-reference-docs v0.3.1-0.20210420163308-c1402a70e2f
|
|||
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
|
||||
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
|
||||
github.com/alecthomas/jsonschema v0.0.0-20180308105923-f2c93856175a/go.mod h1:qpebaTNSsyUn5rPSJMsfqEtDw71TTggXM6stUDI16HA=
|
||||
github.com/alecthomas/jsonschema v0.0.0-20210526225647-edb03dcab7bc h1:mT8qSzuyEAkxbv4GBln7yeuQZpBnfikr3PTuiPs6Z3k=
|
||||
github.com/alecthomas/jsonschema v0.0.0-20210526225647-edb03dcab7bc/go.mod h1:/n6+1/DWPltRLWL/VKyUxg6tzsl5kHUCcraimt4vr60=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
|
@ -556,6 +558,8 @@ github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174 h1:WlZsjVhE8Af9IcZDG
|
|||
github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
|
||||
github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0 h1:i462o439ZjprVSFSZLZxcsoAe592sZB1rci2Z8j4wdk=
|
||||
github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
|
@ -942,6 +946,7 @@ github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoH
|
|||
github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.3.1-0.20190311161405-34c6fa2dc709/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
|
|
|
@ -0,0 +1,222 @@
|
|||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"$ref": "#/definitions/Config",
|
||||
"definitions": {
|
||||
"Config": {
|
||||
"required": [
|
||||
"name",
|
||||
"namespace",
|
||||
"runtime",
|
||||
"image",
|
||||
"imageDigest",
|
||||
"builder",
|
||||
"builderMap",
|
||||
"volumes",
|
||||
"envs",
|
||||
"annotations",
|
||||
"options",
|
||||
"labels"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"pattern": "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$",
|
||||
"type": "string"
|
||||
},
|
||||
"namespace": {
|
||||
"type": "string"
|
||||
},
|
||||
"runtime": {
|
||||
"type": "string"
|
||||
},
|
||||
"image": {
|
||||
"type": "string"
|
||||
},
|
||||
"imageDigest": {
|
||||
"type": "string"
|
||||
},
|
||||
"builder": {
|
||||
"type": "string"
|
||||
},
|
||||
"builderMap": {
|
||||
"patternProperties": {
|
||||
".*": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"volumes": {
|
||||
"items": {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"$ref": "#/definitions/Volume"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"envs": {
|
||||
"items": {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"$ref": "#/definitions/Pair"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"annotations": {
|
||||
"patternProperties": {
|
||||
".*": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"options": {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"$ref": "#/definitions/Options"
|
||||
},
|
||||
"labels": {
|
||||
"items": {
|
||||
"$ref": "#/definitions/Pair"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object"
|
||||
},
|
||||
"Options": {
|
||||
"properties": {
|
||||
"scale": {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"$ref": "#/definitions/ScaleOptions"
|
||||
},
|
||||
"resources": {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"$ref": "#/definitions/ResourcesOptions"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object"
|
||||
},
|
||||
"Pair": {
|
||||
"required": [
|
||||
"value"
|
||||
],
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"value": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object"
|
||||
},
|
||||
"ResourcesLimitsOptions": {
|
||||
"properties": {
|
||||
"cpu": {
|
||||
"pattern": "^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$",
|
||||
"type": "string"
|
||||
},
|
||||
"memory": {
|
||||
"pattern": "^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$",
|
||||
"type": "string"
|
||||
},
|
||||
"concurrency": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object"
|
||||
},
|
||||
"ResourcesOptions": {
|
||||
"properties": {
|
||||
"requests": {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"$ref": "#/definitions/ResourcesRequestsOptions"
|
||||
},
|
||||
"limits": {
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"$ref": "#/definitions/ResourcesLimitsOptions"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object"
|
||||
},
|
||||
"ResourcesRequestsOptions": {
|
||||
"properties": {
|
||||
"cpu": {
|
||||
"pattern": "^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$",
|
||||
"type": "string"
|
||||
},
|
||||
"memory": {
|
||||
"pattern": "^([+-]?[0-9.]+)([eEinumkKMGTP]*[-+]?[0-9]*)$",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object"
|
||||
},
|
||||
"ScaleOptions": {
|
||||
"properties": {
|
||||
"min": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"max": {
|
||||
"type": "integer",
|
||||
"minimum": 0
|
||||
},
|
||||
"metric": {
|
||||
"enum": [
|
||||
"concurrency",
|
||||
"rps"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"target": {
|
||||
"type": "number",
|
||||
"minimum": 0
|
||||
},
|
||||
"utilization": {
|
||||
"maximum": 100,
|
||||
"minimum": 1,
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object"
|
||||
},
|
||||
"Volume": {
|
||||
"required": [
|
||||
"path"
|
||||
],
|
||||
"properties": {
|
||||
"secret": {
|
||||
"type": "string"
|
||||
},
|
||||
"configMap": {
|
||||
"type": "string"
|
||||
},
|
||||
"path": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"type": "object",
|
||||
"oneOf": [
|
||||
{
|
||||
"required": [
|
||||
"secret"
|
||||
],
|
||||
"title": "secret"
|
||||
},
|
||||
{
|
||||
"required": [
|
||||
"configMap"
|
||||
],
|
||||
"title": "configmap"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/alecthomas/jsonschema"
|
||||
|
||||
fn "knative.dev/kn-plugin-func"
|
||||
)
|
||||
|
||||
// This helper application generates json schemas:
|
||||
// - schema for func.yaml stored in schema/func_yaml-schema.json
|
||||
func main() {
|
||||
err := generateFuncYamlSchema()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// generateFuncYamlSchema generates json schema for Function configuration file - func.yaml.
|
||||
// Genereated schema is written into schema/func_yaml-schema.json file
|
||||
func generateFuncYamlSchema() error {
|
||||
// generate json schema for Function struct
|
||||
js := jsonschema.Reflect(&fn.Config{})
|
||||
schema, err := js.MarshalJSON()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// indent the generated json
|
||||
var indentedSchema bytes.Buffer
|
||||
err = json.Indent(&indentedSchema, schema, "", "\t")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// write schema to the file
|
||||
return ioutil.WriteFile("schema/func_yaml-schema.json", indentedSchema.Bytes(), 0644)
|
||||
}
|
Loading…
Reference in New Issue