fix: allow users to set multi-line comments #1

Manually merged
dananglin merged 1 commit from wip into main 2023-11-24 18:37:50 +00:00
6 changed files with 77 additions and 57 deletions

View file

@ -1,4 +1,5 @@
Copyright (c) 2022 Simon Ser Copyright (c) 2022 Simon Ser
Copyright (c) 2023 Dan Anglin
Permission is hereby granted, free of charge, to any person obtaining a copy of Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in this software and associated documentation files (the "Software"), to deal in

View file

@ -4,9 +4,16 @@ A [JSON schema] code generator for Go.
JSON schema draft 2020-12 is supported. JSON schema draft 2020-12 is supported.
This project is a fork of https://git.sr.ht/~emersion/go-jsonschema with the following changes:
- Add the option to add multi-line comments at the top of the generated file.
- Add the option to name the top-level type.
## Usage ## Usage
jsonschemagen -s <schema> -o <output> ```
go-jsonschema -s <schema> -o <output>
```
One Go type per definition will be generated. One Go type per definition will be generated.

View file

@ -13,15 +13,29 @@ import (
"github.com/dave/jennifer/jen" "github.com/dave/jennifer/jen"
"git.sr.ht/~emersion/go-jsonschema" "codeflow.dananglin.me.uk/forks/go-jsonschema"
) )
type commentListFlag []string
func (c *commentListFlag) String() string {
return strings.Join(*c, "\n")
}
func (c *commentListFlag) Set(comment string) error {
if len(comment) > 0 {
*c = append(*c, comment)
}
return nil
}
func formatId(s string) string { func formatId(s string) string {
fields := strings.FieldsFunc(s, func(c rune) bool { fields := strings.FieldsFunc(s, func(c rune) bool {
return !unicode.IsLetter(c) && !unicode.IsNumber(c) return !unicode.IsLetter(c) && !unicode.IsNumber(c)
}) })
for i, v := range fields { for i, v := range fields {
fields[i] = strings.Title(v) fields[i] = title(v)
} }
return strings.Join(fields, "") return strings.Join(fields, "")
} }
@ -218,21 +232,18 @@ func generateDef(schema *jsonschema.Schema, root *jsonschema.Schema, f *jen.File
).Line() ).Line()
var children []jsonschema.Schema var children []jsonschema.Schema
for _, child := range schema.AllOf { children = append(children, schema.AllOf...)
children = append(children, child) children = append(children, schema.AnyOf...)
} children = append(children, schema.OneOf...)
for _, child := range schema.AnyOf {
children = append(children, child)
}
for _, child := range schema.OneOf {
children = append(children, child)
}
if schema.Then != nil { if schema.Then != nil {
children = append(children, *schema.Then) children = append(children, *schema.Then)
} }
if schema.Else != nil { if schema.Else != nil {
children = append(children, *schema.Else) children = append(children, *schema.Else)
} }
for _, child := range schema.DependentSchemas { for _, child := range schema.DependentSchemas {
children = append(children, child) children = append(children, child)
} }
@ -288,18 +299,24 @@ Generate Go types and helpers for the specified JSON schema.
Options: Options:
-s <schema> JSON schema filename. Required. -s <schema> JSON schema filename. (Required)
-o <output> Output filename for generated Go code. Required. -o <output> Output filename for generated Go code. (Required)
-n <package> Go package name, defaults to the dirname of the output file. -n <package> Go package name, defaults to the directory name of the output file.
-r <name> The name of the top-level struct.
-c <comments> A list of comments to add to the generated file.
` `
func main() { func main() {
var schemaFilename, outputFilename, pkgName string var schemaFilename, outputFilename, pkgName, root string
var comments commentListFlag
flag.StringVar(&schemaFilename, "s", "", "schema filename") flag.StringVar(&schemaFilename, "s", "", "schema filename")
flag.StringVar(&outputFilename, "o", "", "output filename") flag.StringVar(&outputFilename, "o", "", "output filename")
flag.StringVar(&pkgName, "n", "", "package name") flag.StringVar(&pkgName, "n", "", "package name")
flag.StringVar(&root, "r", "root", "name of the top-level struct")
flag.Var(&comments, "c", "list of comments to add at the top of the file")
flag.Usage = func() { flag.Usage = func() {
fmt.Fprintf(os.Stderr, usage) fmt.Fprint(os.Stderr, usage)
} }
flag.Parse() flag.Parse()
@ -319,8 +336,12 @@ func main() {
schema := loadSchema(schemaFilename) schema := loadSchema(schemaFilename)
f := jen.NewFile(pkgName) f := jen.NewFile(pkgName)
if len(comments) > 0 {
f.Comment(comments.String())
}
if schema.Ref == "" { if schema.Ref == "" {
generateDef(schema, schema, f, "root") generateDef(schema, schema, f, root)
} }
var names []string var names []string
@ -337,3 +358,11 @@ func main() {
log.Fatalf("failed to save output file: %v", err) log.Fatalf("failed to save output file: %v", err)
} }
} }
func title(str string) string {
runes := []rune(str)
runes[0] = unicode.ToUpper(runes[0])
return string(runes)
}

