Skip to content

Commit

Permalink
feature: generate JSON schema file for configuration for IDE auto com…
Browse files Browse the repository at this point in the history
…pletion
  • Loading branch information
marnixbouhuis committed Nov 22, 2024
1 parent f3e940c commit 063e45d
Show file tree
Hide file tree
Showing 14 changed files with 2,723 additions and 19 deletions.
29 changes: 29 additions & 0 deletions .goreleaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,24 @@ builds:
goarm:
- "6"
- "7"
- id: protoc-gen-jsonschema
main: ./cmd/protoc-gen-jsonschema
binary: protoc-gen-jsonschema
env:
- CGO_ENABLED=0
ldflags:
- -w -s -X github.com/marnixbouhuis/confpb/internal/version.GitReleaseTag={{.Tag}} -X github.com/marnixbouhuis/confpb/internal/version.ReleaseVersion={{.Version}} -X github.com/marnixbouhuis/confpb/internal/version.ShortCommit={{.ShortCommit}}
goos:
- linux
- windows
- darwin
goarch:
- amd64
- arm
- arm64
goarm:
- "6"
- "7"
checksum:
split: true
archives:
Expand All @@ -66,6 +84,17 @@ archives:
format_overrides:
- goos: windows
format: zip
- id: protoc-gen-jsonschema
builds: [ "protoc-gen-jsonschema" ]
format: tar.gz
name_template: >-
{{ .Binary }}_
{{- title .Os }}_
{{- .Arch }}
{{- if .Arm }}v{{ .Arm }}{{ end }}
format_overrides:
- goos: windows
format: zip
changelog:
disable: true
release:
Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@

- `protoc-gen-env`: Automatically map environment variables to protobuf fields in Go code.
- `protoc-gen-default`: Define default values for protobuf fields directly in your `.proto` files.
- erging & Overlaying: Combine multiple protobuf files, allowing one to overlay values from another.
- `protoc-gen-jsonschema`: Generate JSON Schema files for your configuration, enabling IDE autocompletion.
- Merging & Overlaying: Combine multiple protobuf files, allowing one to overlay values from another.
- Multi-format Parsing: Seamlessly parse configurations from various formats such as YAML, JSON, binary protobuf, and text protobuf.

## Why Use `confpb`?
Expand Down Expand Up @@ -125,12 +126,13 @@ Installing a prebuilt binary from release is recommended as this binary contains

