From cfc61867f2fde3a5f59fc15ed5e0d428463fd8a8 Mon Sep 17 00:00:00 2001 From: Balakrishnan Balasubramanian Date: Mon, 3 Oct 2022 23:27:57 -0400 Subject: [PATCH] Add utility command to generate schema for config --- cmd/generate-config/main.go | 4 ++ cmd/generate-jsonschema/main.go | 107 ++++++++++++++++++++++++++++++++ go.mod | 2 + go.sum | 5 ++ 4 files changed, 118 insertions(+) create mode 100644 cmd/generate-jsonschema/main.go diff --git a/cmd/generate-config/main.go b/cmd/generate-config/main.go index 33b18c471..48d7c5e9b 100644 --- a/cmd/generate-config/main.go +++ b/cmd/generate-config/main.go @@ -18,6 +18,7 @@ func main() { dbURI := flag.String("db", "", "The DB URI to use for all components (PostgreSQL only)") dirPath := flag.String("dir", "./", "The folder to use for paths (like SQLite databases, media storage)") normalise := flag.String("normalise", "", "Normalise an existing configuration file by adding new/missing options and defaults") + schemaPath := flag.String("schema", "", "Path to the schema file") polylith := flag.Bool("polylith", false, "Generate a config that makes sense for polylith deployments") flag.Parse() @@ -103,4 +104,7 @@ func main() { } fmt.Println(string(j)) + if *schemaPath != "" { + fmt.Printf("# yaml-language-server: $schema=%s\n", *schemaPath) + } } diff --git a/cmd/generate-jsonschema/main.go b/cmd/generate-jsonschema/main.go new file mode 100644 index 000000000..8d53aeea0 --- /dev/null +++ b/cmd/generate-jsonschema/main.go @@ -0,0 +1,107 @@ +package main + +import ( + "encoding/json" + "flag" + "os" + "reflect" + "time" + + "github.com/invopop/jsonschema" + "github.com/matrix-org/dendrite/setup/config" + "github.com/uber/jaeger-client-go" + "gopkg.in/yaml.v2" +) + +func mapper(rt reflect.Type) *jsonschema.Schema { + + var d time.Duration + if reflect.TypeOf(d) == rt { + return &jsonschema.Schema{ + Type: "string", + Title: "Duration", + Description: "time.Duration with h, m, s to indicate hours, minutes, seconds", + Pattern: "^[0-9][0-9hms]*$", + } + } + + var du config.DataUnit + if reflect.TypeOf(du) == rt { + return &jsonschema.Schema{ + OneOf: []*jsonschema.Schema{ + &jsonschema.Schema{ + Type: "integer", + }, + &jsonschema.Schema{ + Type: "string", + Pattern: "^[0-9]+([tgmk]b)?$", + }, + }, + Title: "Data Unit", Description: "Data unit with suffix as tb, gb, mb, kb", + } + } + + // Cannot set this option in yaml config + var js jaeger.SamplerOption + if reflect.TypeOf(js) == rt { + return &jsonschema.Schema{ + Type: "string", + Title: "Ignore this", + } + } + return nil +} + +func main() { + useJson := false + flag.BoolVar(&useJson, "json", useJson, "Output json instead of yaml") + flag.Parse() + + reflector := jsonschema.Reflector{ + RequiredFromJSONSchemaTags: true, + DoNotReference: true, + ExpandedStruct: true, + Mapper: mapper, + } + + if err := reflector.AddGoComments("github.com/matrix-org/dendrite", "."); err != nil { + panic(err) + } + + schema := reflector.Reflect(config.Dendrite{}) + + json, err := json.Marshal(schema) + if err != nil { + panic(err) + } + + var data []byte + if useJson { + data = json + } else { + data, err = jsonToYaml(json) + if err != nil { + panic(err) + } + } + + if _, err := os.Stdout.Write(data); err != nil { + panic(err) + } +} + +func jsonToYaml(json []byte) ([]byte, error) { + var ( + a any + yml []byte + err error + ) + if err = yaml.Unmarshal(json, &a); err != nil { + return nil, err + } + + if yml, err = yaml.Marshal(a); err != nil { + return nil, err + } + return yml, nil +} diff --git a/go.mod b/go.mod index c82f76d41..1be7ae1b3 100644 --- a/go.mod +++ b/go.mod @@ -17,6 +17,7 @@ require ( github.com/google/uuid v1.3.0 github.com/gorilla/mux v1.8.0 github.com/gorilla/websocket v1.5.0 + github.com/invopop/jsonschema v0.4.0 github.com/kardianos/minwinsvc v1.0.0 github.com/lib/pq v1.10.7 github.com/matrix-org/dugong v0.0.0-20210921133753-66e6b1c67e2e @@ -89,6 +90,7 @@ require ( github.com/golang/protobuf v1.5.2 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/h2non/filetype v1.1.3 // indirect + github.com/iancoleman/orderedmap v0.0.0-20190318233801-ac98e3ecb4b0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/juju/errors v1.0.0 // indirect github.com/klauspost/compress v1.15.11 // indirect diff --git a/go.sum b/go.sum index a99599cb1..e180a2103 100644 --- a/go.sum +++ b/go.sum @@ -322,8 +322,12 @@ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.0.0 h1:pO2K/gKgKaat5LdpAhxhluX2GPQMaI3W5FUz/I/UnWk= github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo= +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/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/invopop/jsonschema v0.4.0 h1:Yuy/unfgCnfV5Wl7H0HgFufp/rlurqPOOuacqyByrws= +github.com/invopop/jsonschema v0.4.0/go.mod h1:O9uiLokuu0+MGFlyiaqtWxwqJm41/+8Nj0lD7A36YH0= github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v0.0.0-20171115153421-f7279a603ede/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= @@ -553,6 +557,7 @@ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSS 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.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=