这是indexloc提供的服务,不要输入任何密码
Skip to content

Generate JSON Schema from Golang structs #817

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ cli/turbo
cli/turbo-new
cli/turbo-new.exe
cli/turbo.exe
cli/schema-generation.exe
.DS_Store
cache
.env
Expand Down Expand Up @@ -58,4 +59,4 @@ store
todos.md
examples/*/*.lock
examples/*/*-lock.yaml
.store
.store
3 changes: 3 additions & 0 deletions cli/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ GO_FLAGS += -trimpath
turbo: cmd/turbo/version.go cmd/turbo/*.go internal/*/*.go go.mod
CGO_ENABLED=0 go build $(GO_FLAGS) ./cmd/turbo

schema-generation: cmd/schema-generation/* internal/*/*.go go.mod
CGO_ENABLED=0 go build -o schema-generation.exe $(GO_FLAGS) ./cmd/schema-generation

# These tests are for development
test: test-go vet-go

Expand Down
37 changes: 37 additions & 0 deletions cli/cmd/schema-generation/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package main

import (
"fmt"
"strings"

"github.com/invopop/jsonschema"
"github.com/vercel/turborepo/cli/internal/fs"
)

func main() {
r := new(jsonschema.Reflector)

if err := r.AddGoComments("github.com/vercel/turborepo/cli", "internal/fs"); err != nil {
panic(err)
}

for key, value := range r.CommentMap {
r.CommentMap[key] = applySoftLineBreaks(value)
}

var schema = r.Reflect(&fs.TurboConfigJSON{})
var schemajson, err = schema.MarshalJSON()
if err != nil {
panic(err)
}
fmt.Println(string(schemajson))
}

