Split & move codegen tasks to codegen/Makefile
This commit is contained in:
2
.github/workflows/snapshot.yml
vendored
2
.github/workflows/snapshot.yml
vendored
@@ -27,7 +27,7 @@ jobs:
|
||||
path: ~/go/pkg/mod
|
||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||
restore-keys: ${{ runner.os }}-go-
|
||||
- run: make test.codegen test.all
|
||||
- run: make test.all
|
||||
|
||||
snapshot-docker:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
7
Makefile
7
Makefile
@@ -133,11 +133,8 @@ watch.test.%: $(FSWATCH)
|
||||
watch.test: watch.test.unit
|
||||
|
||||
# See codegen/README.md for details
|
||||
codegen: $(CUE) $(JSONTPLEXEC)
|
||||
$(CUE) eval codegen/*.cue --out json -e platform | $(JSONTPLEXEC) -v
|
||||
|
||||
test.codegen: $(CUE) $(JSONTPLEXEC)
|
||||
$(CUE) eval codegen/*.cue --out json -e platform > /dev/null
|
||||
codegen:
|
||||
@ make -C codegen all
|
||||
|
||||
cue.fmt: $(CUE)
|
||||
$(CUE) fmt -v codegen/*.cue
|
||||
|
||||
30
Makefile.inc
30
Makefile.inc
@@ -2,6 +2,8 @@ GO = go
|
||||
GOINSTALL = $(GO) install
|
||||
GOFLAGS ?= -trimpath
|
||||
GOPATH ?= $(HOME)/go
|
||||
ROOT_DIR = $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
|
||||
|
||||
|
||||
CGO_ENABLED = 1
|
||||
|
||||
@@ -20,14 +22,17 @@ GIN = $(GOPATH)/bin/gin
|
||||
STATIK = $(GOPATH)/bin/statik
|
||||
MODOUTDATED = $(GOPATH)/bin/go-mod-outdated
|
||||
CUE = $(GOPATH)/bin/cue
|
||||
CODEGEN = build/codegen
|
||||
JSONTPLEXEC = build/json-tpl-exec
|
||||
CODEGEN = $(GOPATH)/bin/corteza-codegen
|
||||
JSONTPLEXEC = $(GOPATH)/bin/corteza-json-tpl-exec
|
||||
|
||||
PROTOC = /usr/local/bin/protoc
|
||||
FSWATCH = /usr/local/bin/fswatch
|
||||
|
||||
# fswatch is intentionally left out...
|
||||
BINS = $(GOCRITIC) $(MOCKGEN) $(GOTEST) $(STATICCHECK) $(PROTOGEN) $(GIN) $(STATIK) $(CODEGEN)
|
||||
BINS = $(GOCRITIC) $(MOCKGEN) $(GOTEST) $(STATICCHECK) $(PROTOGEN) $(GIN) $(STATIK)
|
||||
|
||||
# Corteza's tools
|
||||
CORTEZA_BINS = $(CODEGEN) $(JSONTPLEXEC)
|
||||
|
||||
|
||||
########################################################################################################################
|
||||
@@ -59,16 +64,27 @@ $(STATIK):
|
||||
$(MODOUTDATED):
|
||||
$(GOINSTALL) github.com/psampaz/go-mod-outdated@latest
|
||||
|
||||
$(CODEGEN):
|
||||
$(GO) build -o $@ cmd/codegen/main.go
|
||||
|
||||
$(CUE):
|
||||
$(GOINSTALL) cuelang.org/go/cmd/cue@latest
|
||||
|
||||
$(CODEGEN):
|
||||
$(GO) build -o $@ $(ROOT_DIR)/cmd/codegen/main.go
|
||||
|
||||
$(JSONTPLEXEC):
|
||||
$(GO) build -o $@ ./codegen/tool
|
||||
$(GO) build -o $@ $(ROOT_DIR)/codegen/tool
|
||||
|
||||
clean-tools:
|
||||
rm -f $(BINS)
|
||||
|
||||
clean-corteza-tools:
|
||||
rm -f $(CORTEZA_BINS)
|
||||
|
||||
########################################################################################################################
|
||||
|
||||
COLOUR_GREEN=\033[0;32m
|
||||
COLOUR_RED=\033[0;31m
|
||||
COLOUR_BLUE=\033[0;34m
|
||||
COLOUR_END=\033[0m
|
||||
|
||||
|
||||
#
|
||||
|
||||
1
codegen/.gitignore
vendored
Normal file
1
codegen/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/build
|
||||
18
codegen/Makefile
Normal file
18
codegen/Makefile
Normal file
@@ -0,0 +1,18 @@
|
||||
.PHONY: *.cue
|
||||
|
||||
DEF_ALL = *.cue
|
||||
DEF_SERVER = server.*.cue
|
||||
DEF_DOCS = docs.*.cue
|
||||
|
||||
all: $(DEF_ALL)
|
||||
server: $(DEF_SERVER)
|
||||
docs: $(DEF_DOCS)
|
||||
|
||||
include ../Makefile.inc
|
||||
|
||||
$(DEF_ALL): $(CUE) $(JSONTPLEXEC)
|
||||
@ echo "$(COLOUR_GREEN)Generating from $@$(COLOUR_END)"
|
||||
@ $(CUE) eval $@ --out json | $(JSONTPLEXEC) -v -p ../codegen/assets/templates -b ../
|
||||
|
||||
gen:
|
||||
@ rm $(JSONTPLEXEC)
|
||||
@@ -34,18 +34,36 @@ Platform, component and resource definitions (.cue files) can be found in:
|
||||
|
||||
When a definitions or templates are changed all outputs need to be regenerated
|
||||
|
||||
This can be done with the following command
|
||||
```
|
||||
This can be done with the following command (the root of the project)
|
||||
```shell
|
||||
make codegen
|
||||
```
|
||||
Please note that
|
||||
|
||||
Inside `/codegen` you can run codegen with different options
|
||||
```shell
|
||||
# generate all
|
||||
make
|
||||
|
||||
# generate only server files (golang code, .env.example, ...)
|
||||
make server
|
||||
|
||||
# generate only docs (asciidoc files)
|
||||
make docs
|
||||
|
||||
# generate for only one specific codegen definition
|
||||
make server.options.cue
|
||||
make docs.options.cue
|
||||
|
||||
# or more of them at once
|
||||
make server.options.cue docs.options.cue
|
||||
```
|
||||
|
||||
|
||||
## How does it work?
|
||||
|
||||
### High-level overview
|
||||
|
||||
See [Makefile's `codegen-cue` task](../Makefile)
|
||||
See [Makefile's `codegen` task](../Makefile)
|
||||
|
||||
1. evaluate codegen instructions (see [platform.cue](./platform.cue))
|
||||
2. output instructions as JSON
|
||||
@@ -57,28 +75,8 @@ See [Makefile's `codegen-cue` task](../Makefile)
|
||||
#### Codegen instructions
|
||||
|
||||
Collection of `#codegen` structs with template + payload + output instructions. Template exec tool iterates over collection and creates output from each one.
|
||||
endpoints (unrelated to specific component)
|
||||
|
||||
#### Platform
|
||||
|
||||
Main entry point that combines all components
|
||||
|
||||
- options (see [options.cue](./options.cue))
|
||||
- @todo REST endpoints (unrelated to specific component)
|
||||
|
||||
#### Component
|
||||
|
||||
Defines component, it's behaviour, RBAC operations and resources
|
||||
|
||||
- @todo REST endpoints (unrelated to specific resources)
|
||||
|
||||
#### Resource
|
||||
|
||||
Defines resource, it's behaviour, types, RBAC operations, translatable keys
|
||||
|
||||
- @todo events
|
||||
- @todo actions
|
||||
- @todo errors
|
||||
- @todo automation functions
|
||||
- @todo expression types
|
||||
- @todo REST endpoints
|
||||
# Troubleshooting
|
||||
|
||||
1. Make sure you have the latest version of cue (0.4.2 or newer)
|
||||
|
||||
82
codegen/docs.options.cue
Normal file
82
codegen/docs.options.cue
Normal file
@@ -0,0 +1,82 @@
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"github.com/cortezaproject/corteza-server/app"
|
||||
"github.com/cortezaproject/corteza-server/codegen/schema"
|
||||
)
|
||||
|
||||
[...schema.#codegen] &
|
||||
[
|
||||
{
|
||||
template: "gocode/options/options.go.tpl"
|
||||
output: "pkg/options/options.gen.go"
|
||||
payload: {
|
||||
package: "options"
|
||||
|
||||
// make unique list of packages we'll import
|
||||
imports: [ for i in {for g in app.corteza.options for i in g.imports {"\(i)": i}} {i}]
|
||||
|
||||
groups: [
|
||||
for g in app.corteza.options {
|
||||
func: g.expIdent
|
||||
struct: g.expIdent + "Opt"
|
||||
options: [
|
||||
for o in g.options {
|
||||
o
|
||||
|
||||
default?: string
|
||||
if (o.defaultGoExpr != _|_) {
|
||||
default: o.defaultGoExpr
|
||||
}
|
||||
|
||||
if (o.defaultGoExpr == _|_ && o.defaultValue != _|_) {
|
||||
default: "\"" + o.defaultValue + "\""
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
]+
|
||||
[
|
||||
{
|
||||
template: "docs/.env.example.tpl"
|
||||
output: ".env.example"
|
||||
syntax: ".env"
|
||||
payload: {
|
||||
groups: [
|
||||
for g in app.corteza.options {
|
||||
title: "# " + strings.Join(strings.Split(g.title, "\n"), "\n# ")
|
||||
|
||||
if (g.intro != _|_) {
|
||||
intro: "# " + strings.Join(strings.Split(g.intro, "\n"), "\n# ")
|
||||
}
|
||||
|
||||
options: [
|
||||
for o in g.options {
|
||||
handle: o.handle
|
||||
env: o.env
|
||||
type: o.type
|
||||
|
||||
defaultGoExpr?: string
|
||||
if (o.defaultGoExpr != _|_) {
|
||||
defaultGoExpr: o.defaultGoExpr
|
||||
}
|
||||
|
||||
defaultValue?: string
|
||||
if (o.defaultValue != _|_) {
|
||||
defaultValue: o.defaultValue
|
||||
}
|
||||
|
||||
if (o.description != _|_) {
|
||||
description: "# " + strings.Join(strings.Split(o.description, "\n"), "\n# ")
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
]
|
||||
@@ -1,134 +0,0 @@
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"github.com/cortezaproject/corteza-server/app"
|
||||
"github.com/cortezaproject/corteza-server/codegen/schema"
|
||||
// "strings"
|
||||
)
|
||||
|
||||
envoyRBAC:
|
||||
[...schema.#codegen] &
|
||||
[
|
||||
for cmp in app.corteza.components {
|
||||
template: "gocode/envoy/rbac_references_$component.go.tpl"
|
||||
output: "pkg/envoy/resource/rbac_references_\(cmp.ident).gen.go"
|
||||
payload: {
|
||||
package: "resource"
|
||||
imports: [
|
||||
"\"github.com/cortezaproject/corteza-server/\(cmp.ident)/types\"",
|
||||
]
|
||||
|
||||
resources: [
|
||||
for res in cmp.resources {
|
||||
rbacRefFunc: "\(cmp.expIdent)\(res.expIdent)RbacReferences"
|
||||
references: [
|
||||
for p in res.parents {p},
|
||||
{param: res.ident, refField: "ID", expIdent: res.expIdent},
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
]+
|
||||
[
|
||||
{
|
||||
template: "gocode/envoy/rbac_rules_parse.go.tpl"
|
||||
output: "pkg/envoy/resource/rbac_rules_parse.gen.go"
|
||||
payload: {
|
||||
package: "resource"
|
||||
imports: [
|
||||
for cmp in app.corteza.components {
|
||||
"\(cmp.ident)Types \"github.com/cortezaproject/corteza-server/\(cmp.ident)/types\""
|
||||
},
|
||||
]
|
||||
|
||||
resources: [
|
||||
for cmp in app.corteza.components for res in cmp.resources {
|
||||
importAlias: "\(cmp.ident)Types"
|
||||
expIdent: res.expIdent
|
||||
|
||||
typeConst: "\(importAlias).\(expIdent)ResourceType"
|
||||
rbacRefFunc: "\(cmp.expIdent)\(res.expIdent)RbacReferences"
|
||||
references: [
|
||||
for p in res.parents {p},
|
||||
{param: res.ident, refField: "ID", expIdent: res.expIdent},
|
||||
]
|
||||
},
|
||||
|
||||
for cmp in app.corteza.components {
|
||||
importAlias: "\(cmp.ident)Types"
|
||||
expIdent: cmp.expIdent
|
||||
|
||||
typeConst: "\(importAlias).ComponentResourceType"
|
||||
references: []
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
]+
|
||||
[
|
||||
{
|
||||
template: "gocode/envoy/resource_translation.go.tpl"
|
||||
output: "pkg/envoy/resource/resource_translation.gen.go"
|
||||
payload: {
|
||||
package: "resource"
|
||||
resources: [
|
||||
for cmp in app.corteza.components for res in cmp.resources if res.locale != _|_ {
|
||||
expIdent: "\(cmp.expIdent)\(res.expIdent)"
|
||||
extended: res.locale.extended
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
]+
|
||||
[
|
||||
{
|
||||
template: "gocode/envoy/resource_translation_parse.go.tpl"
|
||||
output: "pkg/envoy/resource/resource_translation_parse.gen.go"
|
||||
payload: {
|
||||
package: "resource"
|
||||
imports: [
|
||||
for cmp in app.corteza.components for res in cmp.resources if res.locale != _|_ {
|
||||
"\(cmp.ident)Types \"github.com/cortezaproject/corteza-server/\(cmp.ident)/types\""
|
||||
},
|
||||
]
|
||||
|
||||
resources: [
|
||||
for cmp in app.corteza.components for res in cmp.resources if res.locale != _|_ {
|
||||
importAlias: "\(cmp.ident)Types"
|
||||
typeConst: "\(importAlias).\(res.expIdent)ResourceTranslationType"
|
||||
resTrRefFunc: "\(cmp.expIdent)\(res.expIdent)ResourceTranslationReferences"
|
||||
references: [
|
||||
for p in res.parents {p},
|
||||
{param: res.ident, refField: "ID", expIdent: res.expIdent},
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
]+
|
||||
[
|
||||
// wrapped with additional for loop to trim out templates with empty types list
|
||||
for tpl in [
|
||||
for cmp in app.corteza.components {
|
||||
template: "gocode/envoy/resource_translation_references_$component.go.tpl"
|
||||
output: "pkg/envoy/resource/resource_translation_references_\(cmp.ident).gen.go"
|
||||
payload: {
|
||||
package: "resource"
|
||||
imports: [
|
||||
"\"github.com/cortezaproject/corteza-server/\(cmp.ident)/types\"",
|
||||
]
|
||||
|
||||
resources: [
|
||||
for res in cmp.resources if res.locale != _|_ {
|
||||
resTrRefFunc: "\(cmp.expIdent)\(res.expIdent)ResourceTranslationReferences"
|
||||
expIdent: res.expIdent
|
||||
references: [
|
||||
for p in res.parents {p},
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
] if len(tpl.payload.resources) > 0 {tpl}]+
|
||||
[]
|
||||
@@ -1,43 +0,0 @@
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"github.com/cortezaproject/corteza-server/app"
|
||||
"github.com/cortezaproject/corteza-server/codegen/schema"
|
||||
)
|
||||
|
||||
localeService:
|
||||
[...schema.#codegen] &
|
||||
[
|
||||
// wrapped with additional for loop to trim out templates with empty types list
|
||||
for tpl in [
|
||||
for cmp in app.corteza.components {
|
||||
template: "gocode/locale/$component_service.go.tpl"
|
||||
output: "\(cmp.ident)/service/locale.gen.go"
|
||||
payload: {
|
||||
package: "service"
|
||||
imports: [
|
||||
"\"github.com/cortezaproject/corteza-server/\(cmp.ident)/types\"",
|
||||
]
|
||||
|
||||
resources: [
|
||||
for res in cmp.resources if (res.locale != _|_) if (!res.locale.skipSvc) {
|
||||
expIdent: res.expIdent
|
||||
ident: res.ident
|
||||
|
||||
references: [ for p in res.parents {p}, {param: "id", refField: "ID"}]
|
||||
|
||||
extended: res.locale.extended
|
||||
|
||||
keys: [ for key in res.locale.keys if key.handlerFunc == _|_ {
|
||||
struct: key.struct
|
||||
|
||||
"extended": extended
|
||||
customHandler: key.customHandler
|
||||
if key.serviceFunc != _|_ {serviceFunc: key.serviceFunc}
|
||||
}]
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
// skip empty type lists
|
||||
] if len(tpl.payload.resources) > 0 {tpl}]
|
||||
@@ -1,55 +0,0 @@
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"github.com/cortezaproject/corteza-server/app"
|
||||
"github.com/cortezaproject/corteza-server/codegen/schema"
|
||||
"strings"
|
||||
)
|
||||
|
||||
localeTypes:
|
||||
[...schema.#codegen] &
|
||||
[
|
||||
// wrapped with additional for loop to trim out templates with empty types list
|
||||
for tpl in [
|
||||
for cmp in app.corteza.components {
|
||||
template: "gocode/locale/$component_types.go.tpl"
|
||||
output: "\(cmp.ident)/types/locale.gen.go"
|
||||
payload: {
|
||||
package: "types"
|
||||
|
||||
resources: [
|
||||
for res in cmp.resources if res.locale != _|_ {
|
||||
expIdent: res.expIdent
|
||||
const: res.locale.resource.const
|
||||
type: res.locale.resource.type
|
||||
|
||||
references: [ for p in res.parents {p}, {param: "id", refField: "ID"}]
|
||||
|
||||
extended: res.locale.extended
|
||||
|
||||
keys: [ for key in res.locale.keys if key.handlerFunc == _|_ {
|
||||
struct: key.struct
|
||||
field: strings.ToTitle(key.name)
|
||||
|
||||
path: strings.Join([ for p in key.expandedPath {
|
||||
if p.var {"{{\(p.part)}}"}
|
||||
if !p.var {p.part}
|
||||
}], ".")
|
||||
|
||||
if !key.customHandler {
|
||||
fieldPath: strings.Join([ for p in key.expandedPath {
|
||||
strings.ToTitle(p.part)
|
||||
}], ".")
|
||||
}
|
||||
|
||||
"extended": extended
|
||||
if key.decodeFunc != _|_ {decodeFunc: key.decodeFunc}
|
||||
if key.encodeFunc != _|_ {encodeFunc: key.encodeFunc}
|
||||
|
||||
}]
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
// skip empty type lists
|
||||
] if len(tpl.payload.resources) > 0 {tpl}]
|
||||
@@ -1,85 +0,0 @@
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"github.com/cortezaproject/corteza-server/app"
|
||||
"github.com/cortezaproject/corteza-server/codegen/schema"
|
||||
)
|
||||
|
||||
options:
|
||||
[...schema.#codegen] &
|
||||
[
|
||||
{
|
||||
template: "gocode/options/options.go.tpl"
|
||||
output: "pkg/options/options.gen.go"
|
||||
payload: {
|
||||
package: "options"
|
||||
|
||||
// make unique list of packages we'll import
|
||||
imports: [ for i in {for g in app.corteza.options for i in g.imports {"\(i)": i}} {i}]
|
||||
|
||||
groups: [
|
||||
for g in app.corteza.options {
|
||||
func: g.expIdent
|
||||
struct: g.expIdent + "Opt"
|
||||
options: [
|
||||
for o in g.options {
|
||||
o
|
||||
|
||||
default?: string
|
||||
if (o.defaultGoExpr != _|_) {
|
||||
default: o.defaultGoExpr
|
||||
}
|
||||
|
||||
if (o.defaultGoExpr == _|_ && o.defaultValue != _|_) {
|
||||
default: "\"" + o.defaultValue + "\""
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
]+
|
||||
|
||||
[
|
||||
{
|
||||
template: "docs/.env.example.tpl"
|
||||
output: ".env.example"
|
||||
syntax: ".env"
|
||||
payload: {
|
||||
groups: [
|
||||
for g in app.corteza.options {
|
||||
title: "# " + strings.Join(strings.Split(g.title, "\n"), "\n# ")
|
||||
|
||||
if (g.intro != _|_) {
|
||||
intro: "# " + strings.Join(strings.Split(g.intro, "\n"), "\n# ")
|
||||
}
|
||||
|
||||
options: [
|
||||
for o in g.options {
|
||||
handle: o.handle
|
||||
env: o.env
|
||||
type: o.type
|
||||
|
||||
defaultGoExpr?: string
|
||||
if (o.defaultGoExpr != _|_) {
|
||||
defaultGoExpr: o.defaultGoExpr
|
||||
}
|
||||
|
||||
defaultValue?: string
|
||||
if (o.defaultValue != _|_) {
|
||||
defaultValue: o.defaultValue
|
||||
}
|
||||
|
||||
if (o.description != _|_) {
|
||||
description: "# " + strings.Join(strings.Split(o.description, "\n"), "\n# ")
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
]+
|
||||
[]
|
||||
@@ -1,19 +0,0 @@
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"github.com/cortezaproject/corteza-server/codegen/schema"
|
||||
)
|
||||
|
||||
// List of all codegen jobs for the entire platform
|
||||
//
|
||||
// How to run it?
|
||||
// @todo when this gets into
|
||||
// cue eval codegen/*.cue --out json -e platform | go run codegen/tool/*.go -v
|
||||
platform: [...schema.#codegen] &
|
||||
rbacAccessControl+
|
||||
rbacTypes+
|
||||
localeTypes+
|
||||
localeService+
|
||||
envoyRBAC+
|
||||
options+
|
||||
[] // placeholder
|
||||
@@ -1,62 +0,0 @@
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"github.com/cortezaproject/corteza-server/codegen/schema"
|
||||
"github.com/cortezaproject/corteza-server/app"
|
||||
)
|
||||
|
||||
rbacAccessControl:
|
||||
[...schema.#codegen] &
|
||||
[
|
||||
for cmp in app.corteza.components {
|
||||
template: "gocode/rbac/$component_access_control.go.tpl"
|
||||
output: "\(cmp.ident)/service/access_control.gen.go"
|
||||
payload: {
|
||||
package: "service"
|
||||
imports: [
|
||||
"\"github.com/cortezaproject/corteza-server/\(cmp.ident)/types\"",
|
||||
]
|
||||
|
||||
// All possible RBAC operations on component and resources
|
||||
// flattened
|
||||
operations: [
|
||||
for res in cmp.resources for op in res.rbac.operations {
|
||||
"op": op.handle
|
||||
const: "types.\(res.expIdent)ResourceType"
|
||||
resFunc: "types.\(res.expIdent)RbacResource"
|
||||
goType: "types.\(res.expIdent)"
|
||||
description: op.description
|
||||
checkFuncName: op.checkFuncName
|
||||
|
||||
references: [ for p in res.parents {p}, {param: "id", refField: "ID"}]
|
||||
},
|
||||
for op in cmp.rbac.operations {
|
||||
"op": op.handle
|
||||
const: "types.ComponentResourceType"
|
||||
resFunc: "types.ComponentRbacResource"
|
||||
goType: "types.Component"
|
||||
description: op.description
|
||||
checkFuncName: op.checkFuncName
|
||||
component: true
|
||||
},
|
||||
]
|
||||
|
||||
// Operation/resource validators, grouped by resource
|
||||
validation: [
|
||||
for res in cmp.resources {
|
||||
label: res.ident
|
||||
const: "types.\(res.expIdent)ResourceType"
|
||||
funcName: "rbac\(res.expIdent)ResourceValidator"
|
||||
references: [ for p in res.parents {p.refField}, "ID"]
|
||||
operations: [ for op in res.rbac.operations {op.handle}]
|
||||
},
|
||||
{
|
||||
label: "\(cmp.ident) component"
|
||||
const: "types.ComponentResourceType"
|
||||
funcName: "rbacComponentResourceValidator"
|
||||
operations: [ for op in cmp.rbac.operations {op.handle}]
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
]
|
||||
@@ -1,42 +0,0 @@
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"github.com/cortezaproject/corteza-server/app"
|
||||
"github.com/cortezaproject/corteza-server/codegen/schema"
|
||||
)
|
||||
|
||||
rbacTypes:
|
||||
[...schema.#codegen] &
|
||||
[
|
||||
for cmp in app.corteza.components {
|
||||
template: "gocode/rbac/$component_types.go.tpl"
|
||||
output: "\(cmp.ident)/types/rbac.gen.go"
|
||||
payload: {
|
||||
package: "types"
|
||||
|
||||
cmpIdent: cmp.ident
|
||||
// Operation/resource validators, grouped by resource
|
||||
types: [
|
||||
for res in cmp.resources {
|
||||
const: "\(res.expIdent)ResourceType"
|
||||
type: res.fqrn
|
||||
resFunc: "\(res.expIdent)RbacResource"
|
||||
tplFunc: "\(res.expIdent)RbacResourceTpl"
|
||||
attFunc: "\(res.expIdent)RbacAttributes"
|
||||
goType: res.expIdent
|
||||
|
||||
references: [ for p in res.parents {p}, {param: "id", refField: "ID"}]
|
||||
},
|
||||
{
|
||||
const: "ComponentResourceType"
|
||||
type: cmp.fqrn
|
||||
resFunc: "ComponentRbacResource"
|
||||
tplFunc: "ComponentRbacResourceTpl"
|
||||
attFunc: "ComponentRbacAttributes"
|
||||
goType: "Component"
|
||||
component: true
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
]
|
||||
133
codegen/server.envoy-rbac.cue
Normal file
133
codegen/server.envoy-rbac.cue
Normal file
@@ -0,0 +1,133 @@
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"github.com/cortezaproject/corteza-server/app"
|
||||
"github.com/cortezaproject/corteza-server/codegen/schema"
|
||||
// "strings"
|
||||
)
|
||||
|
||||
[...schema.#codegen] &
|
||||
[
|
||||
for cmp in app.corteza.components {
|
||||
template: "gocode/envoy/rbac_references_$component.go.tpl"
|
||||
output: "pkg/envoy/resource/rbac_references_\(cmp.ident).gen.go"
|
||||
payload: {
|
||||
package: "resource"
|
||||
imports: [
|
||||
"\"github.com/cortezaproject/corteza-server/\(cmp.ident)/types\"",
|
||||
]
|
||||
|
||||
resources: [
|
||||
for res in cmp.resources {
|
||||
rbacRefFunc: "\(cmp.expIdent)\(res.expIdent)RbacReferences"
|
||||
references: [
|
||||
for p in res.parents {p},
|
||||
{param: res.ident, refField: "ID", expIdent: res.expIdent},
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
]+
|
||||
[
|
||||
{
|
||||
template: "gocode/envoy/rbac_rules_parse.go.tpl"
|
||||
output: "pkg/envoy/resource/rbac_rules_parse.gen.go"
|
||||
payload: {
|
||||
package: "resource"
|
||||
imports: [
|
||||
for cmp in app.corteza.components {
|
||||
"\(cmp.ident)Types \"github.com/cortezaproject/corteza-server/\(cmp.ident)/types\""
|
||||
},
|
||||
]
|
||||
|
||||
resources: [
|
||||
for cmp in app.corteza.components for res in cmp.resources {
|
||||
importAlias: "\(cmp.ident)Types"
|
||||
expIdent: res.expIdent
|
||||
|
||||
typeConst: "\(importAlias).\(expIdent)ResourceType"
|
||||
rbacRefFunc: "\(cmp.expIdent)\(res.expIdent)RbacReferences"
|
||||
references: [
|
||||
for p in res.parents {p},
|
||||
{param: res.ident, refField: "ID", expIdent: res.expIdent},
|
||||
]
|
||||
},
|
||||
|
||||
for cmp in app.corteza.components {
|
||||
importAlias: "\(cmp.ident)Types"
|
||||
expIdent: cmp.expIdent
|
||||
|
||||
typeConst: "\(importAlias).ComponentResourceType"
|
||||
references: []
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
]+
|
||||
[
|
||||
{
|
||||
template: "gocode/envoy/resource_translation.go.tpl"
|
||||
output: "pkg/envoy/resource/resource_translation.gen.go"
|
||||
payload: {
|
||||
package: "resource"
|
||||
resources: [
|
||||
for cmp in app.corteza.components for res in cmp.resources if res.locale != _|_ {
|
||||
expIdent: "\(cmp.expIdent)\(res.expIdent)"
|
||||
extended: res.locale.extended
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
]+
|
||||
[
|
||||
{
|
||||
template: "gocode/envoy/resource_translation_parse.go.tpl"
|
||||
output: "pkg/envoy/resource/resource_translation_parse.gen.go"
|
||||
payload: {
|
||||
package: "resource"
|
||||
imports: [
|
||||
for cmp in app.corteza.components for res in cmp.resources if res.locale != _|_ {
|
||||
"\(cmp.ident)Types \"github.com/cortezaproject/corteza-server/\(cmp.ident)/types\""
|
||||
},
|
||||
]
|
||||
|
||||
resources: [
|
||||
for cmp in app.corteza.components for res in cmp.resources if res.locale != _|_ {
|
||||
importAlias: "\(cmp.ident)Types"
|
||||
typeConst: "\(importAlias).\(res.expIdent)ResourceTranslationType"
|
||||
resTrRefFunc: "\(cmp.expIdent)\(res.expIdent)ResourceTranslationReferences"
|
||||
references: [
|
||||
for p in res.parents {p},
|
||||
{param: res.ident, refField: "ID", expIdent: res.expIdent},
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
]+
|
||||
[
|
||||
// wrapped with additional for loop to trim out templates with empty types list
|
||||
for tpl in [
|
||||
for cmp in app.corteza.components {
|
||||
template: "gocode/envoy/resource_translation_references_$component.go.tpl"
|
||||
output: "pkg/envoy/resource/resource_translation_references_\(cmp.ident).gen.go"
|
||||
payload: {
|
||||
package: "resource"
|
||||
imports: [
|
||||
"\"github.com/cortezaproject/corteza-server/\(cmp.ident)/types\"",
|
||||
]
|
||||
|
||||
resources: [
|
||||
for res in cmp.resources if res.locale != _|_ {
|
||||
resTrRefFunc: "\(cmp.expIdent)\(res.expIdent)ResourceTranslationReferences"
|
||||
expIdent: res.expIdent
|
||||
references: [
|
||||
for p in res.parents {p},
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
] if len(tpl.payload.resources) > 0 {tpl}
|
||||
]
|
||||
43
codegen/server.locale-service.cue
Normal file
43
codegen/server.locale-service.cue
Normal file
@@ -0,0 +1,43 @@
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"github.com/cortezaproject/corteza-server/app"
|
||||
"github.com/cortezaproject/corteza-server/codegen/schema"
|
||||
)
|
||||
|
||||
[...schema.#codegen] &
|
||||
[
|
||||
// wrapped with additional for loop to trim out templates with empty types list
|
||||
for tpl in [
|
||||
for cmp in app.corteza.components {
|
||||
template: "gocode/locale/$component_service.go.tpl"
|
||||
output: "\(cmp.ident)/service/locale.gen.go"
|
||||
payload: {
|
||||
package: "service"
|
||||
imports: [
|
||||
"\"github.com/cortezaproject/corteza-server/\(cmp.ident)/types\"",
|
||||
]
|
||||
|
||||
resources: [
|
||||
for res in cmp.resources if (res.locale != _|_) if (!res.locale.skipSvc) {
|
||||
expIdent: res.expIdent
|
||||
ident: res.ident
|
||||
|
||||
references: [ for p in res.parents {p}, {param: "id", refField: "ID"}]
|
||||
|
||||
extended: res.locale.extended
|
||||
|
||||
keys: [ for key in res.locale.keys if key.handlerFunc == _|_ {
|
||||
struct: key.struct
|
||||
|
||||
"extended": extended
|
||||
customHandler: key.customHandler
|
||||
if key.serviceFunc != _|_ {serviceFunc: key.serviceFunc}
|
||||
}]
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
// skip empty type lists
|
||||
] if len(tpl.payload.resources) > 0 {tpl}
|
||||
]
|
||||
55
codegen/server.locale-types.cue
Normal file
55
codegen/server.locale-types.cue
Normal file
@@ -0,0 +1,55 @@
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"github.com/cortezaproject/corteza-server/app"
|
||||
"github.com/cortezaproject/corteza-server/codegen/schema"
|
||||
"strings"
|
||||
)
|
||||
|
||||
[...schema.#codegen] &
|
||||
[
|
||||
// wrapped with additional for loop to trim out templates with empty types list
|
||||
for tpl in [
|
||||
for cmp in app.corteza.components {
|
||||
template: "gocode/locale/$component_types.go.tpl"
|
||||
output: "\(cmp.ident)/types/locale.gen.go"
|
||||
payload: {
|
||||
package: "types"
|
||||
|
||||
resources: [
|
||||
for res in cmp.resources if res.locale != _|_ {
|
||||
expIdent: res.expIdent
|
||||
const: res.locale.resource.const
|
||||
type: res.locale.resource.type
|
||||
|
||||
references: [ for p in res.parents {p}, {param: "id", refField: "ID"}]
|
||||
|
||||
extended: res.locale.extended
|
||||
|
||||
keys: [ for key in res.locale.keys if key.handlerFunc == _|_ {
|
||||
struct: key.struct
|
||||
field: strings.ToTitle(key.name)
|
||||
|
||||
path: strings.Join([ for p in key.expandedPath {
|
||||
if p.var {"{{\(p.part)}}"}
|
||||
if !p.var {p.part}
|
||||
}], ".")
|
||||
|
||||
if !key.customHandler {
|
||||
fieldPath: strings.Join([ for p in key.expandedPath {
|
||||
strings.ToTitle(p.part)
|
||||
}], ".")
|
||||
}
|
||||
|
||||
"extended": extended
|
||||
if key.decodeFunc != _|_ {decodeFunc: key.decodeFunc}
|
||||
if key.encodeFunc != _|_ {encodeFunc: key.encodeFunc}
|
||||
|
||||
}]
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
// skip empty type lists
|
||||
] if len(tpl.payload.resources) > 0 {tpl}
|
||||
]
|
||||
82
codegen/server.options.cue
Normal file
82
codegen/server.options.cue
Normal file
@@ -0,0 +1,82 @@
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"github.com/cortezaproject/corteza-server/app"
|
||||
"github.com/cortezaproject/corteza-server/codegen/schema"
|
||||
)
|
||||
|
||||
[...schema.#codegen] &
|
||||
[
|
||||
{
|
||||
template: "gocode/options/options.go.tpl"
|
||||
output: "pkg/options/options.gen.go"
|
||||
payload: {
|
||||
package: "options"
|
||||
|
||||
// make unique list of packages we'll import
|
||||
imports: [ for i in {for g in app.corteza.options for i in g.imports {"\(i)": i}} {i}]
|
||||
|
||||
groups: [
|
||||
for g in app.corteza.options {
|
||||
func: g.expIdent
|
||||
struct: g.expIdent + "Opt"
|
||||
options: [
|
||||
for o in g.options {
|
||||
o
|
||||
|
||||
default?: string
|
||||
if (o.defaultGoExpr != _|_) {
|
||||
default: o.defaultGoExpr
|
||||
}
|
||||
|
||||
if (o.defaultGoExpr == _|_ && o.defaultValue != _|_) {
|
||||
default: "\"" + o.defaultValue + "\""
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
]+
|
||||
[
|
||||
{
|
||||
template: "docs/.env.example.tpl"
|
||||
output: ".env.example"
|
||||
syntax: ".env"
|
||||
payload: {
|
||||
groups: [
|
||||
for g in app.corteza.options {
|
||||
title: "# " + strings.Join(strings.Split(g.title, "\n"), "\n# ")
|
||||
|
||||
if (g.intro != _|_) {
|
||||
intro: "# " + strings.Join(strings.Split(g.intro, "\n"), "\n# ")
|
||||
}
|
||||
|
||||
options: [
|
||||
for o in g.options {
|
||||
handle: o.handle
|
||||
env: o.env
|
||||
type: o.type
|
||||
|
||||
defaultGoExpr?: string
|
||||
if (o.defaultGoExpr != _|_) {
|
||||
defaultGoExpr: o.defaultGoExpr
|
||||
}
|
||||
|
||||
defaultValue?: string
|
||||
if (o.defaultValue != _|_) {
|
||||
defaultValue: o.defaultValue
|
||||
}
|
||||
|
||||
if (o.description != _|_) {
|
||||
description: "# " + strings.Join(strings.Split(o.description, "\n"), "\n# ")
|
||||
}
|
||||
},
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
]
|
||||
61
codegen/server.rbac-access_control.cue
Normal file
61
codegen/server.rbac-access_control.cue
Normal file
@@ -0,0 +1,61 @@
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"github.com/cortezaproject/corteza-server/codegen/schema"
|
||||
"github.com/cortezaproject/corteza-server/app"
|
||||
)
|
||||
|
||||
[...schema.#codegen] &
|
||||
[
|
||||
for cmp in app.corteza.components {
|
||||
template: "gocode/rbac/$component_access_control.go.tpl"
|
||||
output: "\(cmp.ident)/service/access_control.gen.go"
|
||||
payload: {
|
||||
package: "service"
|
||||
imports: [
|
||||
"\"github.com/cortezaproject/corteza-server/\(cmp.ident)/types\"",
|
||||
]
|
||||
|
||||
// All possible RBAC operations on component and resources
|
||||
// flattened
|
||||
operations: [
|
||||
for res in cmp.resources for op in res.rbac.operations {
|
||||
"op": op.handle
|
||||
const: "types.\(res.expIdent)ResourceType"
|
||||
resFunc: "types.\(res.expIdent)RbacResource"
|
||||
goType: "types.\(res.expIdent)"
|
||||
description: op.description
|
||||
checkFuncName: op.checkFuncName
|
||||
|
||||
references: [ for p in res.parents {p}, {param: "id", refField: "ID"}]
|
||||
},
|
||||
for op in cmp.rbac.operations {
|
||||
"op": op.handle
|
||||
const: "types.ComponentResourceType"
|
||||
resFunc: "types.ComponentRbacResource"
|
||||
goType: "types.Component"
|
||||
description: op.description
|
||||
checkFuncName: op.checkFuncName
|
||||
component: true
|
||||
},
|
||||
]
|
||||
|
||||
// Operation/resource validators, grouped by resource
|
||||
validation: [
|
||||
for res in cmp.resources {
|
||||
label: res.ident
|
||||
const: "types.\(res.expIdent)ResourceType"
|
||||
funcName: "rbac\(res.expIdent)ResourceValidator"
|
||||
references: [ for p in res.parents {p.refField}, "ID"]
|
||||
operations: [ for op in res.rbac.operations {op.handle}]
|
||||
},
|
||||
{
|
||||
label: "\(cmp.ident) component"
|
||||
const: "types.ComponentResourceType"
|
||||
funcName: "rbacComponentResourceValidator"
|
||||
operations: [ for op in cmp.rbac.operations {op.handle}]
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
]
|
||||
41
codegen/server.rbac-types.cue
Normal file
41
codegen/server.rbac-types.cue
Normal file
@@ -0,0 +1,41 @@
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"github.com/cortezaproject/corteza-server/app"
|
||||
"github.com/cortezaproject/corteza-server/codegen/schema"
|
||||
)
|
||||
|
||||
[...schema.#codegen] &
|
||||
[
|
||||
for cmp in app.corteza.components {
|
||||
template: "gocode/rbac/$component_types.go.tpl"
|
||||
output: "\(cmp.ident)/types/rbac.gen.go"
|
||||
payload: {
|
||||
package: "types"
|
||||
|
||||
cmpIdent: cmp.ident
|
||||
// Operation/resource validators, grouped by resource
|
||||
types: [
|
||||
for res in cmp.resources {
|
||||
const: "\(res.expIdent)ResourceType"
|
||||
type: res.fqrn
|
||||
resFunc: "\(res.expIdent)RbacResource"
|
||||
tplFunc: "\(res.expIdent)RbacResourceTpl"
|
||||
attFunc: "\(res.expIdent)RbacAttributes"
|
||||
goType: res.expIdent
|
||||
|
||||
references: [ for p in res.parents {p}, {param: "id", refField: "ID"}]
|
||||
},
|
||||
{
|
||||
const: "ComponentResourceType"
|
||||
type: cmp.fqrn
|
||||
resFunc: "ComponentRbacResource"
|
||||
tplFunc: "ComponentRbacResourceTpl"
|
||||
attFunc: "ComponentRbacAttributes"
|
||||
goType: "Component"
|
||||
component: true
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
]
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"text/template"
|
||||
|
||||
"github.com/cortezaproject/corteza-server/pkg/cli"
|
||||
@@ -23,12 +24,14 @@ var (
|
||||
verbose bool
|
||||
showHelp bool
|
||||
tplRootPath string
|
||||
outputBase string
|
||||
)
|
||||
|
||||
func init() {
|
||||
flag.BoolVar(&showHelp, "h", false, "show help")
|
||||
flag.BoolVar(&verbose, "v", false, "be verbose")
|
||||
flag.StringVar(&tplRootPath, "p", "codegen/assets/templates", "location of the template files")
|
||||
flag.StringVar(&outputBase, "b", ".", "base dir for output")
|
||||
flag.Parse()
|
||||
}
|
||||
|
||||
@@ -56,13 +59,14 @@ func main() {
|
||||
}
|
||||
|
||||
for _, j := range tasks {
|
||||
print(fmt.Sprintf("generating %s (from %s) ...", j.Output, j.Template))
|
||||
output := path.Join(outputBase, j.Output)
|
||||
print(fmt.Sprintf("generating %s (from %s) ...", output, j.Template))
|
||||
|
||||
switch j.Syntax {
|
||||
case "go":
|
||||
err = writeFormattedGo(j.Output, tpl.Lookup(j.Template), j.Payload)
|
||||
err = writeFormattedGo(output, tpl.Lookup(j.Template), j.Payload)
|
||||
default:
|
||||
err = write(j.Output, tpl.Lookup(j.Template), j.Payload)
|
||||
err = write(output, tpl.Lookup(j.Template), j.Payload)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user