6
go.mod
View file

@ -1,5 +1,5 @@
module git.sr.ht/~emersion/go-jsonschema module codeflow.dananglin.me.uk/forks/go-jsonschema
go 1.16 go 1.21
require github.com/dave/jennifer v1.5.1 require github.com/dave/jennifer v1.7.0

36
go.sum
View file

@ -1,34 +1,2 @@
github.com/dave/astrid v0.0.0-20170323122508-8c2895878b14/go.mod h1:Sth2QfxfATb/nW4EsrSi2KyJmbcniZ8TgTaji17D6ms= github.com/dave/jennifer v1.7.0 h1:uRbSBH9UTS64yXbh4FrMHfgfY762RD+C7bUPKODpSJE=
github.com/dave/brenda v1.1.0/go.mod h1:4wCUr6gSlu5/1Tk7akE5X7UorwiQ8Rij0SKH3/BGMOM= github.com/dave/jennifer v1.7.0/go.mod h1:nXbxhEmQfOZhWml3D1cDK5M1FLnMSozpbFN/m3RmGZc=
github.com/dave/courtney v0.3.0/go.mod h1:BAv3hA06AYfNUjfjQr+5gc6vxeBVOupLqrColj+QSD8=
github.com/dave/gopackages v0.0.0-20170318123100-46e7023ec56e/go.mod h1:i00+b/gKdIDIxuLDFob7ustLAVqhsZRk2qVZrArELGQ=
github.com/dave/jennifer v1.5.1 h1:AI8gaM02nCYRw6/WTH0W+S6UNck9YqPZ05xoIxQtuoE=
github.com/dave/jennifer v1.5.1/go.mod h1:AxTG893FiZKqxy3FP1kL80VMshSMuz2G+EgvszgGRnk=
github.com/dave/kerr v0.0.0-20170318121727-bc25dd6abe8e/go.mod h1:qZqlPyPvfsDJt+3wHJ1EvSXDuVjFTK0j2p/ca+gtsb8=
github.com/dave/patsy v0.0.0-20210517141501-957256f50cba/go.mod h1:qfR88CgEGLoiqDaE+xxDCi5QA5v4vUoW0UCX2Nd5Tlc=
github.com/dave/rebecca v0.9.1/go.mod h1:N6XYdMD/OKw3lkF3ywh8Z6wPGuwNFDNtWYEMFWEmXBA=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

View file

@ -114,7 +114,7 @@ func (schema *Schema) UnmarshalJSON(b []byte) error {
*schema = Schema{} *schema = Schema{}
} else if bytes.Equal(b, []byte("false")) { } else if bytes.Equal(b, []byte("false")) {
*schema = Schema{Not: []Schema{ *schema = Schema{Not: []Schema{
Schema{}, {},
}} }}
} else { } else {
type rawSchema Schema type rawSchema Schema
@ -128,7 +128,21 @@ func (schema *Schema) UnmarshalJSON(b []byte) error {
} }
func (schema *Schema) IsTrue() bool { func (schema *Schema) IsTrue() bool {
return len(schema.AllOf) == 0 && len(schema.AnyOf) == 0 && len(schema.OneOf) == 0 && len(schema.Not) == 0 && schema.If == nil && schema.Then == nil && schema.Else == nil && len(schema.DependentSchemas) == 0 && len(schema.PrefixItems) == 0 && schema.Items == nil && schema.Contains == nil && len(schema.Properties) == 0 && len(schema.PatternProperties) == 0 && schema.AdditionalProperties == nil && schema.PropertyNames == nil return len(schema.AllOf) == 0 &&
len(schema.AnyOf) == 0 &&
len(schema.OneOf) == 0 &&
len(schema.Not) == 0 &&
schema.If == nil &&
schema.Then == nil &&
schema.Else == nil &&
len(schema.DependentSchemas) == 0 &&
len(schema.PrefixItems) == 0 &&
schema.Items == nil &&
schema.Contains == nil &&
len(schema.Properties) == 0 &&
len(schema.PatternProperties) == 0 &&
schema.AdditionalProperties == nil &&
schema.PropertyNames == nil
} }
func (schema *Schema) IsFalse() bool { func (schema *Schema) IsFalse() bool {
@ -137,5 +151,6 @@ func (schema *Schema) IsFalse() bool {
return true return true
} }
} }
return false return false
} }