// applySoftLineBreaks is a function that replaces all soft line breaks
// with a space, and hard line breaks with a newline.
func applySoftLineBreaks(comment string) string {
replaced := strings.ReplaceAll(comment, "\n\n", "[[newline]]")
replaced = strings.ReplaceAll(replaced, "\n", " ")
replaced = strings.ReplaceAll(replaced, "[[newline]]", "\n")
return replaced
}
1 change: 1 addition & 0 deletions cli/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,5 @@ require (
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf // indirect
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
github.com/invopop/jsonschema v0.3.0
)
5 changes: 5 additions & 0 deletions cli/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -265,13 +265,17 @@ 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/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw=
github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
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/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
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.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA=
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/invopop/jsonschema v0.3.0 h1:bLc7vCIFtaJYARy0JXnc/IKZygCms+lfOK4BaJM+fkI=
github.com/invopop/jsonschema v0.3.0/go.mod h1:O9uiLokuu0+MGFlyiaqtWxwqJm41/+8Nj0lD7A36YH0=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
Expand Down Expand Up @@ -399,6 +403,7 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
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=
Expand Down
60 changes: 51 additions & 9 deletions cli/internal/fs/package_json.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,36 @@ import (

// TurboConfigJSON is the root turborepo configuration
type TurboConfigJSON struct {
// Base Git branch
Base string `json:"baseBranch,omitempty"`
// Global root filesystem dependencies
JsonSchema string `json:"$schema"`
// Base is the branch or your git repository. Git is used by turbo in its hashing algorithm
// and --since CLI flag.
Base string `json:"baseBranch,omitempty" jsonschema:"default=origin/master,example=origin/main"`
// GlobalDependencies is a list of globs and environment variables for implicit global hash dependencies.
// Environment variables should be prefixed with $ (e.g. $GITHUB_TOKEN).
//
// Any other entry without this prefix, will be considered filesystem glob. The
// contents of these files will be included in the global hashing algorithm and affect
// the hashes of all tasks.
//
// This is useful for busting the cache based on .env files (not in Git), environment
// variables, or any root level file that impacts package tasks (but are not represented
// in the traditional dependency graph
//
// (e.g. a root tsconfig.json, jest.config.js, .eslintrc, etc.)).
GlobalDependencies []string `json:"globalDependencies,omitempty"`
TurboCacheOptions string `json:"cacheOptions,omitempty"`
Outputs []string `json:"outputs,omitempty"`
// RemoteCacheUrl is the Remote Cache API URL
RemoteCacheUrl string `json:"remoteCacheUrl,omitempty"`
// Pipeline is a map of Turbo pipeline entries which define the task graph
// and cache behavior on a per task or per package-task basis.
Pipeline map[string]Pipeline
// Pipeline is an object representing the task dependency graph of your project. turbo interprets
// these conventions to properly schedule, execute, and cache the outputs of tasks in
// your project.
//
// Each key in this object is the name of a task that can be executed by turbo run. If turbo finds a workspace
// package with a package.json scripts object with a matching key, it will apply the
// pipeline task configuration to that NPM script during execution. This allows you to
// use pipeline to set conventions across your entire Turborepo.
Pipeline map[string]Pipeline `json:"pipeline"`
}

func ReadTurboConfigJSON(path string) (*TurboConfigJSON, error) {
Expand All @@ -41,9 +60,32 @@ func ReadTurboConfigJSON(path string) (*TurboConfigJSON, error) {
}

type PPipeline struct {
Outputs *[]string `json:"outputs"`
Cache *bool `json:"cache,omitempty"`
DependsOn []string `json:"dependsOn,omitempty"`
// The set of glob patterns of a task's cacheable filesystem outputs.
//
// Note: turbo automatically logs stderr/stdout to .turbo/run-<task>.log. This file is
// always treated as a cacheable artifact and never needs to be specified.
//
// Passing an empty array can be used to tell turbo that a task is a side-effect and
// thus doesn't emit any filesystem artifacts (e.g. like a linter), but you still want
// to cache its logs (and treat them like an artifact).
Outputs *[]string `json:"outputs" jsonschema:"default=dist/**,default=build/**"`
// Whether or not to cache the task outputs. Setting cache to false is useful for daemon
// or long-running "watch" or development mode tasks that you don't want to cache.
Cache *bool `json:"cache,omitempty" jsonschema:"default=true"`
// The list of tasks and environment variables that this task depends on.
//
// Prefixing an item in dependsOn with a ^ tells turbo that this pipeline task depends
// on the package's topological dependencies completing the task with the ^ prefix first
// (e.g. "a package's build tasks should only run once all of its dependencies and
// devDependencies have completed their own build commands").
//
// Items in dependsOn without ^ prefix, express the relationships between tasks at the
// package level (e.g. "a package's test and lint commands depend on build being
// completed first").
//
// Prefixing an item in dependsOn with a $ tells turbo that this pipeline task depends
// the value of that environment variable.
DependsOn []string `json:"dependsOn,omitempty"`
}

type Pipeline struct {
Expand Down
1 change: 1 addition & 0 deletions cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"e2e": "node -r esbuild-register scripts/e2e/e2e.ts",
"watch": "watchlist e2e -- pnpm test",
"publish": "make publish-all",
"schema": "make schema-generation",
"format": "go fmt ./cmd/... ./internal/...",
"lint": "go vet ./cmd/... ./internal/..."
},
Expand Down
3 changes: 1 addition & 2 deletions docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"start": "next start",
"build": "next build ",
"lint": "next lint",
"schema": "ts-json-schema-generator -p ./schema.d.ts -o ./public/schema.json -t Schema --minify"
"schema": "(cd ../cli && ./schema-generation.exe) > public/schema.json"
},
"author": "Jared Palmer",
"license": "MPL-2.0",
Expand Down Expand Up @@ -61,7 +61,6 @@
"eslint-config-prettier": "8.4.0",
"postcss": "8.3.5",
"tailwindcss": "3.0.15",
"ts-json-schema-generator": "0.98.0-next.0",
"typescript": "4.5.5",
"webpack": "5.65.0"
},
Expand Down
92 changes: 0 additions & 92 deletions docs/schema.d.ts

This file was deleted.

25 changes: 0 additions & 25 deletions pnpm-lock.yaml

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

12 changes: 10 additions & 2 deletions turbo.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,23 @@
"dependsOn": []
},
"schema": {
"outputs": ["public/schema.json"]
"outputs": [
"schema-generation",
"schema-generation.exe",
"public/schema.json"
]
},
"docs#schema": {
"outputs": ["public/schema.json"],
"dependsOn": ["cli#schema"]
},
"create-turbo#test": {
"dependsOn": ["create-turbo#build"],
"outputs": []
},
"docs#build": {
"outputs": [".next/**"],
"dependsOn": ["^build", "docs#schema"]
"dependsOn": ["^build", "cli#schema"]
}
}
}