From a52fc2141fb14ab05a46fcab2030b70d36784394 Mon Sep 17 00:00:00 2001 From: Alex Boten Date: Thu, 25 May 2023 13:58:13 -0700 Subject: [PATCH] feat: add support for --tags flag This feature allows users to configure which struct tags to generate. By default it generates json, yaml, mapstructure. Fix #79 Signed-off-by: Alex Boten --- cmd/gojsonschema/main.go | 4 ++++ pkg/generator/generate.go | 14 +++++++++++--- tests/data/misc/tags.go.output | 14 ++++++++++++++ tests/data/misc/tags.json | 16 ++++++++++++++++ tests/integration_test.go | 9 +++++++++ 5 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 tests/data/misc/tags.go.output create mode 100644 tests/data/misc/tags.json diff --git a/cmd/gojsonschema/main.go b/cmd/gojsonschema/main.go index 192e3c3d..720f26ed 100644 --- a/cmd/gojsonschema/main.go +++ b/cmd/gojsonschema/main.go @@ -29,6 +29,7 @@ var ( capitalizations []string resolveExtensions []string yamlExtensions []string + tags []string structNameFromTitle bool errFlagFormat = errors.New("flag must be in the format URI=PACKAGE") @@ -73,6 +74,7 @@ var ( ResolveExtensions: resolveExtensions, YAMLExtensions: yamlExtensions, StructNameFromTitle: structNameFromTitle, + Tags: tags, } for _, id := range allKeys(schemaPackageMap, schemaOutputMap, schemaRootTypeMap) { mapping := generator.SchemaMapping{SchemaID: id} @@ -163,6 +165,8 @@ also look for foo.json if --resolve-extension json is provided.`) `Add a file extension that should be recognized as YAML. Default are .yml, .yaml.`) rootCmd.PersistentFlags().BoolVarP(&structNameFromTitle, "struct-name-from-title", "t", false, "Use the schema title as the generated struct name") + rootCmd.PersistentFlags().StringSliceVar(&tags, "tags", []string{"json", "yaml", "mapstructure"}, + `Specify which struct tags to generate. Defaults are json, yaml, mapstructure`) abortWithErr(rootCmd.Execute()) } diff --git a/pkg/generator/generate.go b/pkg/generator/generate.go index 8f3212d3..af84ac3c 100644 --- a/pkg/generator/generate.go +++ b/pkg/generator/generate.go @@ -24,6 +24,7 @@ type Config struct { DefaultOutputName string StructNameFromTitle bool Warner func(string) + Tags []string } type SchemaMapping struct { @@ -804,13 +805,20 @@ func (g *schemaGenerator) generateStructType( SchemaType: prop, } + tags := "" + if isRequired { - structField.Tags = fmt.Sprintf(`json:"%s" yaml:"%s" mapstructure:"%s"`, name, name, name) + for _, tag := range g.config.Tags { + tags += fmt.Sprintf(`%s:"%s" `, tag, name) + } } else { - structField.Tags = fmt.Sprintf(`json:"%s,omitempty" yaml:"%s,omitempty" mapstructure:"%s,omitempty"`, - name, name, name) + for _, tag := range g.config.Tags { + tags += fmt.Sprintf(`%s:"%s,omitempty" `, tag, name) + } } + structField.Tags = strings.TrimSpace(tags) + if structField.Comment == "" { structField.Comment = fmt.Sprintf("%s corresponds to the JSON schema field %q.", structField.Name, name) diff --git a/tests/data/misc/tags.go.output b/tests/data/misc/tags.go.output new file mode 100644 index 00000000..83ae7b46 --- /dev/null +++ b/tests/data/misc/tags.go.output @@ -0,0 +1,14 @@ +// Code generated by github.com/atombender/go-jsonschema, DO NOT EDIT. + +package test + +type Tags struct { + // Html corresponds to the JSON schema field "html". + Html *string `yaml:"html,omitempty"` + + // Id corresponds to the JSON schema field "id". + Id *string `yaml:"id,omitempty"` + + // Url corresponds to the JSON schema field "url". + Url *string `yaml:"url,omitempty"` +} diff --git a/tests/data/misc/tags.json b/tests/data/misc/tags.json new file mode 100644 index 00000000..2fded5f7 --- /dev/null +++ b/tests/data/misc/tags.json @@ -0,0 +1,16 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "id": "https://example.com/case", + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "id": { + "type": "string" + }, + "html": { + "type": "string" + } + } +} diff --git a/tests/integration_test.go b/tests/integration_test.go index 6363d25f..a87b82c9 100644 --- a/tests/integration_test.go +++ b/tests/integration_test.go @@ -27,6 +27,7 @@ var ( Warner: func(message string) { log.Printf("[from warner] %s", message) }, + Tags: []string{"json", "yaml", "mapstructure"}, } ) @@ -140,6 +141,14 @@ func TestExtraImportsAnotherYAML(t *testing.T) { testExampleFile(t, cfg, "./data/extraImports/gopkgYAMLv2.json") } +func TestTags(t *testing.T) { + t.Parallel() + + cfg := basicConfig + cfg.Tags = []string{"yaml"} + testExampleFile(t, cfg, "./data/misc/tags.json") +} + func testExamples(t *testing.T, cfg generator.Config, dataDir string) { t.Helper()