Documentation
¶
Index ¶
- Constants
- Variables
- func ApplyServiceFile(file *ast.File, action *dsl.Action, servicePkgName string) bool
- func ApplyServiceFileWithModelSync(file *ast.File, action *dsl.Action, servicePkgName string, ...) bool
- func BuildAPIDocFile(pkgName string, entries APIDocEntries) (string, error)
- func BuildMainFile(projectName string) (string, error)
- func BuildModelFile(pkgName string, modelImports []string, stmts ...ast.Stmt) (string, error)
- func BuildRouterFile(pkgName string, modelImports []string, stmts ...ast.Stmt) (string, error)
- func BuildServiceFile(pkgName string, modelImports []string, stmts ...ast.Stmt) (string, error)
- func EmptyLine() *ast.EmptyStmt
- func FormatNode(node ast.Node, processImport ...bool) (string, error)
- func FormatNodeExtra(node ast.Node, processImport ...bool) (string, error)
- func FormatNodeExtraWithFileSet(node ast.Node, fset *token.FileSet, processImport ...bool) (string, error)
- func GenerateService(info *ModelInfo, action *dsl.Action, phase consts.Phase) *ast.File
- func GenerateServiceWithPackage(info *ModelInfo, action *dsl.Action, phase consts.Phase, servicePkgName string) *ast.File
- func GetModulePath() (string, error)
- func GstModelImportEntry(pkgName string) string
- func IsActionServiceSource(path string) bool
- func MethodAddComments(code string, modelName string) string
- func ResolveImportConflicts(imports []string) map[string]string
- func Returns(exprs ...ast.Expr) *ast.ReturnStmt
- func RouterGstModelUse(models []*ModelInfo) (pkgName string, needed bool)
- func ServiceOutputRel(modelFilePath, modelDir string) string
- func StmtLogInfo(str string) *ast.ExprStmt
- func StmtLogWithContext(modelVarName string) *ast.AssignStmt
- func StmtModelRegister(modelName string) *ast.ExprStmt
- func StmtRouterRegister(modelPkgName, modelName, reqName, rspName, gstModelPkg string, ...) *ast.ExprStmt
- func StmtServiceRegister(serviceImport string, phase consts.Phase, route string) *ast.ExprStmt
- type APIDocEntries
- type EnumDocEntry
- type ModelInfo
- type ServiceTargetInfo
- type StructDocEntry
Constants ¶
const GstModelImportPath = "github.com/hydroan/gst/model"
GstModelImportPath is the import path of the gst model package that defines model.Empty, the request type generated for List and Get actions declaring Result (dsl.PayloadEmpty).
Variables ¶
var Methods = []string{ strcase.UpperCamelCase(string(consts.PHASE_CREATE_BEFORE)), strcase.UpperCamelCase(string(consts.PHASE_CREATE_AFTER)), strcase.UpperCamelCase(string(consts.PHASE_DELETE_BEFORE)), strcase.UpperCamelCase(string(consts.PHASE_DELETE_AFTER)), strcase.UpperCamelCase(string(consts.PHASE_UPDATE_BEFORE)), strcase.UpperCamelCase(string(consts.PHASE_UPDATE_AFTER)), strcase.UpperCamelCase(string(consts.PHASE_PATCH_BEFORE)), strcase.UpperCamelCase(string(consts.PHASE_PATCH_AFTER)), strcase.UpperCamelCase(string(consts.PHASE_LIST_BEFORE)), strcase.UpperCamelCase(string(consts.PHASE_LIST_AFTER)), strcase.UpperCamelCase(string(consts.PHASE_GET_BEFORE)), strcase.UpperCamelCase(string(consts.PHASE_GET_AFTER)), strcase.UpperCamelCase(string(consts.PHASE_CREATE_MANY_BEFORE)), strcase.UpperCamelCase(string(consts.PHASE_CREATE_MANY_AFTER)), strcase.UpperCamelCase(string(consts.PHASE_DELETE_MANY_BEFORE)), strcase.UpperCamelCase(string(consts.PHASE_DELETE_MANY_AFTER)), strcase.UpperCamelCase(string(consts.PHASE_UPDATE_MANY_BEFORE)), strcase.UpperCamelCase(string(consts.PHASE_UPDATE_MANY_AFTER)), strcase.UpperCamelCase(string(consts.PHASE_PATCH_MANY_BEFORE)), strcase.UpperCamelCase(string(consts.PHASE_PATCH_MANY_AFTER)), }
Functions ¶
func ApplyServiceFile ¶
ApplyServiceFile will apply the dsl.Action to the ast.File. It will modify the struct type and struct methods if Payload or Result is changed, and returns true. Otherwise returns false. The servicePkgName parameter specifies the expected package name for the service file. This should match the package name used in service registration to maintain consistency.
func ApplyServiceFileWithModelSync ¶
func ApplyServiceFileWithModelSync(file *ast.File, action *dsl.Action, servicePkgName string, modelInfo *ModelInfo) bool
ApplyServiceFileWithModelSync extends ApplyServiceFile to handle import path and package name updates. It will update import statements and package references when model packages are renamed.
Design Philosophy: This function uses AST manipulation instead of regenerating files to preserve user's code formatting and custom modifications. Different developers have different code formatting preferences, and we should not force our formatting on their existing code. We only update the necessary parts (imports and type references) while keeping everything else intact.
Example transformation when "model/oldpkg" is renamed to "model/newpkg": - Import statement: "myproject/model/oldpkg" -> "myproject/model/newpkg" - Type references: oldpkg.User -> newpkg.User, oldpkg.UserReq -> newpkg.UserReq, oldpkg.UserRsp -> newpkg.UserRsp
Parameters: - file: The AST file to process - action: The DSL action configuration - servicePkgName: The expected service package name - modelInfo: The correct model generation context
Returns true if any changes were made to the file.
func BuildAPIDocFile ¶
func BuildAPIDocFile(pkgName string, entries APIDocEntries) (string, error)
BuildAPIDocFile generates an apidoc.go file that registers struct and field doc comments into the apidoc registry at build time, so the OpenAPI document keeps schema descriptions in binaries deployed without Go source files. The content looks like below:
package model
import "github.com/hydroan/gst/apidoc"
func init() {
apidoc.Register("myproject/model", "User", apidoc.StructDoc{
Comment: "User is the user record.",
Fields: map[string]string{
"Name": "Name is the user name.",
},
})
}
func BuildMainFile ¶
BuildMainFile generates a main.go file, the content like below:
package main
import (
_ "helloworld/configx" _ "helloworld/cronjob" _ "helloworld/middleware" _ "helloworld/model" _ "helloworld/module" "helloworld/router" _ "helloworld/service" "github.com/hydroan/gst/bootstrap" . "github.com/hydroan/gst/util"
)
func main() {
RunOrDie(bootstrap.Bootstrap)
RunOrDie(router.Init)
RunOrDie(bootstrap.Run)
}
func BuildModelFile ¶
BuildModelFile generates a model.go file, the content like below:
package model
import "github.com/hydroan/gst/model"
func init() {
model.Register[*Group]()
model.Register[*User]()
}
func BuildRouterFile ¶
BuildRouterFile generates a router.go file, the content like below:
package router
import (
"helloworld/model" "github.com/hydroan/gst/router"
)
func Init() error {
router.Register[*model.Group, *model.Group, *model.Group](router.Auth(), "group")
router.Register[*model.User, *model.User, *model.User](router.Pub(), "user")
return nil
}
FIXME: process imports automatically problem.
func BuildServiceFile ¶
BuildServiceFile generates a service.go file, the content like below:
package service
import (
"github.com/hydroan/gst/service" "github.com/hydroan/gst/types/consts"
)
func init() {
service.Register[*group](consts.PHASE_UPDATE, "groups/:id")
service.Register[*user](consts.PHASE_CREATE, "users")
}
FIXME: process imports automatically problem.
func FormatNode ¶
FormatNode use go standard lib "go/format" to format ast.Node into code.
func FormatNodeExtra ¶
FormatNodeExtra use "https://github.com/mvdan/gofumpt" to format ast.Node into code.
func FormatNodeExtraWithFileSet ¶
func FormatNodeExtraWithFileSet(node ast.Node, fset *token.FileSet, processImport ...bool) (string, error)
FormatNodeExtraWithFileSet formats the node with the given FileSet, which keeps comments in place.
func GenerateService ¶
func GetModulePath ¶
GetModulePath parses go.mod to get module path
func GstModelImportEntry ¶
GstModelImportEntry returns the imports() entry ("path" or "alias path") that makes the given gst model package qualifier resolvable in a generated file.
func IsActionServiceSource ¶
IsActionServiceSource reports whether the Go source file at path contains a type that embeds service.Base with three type parameters, matching gg-generated per-action service files (including those with a custom DSL Filename). It returns false on read/parse errors.
func MethodAddComments ¶
func ResolveImportConflicts ¶
ResolveImportConflicts detects import conflicts and generates unique aliases Returns a map where key is the import path and value is the alias (empty string means no alias needed)
func RouterGstModelUse ¶
RouterGstModelUse resolves how the generated router file references the gst model package. pkgName is the qualifier emitted for model.Empty: the plain package name by default, falling back to the gstmodel alias when a routed business model package is itself named "model" (Go forbids an identifier in both the file and package block, so the plain qualifier would clash with that import). needed reports whether any routed action resolves either side to dsl.PayloadEmpty, i.e. whether the qualifier appears in the file at all. Call it after the route/model ignore passes so disabled actions no longer count as routed.
func ServiceOutputRel ¶
ServiceOutputRel returns the path under the service root where generated service .go files for a model file should live, relative to the service directory (e.g. "common" for model/common/common.go, or "config/namespace/app/env/item" for model/.../env/item.go).
When the file base name (without .go) equals the immediate parent directory name — a common Go layout such as model/pkg/pkg.go — redundant segments are collapsed so output is service/pkg/... instead of service/pkg/pkg/...
func StmtLogInfo ¶
StmtLogInfo create *ast.ExprStmt represents `log.Info(str)`
func StmtLogWithContext ¶
func StmtLogWithContext(modelVarName string) *ast.AssignStmt
StmtLogWithContext create *ast.AssignStmt represents `log := u.WithContext(ctx, ctx.Phase())` modelVarName is model variable name.
func StmtModelRegister ¶
StmtModelRegister creates a *ast.ExprStmt represents golang code like below:
model.Register[*User]()
func StmtRouterRegister ¶
func StmtRouterRegister(modelPkgName, modelName, reqName, rspName, gstModelPkg string, routerGroup string, route string, paramName string, verb string) *ast.ExprStmt
StmtRouterRegister creates a *ast.ExprStmt represents golang code like below:
router.Register[*model.Group, *model.Group, *model.Group](router.Auth(), "group", &types.ControllerConfig[*model.Group]{}, consts.Create)
router.Register[*model.Group, *model.Group, *model.Group](router.Pub(), "login", &types.ControllerConfig[*auth.LoginReq]{}, consts.Create)
routerGroup names the router group accessor ("Auth" or "Pub") and route is the raw route string, shared verbatim with the matching StmtServiceRegister statement. gstModelPkg is the qualifier the router file uses for model.Empty, resolved once per file by RouterGstModelUse.
func StmtServiceRegister ¶
StmtServiceRegister creates a *ast.ExprStmt represents golang code like below:
service.Register[*user.Creator](consts.PHASE_CREATE, "users")
The route argument must be the same raw route string the matching StmtRouterRegister statement carries, because the service registry keys services by route and phase.
Types ¶
type APIDocEntries ¶
type APIDocEntries struct {
Structs []StructDocEntry
Enums []EnumDocEntry
}
APIDocEntries bundles everything registered by the generated apidoc.go.
type EnumDocEntry ¶
EnumDocEntry describes one enum-like named type extracted from a model package: its doc comment and declared constant values.
type ModelInfo ¶
type ModelInfo struct {
// module related fields
ModulePath string // module path parsed from go.mod
// model related fields
ModelPkgName string // model package name, e.g.: model, model_authz, model_log
ModelName string // model name, e.g.: User, Group
ModelVarName string // lowercase model variable name, e.g.: u, g
ModelFileDir string // relative path of model file directory, e.g.: github.com/hydroan/gst/model
ModelFilePath string // relative path of model file, e.g.: github.com/hydroan/gst/model/user.go
// custom request and response related fields
Design *dsl.Design
// RegisterIgnored marks a model matched by a gst.yaml gen.models.ignore
// rule: its generated model.Register call is skipped while column
// generation still treats it as a table-backed model.
RegisterIgnored bool
}
ModelInfo stores model information
Examples: {ModulePath:"github.com/hydroan/gst", ModelPkgName:"model", ModelName:"User", ModelVarName:"u", ModelFileDir:"/tmp/model"}, {ModulePath:"github.com/hydroan/gst", ModelPkgName:"model", ModelName:"Group", ModelVarName:"g", ModelFileDir:"/tmp/model"}, {ModulePath:"github.com/hydroan/gst", ModelPkgName:"model_auth", ModelName:"User", ModelVarName:"u", ModelFileDir:"/tmp/model"}, {ModulePath:"github.com/hydroan/gst", ModelPkgName:"model_auth", ModelName:"Group", ModelVarName:"g", ModelFileDir:"/tmp/model"},
func FindModels ¶
FindModels finds all structs in model files
func (*ModelInfo) ModelImportPath ¶
func (*ModelInfo) RouterImportPath ¶
func (*ModelInfo) ServiceImportPath ¶
type ServiceTargetInfo ¶
func ServiceTarget ¶
func ServiceTarget(m *ModelInfo, action *dsl.Action, modelDir, serviceDir string) ServiceTargetInfo