### Option 1: Download prebuilt binaries
1. Head to the [releases page](https://github.com/MarnixBouhuis/confpb/releases) to download the appropriate binary for your platform.
- Download both `protoc-gen-env` and `protoc-gen-default`.
- Download `protoc-gen-env`, `protoc-gen-default` and `protoc-gen-jsonschema` (depending on what features you require).
2. Extract the downloaded archives.
3. Move the binaries to a directory in your `$PATH`, such as `/usr/local/bin` or `/bin`.

### Option 2: Building / installing from source
```bash
$ go install github.com/marnixbouhuis/confpb/cmd/protoc-gen-default@latest
$ go install github.com/marnixbouhuis/confpb/cmd/protoc-gen-env@latest
$ go install github.com/marnixbouhuis/confpb/cmd/protoc-gen-jsonschema@latest
```
10 changes: 10 additions & 0 deletions cmd/protoc-gen-jsonschema/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package main

import (
"github.com/marnixbouhuis/confpb/internal/codegen"
"github.com/marnixbouhuis/confpb/internal/codegen/jsonschemagen"
)

func main() {
codegen.RunProtocPlugin(jsonschemagen.GenerateFile)
}
6 changes: 3 additions & 3 deletions examples/sample-app/gen/config/v1/config.defaultpb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions examples/sample-app/gen/config/v1/config.envpb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 11 additions & 11 deletions examples/sample-app/gen/config/v1/config.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

162 changes: 162 additions & 0 deletions examples/sample-app/gen/config/v1/config.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$defs": {
"config.v1.ApplicationConfig": {
"title": "config.v1.ApplicationConfig",
"description": "",
"deprecated": false,
"additionalProperties": false,
"properties": {
"keyValue": {
"title": "config.v1.ApplicationConfig.key_value",
"description": "",
"deprecated": false,
"additionalProperties": {
"title": "config.v1.ApplicationConfig.KeyValueEntry.value",
"description": "",
"deprecated": false,
"type": [
"string"
]
},
"type": [
"object"
]
},
"server": {
"title": "config.v1.ApplicationConfig.server",
"description": "",
"deprecated": false,
"allOf": [
{
"$ref": "#/$defs/config.v1.ApplicationConfig.ServerConfig"
}
]
},
"serverList": {
"items": {
"title": "config.v1.ApplicationConfig.server_list",
"description": "// Multiple values can also be set for nested messages, the env key specified for the list will be used as prefix.\n// Values can be set using:\n// - SERVER_LIST_1_HOST = \"1.2.3.4\"\n// - SERVER_LIST_1_HOST = \"8080\"\n// - SERVER_LIST_2_HOST = \"127.0.0.1\"\n// - SERVER_LIST_2_HOST = \"433\"\n// ...\n",
"deprecated": false,
"allOf": [
{
"$ref": "#/$defs/config.v1.ApplicationConfig.ServerConfig"
}
]
},
"type": [
"array"
]
},
"someDuration": {
"title": "config.v1.ApplicationConfig.some_duration",
"description": "// Some types have a special mapping. For durations, strings are parsed to durations (e.g. 10s, 10m30s, 1h).\n// Other types that use special parsing include: timestamps, structs, struct values, and fields with the \"bytes\" type.\n",
"deprecated": false,
"type": [
"string"
],
"pattern": "^-?([0-9]*[.])?[0-9]+(s)$"
},
"someList": {
"items": {
"title": "config.v1.ApplicationConfig.some_list",
"description": "// Multiple values can be set for a list using:\n// - SOME_LIST_1 = \"item1\"\n// - SOME_LIST_2 = \"item2\"\n// - SOME_LIST_3 = \"item3\"\n// - SOME_LIST_4 = \"item4\"\n// ...\n",
"deprecated": false,
"type": [
"string"
]
},
"type": [
"array"
]
}
},
"type": [
"object"
]
},
"config.v1.ApplicationConfig.ServerConfig": {
"title": "config.v1.ApplicationConfig.ServerConfig",
"description": "",
"deprecated": false,
"additionalProperties": false,
"properties": {
"host": {
"title": "config.v1.ApplicationConfig.ServerConfig.host",
"description": "",
"deprecated": false,
"type": [
"string"
]
},
"port": {
"title": "config.v1.ApplicationConfig.ServerConfig.port",
"description": "",
"deprecated": false,
"type": [
"integer"
],
"maximum": 4294967295,
"minimum": 0
}
},
"type": [
"object"
]
}
},
"title": "config.v1",
"description": "Code generated by protoc-gen-jsonschema. DO NOT EDIT. Schema definitions for config.v1.",
"oneOf": [
{
"title": "Configuration file format for: config.v1.ApplicationConfig.ServerConfig.",
"description": "",
"deprecated": false,
"additionalProperties": false,
"properties": {
"@type": {
"type": [
"string"
],
"const": "type.googleapis.com/config.v1.ApplicationConfig.ServerConfig"
}
},
"allOf": [
{
"$ref": "#/$defs/config.v1.ApplicationConfig.ServerConfig"
}
],
"type": [
"object"
],
"required": [
"@type"
]
},
{
"title": "Configuration file format for: config.v1.ApplicationConfig.",
"description": "",
"deprecated": false,
"additionalProperties": false,
"properties": {
"@type": {
"type": [
"string"
],
"const": "type.googleapis.com/config.v1.ApplicationConfig"
}
},
"allOf": [
{
"$ref": "#/$defs/config.v1.ApplicationConfig"
}
],
"type": [
"object"
],
"required": [
"@type"
]
}
]
}
3 changes: 3 additions & 0 deletions examples/sample-app/generate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@ rm -rf ./gen/*
# - proto-gen-go: go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
# - protoc-gen-default: download / install from this repo's release page.
# - protoc-gen-env: download / install from this repo's release page.
# - protoc-gen-jsonschema: download / install from this repo's release page.
protoc \
--go_out=./gen/ \
--go_opt=paths=source_relative \
--default_out=./gen/ \
--default_opt=paths=source_relative \
--env_out=./gen/ \
--env_opt=paths=source_relative \
--jsonschema_out=./gen/ \
--jsonschema_opt=paths=source_relative \
--proto_path=$PWD/../../proto/ \
--proto_path=./proto/ \
$(find ./proto/ -name "*.proto")
20 changes: 20 additions & 0 deletions internal/codegen/jsonschemagen/e2e/snapshot_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package e2e_test

import (
"testing"

"github.com/marnixbouhuis/confpb/internal/codegen/jsonschemagen"
"github.com/marnixbouhuis/confpb/internal/codegen/testutil"
"github.com/stretchr/testify/require"
)

func TestSnapshot(t *testing.T) {
t.Parallel()

res := testutil.RunGeneratorForFiles(t, jsonschemagen.GenerateFile, testDataFS, "testdata/e2e.proto")
content := testutil.GetFileFromGenerationResult(t, res, "e2e.schema.json")

expected, err := testDataFS.ReadFile("testdata/e2e.schema.json")
require.NoError(t, err)
require.Equal(t, string(expected), content)
}
Loading

0 comments on commit 063e45d

Please sign in to comment.