作者 yangfu

pm init

# Binaries for programs and plugins
*.exe
*.dll
*.so
*.dylib
*.vscode
# Test binary, build with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
*.log
*debug
*wasm
*.idea
*.sum
# protoc
#*.pb.go
\ No newline at end of file
... ...
module pm
go 1.16
require (
github.com/tal-tech/go-zero v1.0.27
github.com/tiptok/gocomm v1.0.12
gopkg.in/yaml.v2 v2.3.0
)
replace (
github.com/tiptok/gocomm v1.0.12 => F:\go\src\learn_project\gocomm
)
\ No newline at end of file
... ...
package main
import (
"bytes"
"flag"
"fmt"
"github.com/tal-tech/go-zero/core/mapping"
"github.com/tiptok/gocomm/common"
"github.com/tiptok/gocomm/gs"
"gopkg.in/yaml.v2"
"html/template"
"io/fs"
"io/ioutil"
"os"
"path/filepath"
"sort"
"strings"
)
const (
ModulePrintModel ="print"
ModulePrintGateway ="gateway"
)
var projectPath string
var useCase string
func init(){
flag.StringVar(&useCase,"m","print","module 1.print(打印模型) 2.gateway(输出网关接口)")
flag.StringVar(&projectPath,"p","F:\\go\\src\\mmm-go-pp\\terms\\document\\terms","项目描述文件根目录")
}
var attrMap map[string]*MetaDataItem = make(map[string]*MetaDataItem)
var schemaMap map[string]Schema = make(map[string]Schema)
var apiMap map[string]ApiItem= make(map[string]ApiItem)
var apiKey []string
func main(){
flag.Parse()
schemaPath:=filepath.Join(projectPath,"schemas")
attributesPath:=filepath.Join(projectPath,"attributes")
apiPath:=filepath.Join(projectPath,"api")
valid()
initSchema(schemaPath)
initAttr(attributesPath)
initApi(apiPath)
switch useCase {
case ModulePrintModel:
printSchema()
case ModulePrintGateway:
printGateWay()
}
}
func valid(){
if _,err:=os.Stat(projectPath);err!=nil{
fmt.Println(err)
}
}
func initSchema(schemaPath string){
schemaFiles,_ :=ioutil.ReadDir(schemaPath)
for _,f :=range schemaFiles{
var schema Schema
if f.IsDir(){
continue
}
fr,_ :=os.Open(filepath.Join(schemaPath,f.Name()))
if err :=mapping.UnmarshalYamlReader(fr,&schema);err!=nil{
fmt.Printf("file:%v error:%v \n",f.Name(),err.Error())
continue
}
schemaMap[schema.MetaData.Name] = schema
}
}
func initAttr(attributesPath string){
filepath.WalkDir(attributesPath,wrapperWalkDirFunc(readAttr))
}
func initApi(apiPath string){
filepath.WalkDir(apiPath,wrapperWalkDirFunc(readApi))
}
func readAttr(f *os.File)error{
var attr Attribute
if err :=mapping.UnmarshalYamlReader(f,&attr);err!=nil{
return err
}
attrMap[attr.MetaDataItem.Name]=attr.MetaDataItem
return nil
}
func readApi(f *os.File)error{
var data gs.MapData
content, err := ioutil.ReadAll(f)
if err != nil {
return err
}
if err :=yaml.Unmarshal(content, &data);err!=nil{
return err
}
service :=data.String("metadata.service")
paths:=data.String("metadata.path")
endpoints,_:=data.FindField("metadata.endpoints")
endpointsMap :=endpoints.([]interface{})
for _,p:=range endpointsMap{
mapP:=p.(map[interface{}]interface{})
method :=mapP["method"].(string)
httpMethod,route :=mapFirstKv(mapP["route"].(map[interface{}]interface{}))
apiItem:=ApiItem{
Method:common.CamelCase(service,true)+common.CamelCase(method,true),
Path: paths+route,
HttpMethod:strings.ToUpper(httpMethod),
}
apiItem.Path = strings.Replace(apiItem.Path,"}","",-1)
apiItem.Path = strings.Replace(apiItem.Path,"/{","/:",-1)
apiMap[apiItem.Method] = apiItem
apiKey = append(apiKey,apiItem.Method)
}
return nil
}
func wrapperWalkDirFunc(doFile func(f *os.File)error)fs.WalkDirFunc{
return func(path string, d fs.DirEntry, err error)error{
defer func(){
if p:=recover();p!=nil{
fmt.Println(path)
}
}()
if d==nil{
return nil
}
if d.IsDir(){
return nil
}
if f,err:=os.Open(path);err!=nil{
return err
}else {
err=doFile(f)
}
return err
}
}
func mapFirstOne(mts map[string]interface{})string{
for k,v:=range mts{
value:=common.AssertString(v)
if strings.ToUpper(k)=="ARRAY"{
return "[]"+value
}
return value
}
return ""
}
func mapFirstKv(mts map[interface{}]interface{})(string,string){
for k,v:=range mts{
return k.(string),v.(string)
}
return "",""
}
func printSchema(){
var keys []string
for k,_:=range schemaMap{
keys = append(keys,k)
}
sort.Strings(keys)
for _,k :=range keys{
schema:=schemaMap[k]
fmt.Println("\n\n")
fmt.Printf("%v %v\n\n",schema.MetaData.Name,schema.MetaData.Description)
for _,v :=range schema.MetaData.Attributes{
if len(v.Ref)>0{
if attr,ok:=attrMap[v.Ref];ok{
fmt.Printf("%-15s %-10s %v\n",attr.Name,mapFirstOne(attr.Type),attr.Description)
}
continue
}
fmt.Printf("%-15s %-10s %v\n",v.Name,mapFirstOne(v.Type),v.Description)
}
}
}
func printGateWay(){
var keys []string
for k,_:=range apiMap{
keys = append(keys,k)
}
sort.Strings(keys)
var apiList []ApiItem
for _,k:=range keys{
apiList = append(apiList,apiMap[k])
}
t:=template.New("gateway")
gt,err:= t.Parse(gatewayTemplate)
if err!=nil{
fmt.Println(err)
}
buf :=bytes.NewBuffer(nil)
gt.Execute(buf,map[string]interface{}{"Routers":apiList})
fmt.Println("print gateway")
fmt.Println(buf.String())
}
... ...
package main
type Schema struct {
MetaData *MetaData `json:"metadata,optional"`
}
type MetaData struct {
Name string `json:"name,optional"`
Description string `json:"description,optional"`
Attributes []*Attributes `json:"attributes,optional"`
}
type Attributes struct {
Ref string `json:"ref,optional"`
Name string `json:"name,optional"`
Description string `json:"description,optional"`
Type map[string]interface{} `json:"type,optional"`
}
type Attribute struct {
MetaDataItem *MetaDataItem `json:"metadata,optional"`
}
type MetaDataItem struct {
Name string `json:"name,optional"`
Description string `json:"description,optional"`
Type map[string]interface{} `json:"type,optional"`
}
type ApiItem struct {
Method string
Path string
//Router string
HttpMethod string
}
const gatewayTemplate =`
package gateway
const (
{{range .Routers}}
{{.Method}} = "{{.Method}}"{{end}}
)
var DefaultService *HttpDefaultServiceGateway
func init() {
DefaultService = &HttpDefaultServiceGateway{gs.NewManagerService("127.0.0.1", DefaultRouters())}
DefaultService.WithDebugModel(true)
}
type HttpDefaultServiceGateway struct {
*gs.GatewayService
}
func DefaultRouters() []gs.Router {
routers := []gs.Router{
{{range .Routers}}
{ {{.Method}}, "{{.Path}}", "{{.HttpMethod}}"},{{end}}
}
return routers
}
`
\ No newline at end of file
... ...