From a70a7748fe7dc46bdfcc713f215ced384fae1398 Mon Sep 17 00:00:00 2001 From: ymnuk Date: Sun, 5 Nov 2023 13:03:06 +0300 Subject: [PATCH 1/7] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BD=D0=BE=D0=B2=D1=8B=D1=85=20=D0=BF?= =?UTF-8?q?=D0=B0=D1=80=D0=B0=D0=BC=D0=B5=D1=82=D1=80=D0=BE=D0=B2=20=D0=B7?= =?UTF-8?q?=D0=B0=D0=BF=D1=83=D1=81=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/config.go | 7 +++++++ lib/templ/tmpl/docs/index.md.tmpl | 1 + 2 files changed, 8 insertions(+) create mode 100644 lib/templ/tmpl/docs/index.md.tmpl diff --git a/lib/config.go b/lib/config.go index 5f3a48e..676188d 100644 --- a/lib/config.go +++ b/lib/config.go @@ -16,6 +16,13 @@ var AppConfig struct { Filename string `arg:"-m,--metafile" help:"Файл с метоописанием в формате YAML или JSON"` // Файл с метоописанием в формате YAML или JSON OutdirBackend string `arg:"-b,--outdir-backend" help:"Директория для сохранения кода сервера"` // Директория для сохранения кода сервера OutdirFrontend string `arg:"-f,--outdir-frontend" help:"Директория для сохранения кода клиента"` // Директория для сохранения кода клиента + OutdirDoc string `arg:"-d,--outdir-doc" help:"Директория для сохранения сгенерированной документации по проекта"` + IsMarkdown bool `arg:"--format-markdown" help:"Выходная документация в формате Markdown"` + IsHtml bool `arg:"--format-html" help:"Выходная документация в формате HTML"` + IsGraphviz bool `arg:"--graphviz" help:"Генерировать графики в формате GraphViz (должен быть установлен локально)."` + IsMermaid bool `arg:"--mermaid" help:"Генерировать графики в формате Mermaid"` + MermaidAddr string `arg:"--mermaid-addr" default:"http://localhost" help:"Адрес сервера Mermaid. Если не указан и указан выходной формат Markdown, то просто встраивается в файл без предварительной генерации."` + IsSingleDoc bool `arg:"--single-doc" help:"Генерировать документацию в одном файле без разделения"` } var Project *structs.Project diff --git a/lib/templ/tmpl/docs/index.md.tmpl b/lib/templ/tmpl/docs/index.md.tmpl new file mode 100644 index 0000000..7581886 --- /dev/null +++ b/lib/templ/tmpl/docs/index.md.tmpl @@ -0,0 +1 @@ +# Help \ No newline at end of file From c5572183fe9889e3204fb6df15c2fca058908bd6 Mon Sep 17 00:00:00 2001 From: Ymnuk Date: Tue, 7 Nov 2023 16:35:47 +0300 Subject: [PATCH 2/7] =?UTF-8?q?=D0=93=D0=B5=D0=BD=D0=B5=D1=80=D0=B8=D1=80?= =?UTF-8?q?=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20=D0=BF=D0=BE=D0=BB=D0=BD?= =?UTF-8?q?=D0=BE=D0=B9=20=D1=81=D1=85=D0=B5=D0=BC=D1=8B=20=D0=91=D0=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/launch.json | 13 ++ go.mod | 6 +- go.sum | 4 + lib/config.go | 4 +- lib/documentation.go | 58 +++++++ lib/generate.go | 8 + lib/kroki-client.go | 20 +++ lib/templ/template.go | 144 +++++++++++++----- lib/templ/tmpl/docs/db/entity.tmpl | 10 ++ lib/templ/tmpl/docs/db/full-schema.tmpl | 17 +++ lib/templ/tmpl/docs/db/role.tmpl | 5 + .../tmpl/docs/db/user-role-relations.tmpl | 2 + lib/templ/tmpl/docs/db/user-role.tmpl | 5 + lib/templ/tmpl/docs/db/user.tmpl | 11 ++ 14 files changed, 263 insertions(+), 44 deletions(-) create mode 100644 lib/documentation.go create mode 100644 lib/kroki-client.go create mode 100644 lib/templ/tmpl/docs/db/entity.tmpl create mode 100644 lib/templ/tmpl/docs/db/full-schema.tmpl create mode 100644 lib/templ/tmpl/docs/db/role.tmpl create mode 100644 lib/templ/tmpl/docs/db/user-role-relations.tmpl create mode 100644 lib/templ/tmpl/docs/db/user-role.tmpl create mode 100644 lib/templ/tmpl/docs/db/user.tmpl diff --git a/.vscode/launch.json b/.vscode/launch.json index 6f0f551..10406c8 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -51,6 +51,19 @@ "--outdir-frontend", "../zmap/frontend" ] + }, + { + "name": "zmap docs", + "type": "go", + "request": "launch", + "mode": "auto", + "program": "${workspaceFolder}/main.go", + "args": [ + "--metafile", + "/home/ymnuk/projects/zmap/zmap.yml", + "--outdir-doc", + "../zmap/docs" + ] } ] } \ No newline at end of file diff --git a/go.mod b/go.mod index af6d3c8..680488d 100644 --- a/go.mod +++ b/go.mod @@ -9,4 +9,8 @@ require ( gopkg.in/yaml.v3 v3.0.1 ) -require github.com/alexflint/go-scalar v1.2.0 // indirect +require ( + github.com/alexflint/go-scalar v1.2.0 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/yuzutech/kroki-go v0.8.1 // indirect +) diff --git a/go.sum b/go.sum index a1d963c..3f088d0 100644 --- a/go.sum +++ b/go.sum @@ -8,12 +8,16 @@ github.com/creasty/defaults v1.7.0 h1:eNdqZvc5B509z18lD8yc212CAqJNvfT1Jq6L8WowdB github.com/creasty/defaults v1.7.0/go.mod h1:iGzKe6pbEHnpMPtfDXZEr0NVxWnPTjb1bbDy08fPzYM= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/yuzutech/kroki-go v0.8.1 h1:p6doXpgWUXgLrVWt6MA1/ODH/oMBsnNGC3f7wGUewbM= +github.com/yuzutech/kroki-go v0.8.1/go.mod h1:JyGBdT3Od/PHEDf95GirXwhf1PM31k+tevrXGVjqNpg= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/lib/config.go b/lib/config.go index 676188d..9ec6d76 100644 --- a/lib/config.go +++ b/lib/config.go @@ -19,9 +19,7 @@ var AppConfig struct { OutdirDoc string `arg:"-d,--outdir-doc" help:"Директория для сохранения сгенерированной документации по проекта"` IsMarkdown bool `arg:"--format-markdown" help:"Выходная документация в формате Markdown"` IsHtml bool `arg:"--format-html" help:"Выходная документация в формате HTML"` - IsGraphviz bool `arg:"--graphviz" help:"Генерировать графики в формате GraphViz (должен быть установлен локально)."` - IsMermaid bool `arg:"--mermaid" help:"Генерировать графики в формате Mermaid"` - MermaidAddr string `arg:"--mermaid-addr" default:"http://localhost" help:"Адрес сервера Mermaid. Если не указан и указан выходной формат Markdown, то просто встраивается в файл без предварительной генерации."` + KrokiAddr string `arg:"--kroki-addr" default:"https://kroki.io" help:"Адрес сервера Kroki."` IsSingleDoc bool `arg:"--single-doc" help:"Генерировать документацию в одном файле без разделения"` } diff --git a/lib/documentation.go b/lib/documentation.go new file mode 100644 index 0000000..feec0cf --- /dev/null +++ b/lib/documentation.go @@ -0,0 +1,58 @@ +package lib + +import ( + "git.ymnuktech.ru/ymnuk/yt-gen-app/lib/templ" + "git.ymnuktech.ru/ymnuk/yt-gen-app/structs" + "github.com/yuzutech/kroki-go" +) + +func Documentation() { + if !AppConfig.IsHtml { + AppConfig.IsMarkdown = true + } + // Генерация общей схемы БД + fullDocDBGen() + // Генерация каждой таблицы по отдельности с прилегающими ближайшими таблицами + /*for i := range Project.DB.Tables { + docDBGen(Project.DB.Tables[i]) + }*/ + // TODO +} + +// Генерирования списка таблиц +/*func listTablesDocGen() string { + // TODO +} + +// Генерирование полей таблицы +func tableDocGen(table structs.Table) string { + // TODO +}*/ + +// Генерация общей схемы БД +func fullDocDBGen() { + // TODO + if tmpl, err := templ.ReadTmplFile("tmpl/docs/db/full-schema.tmpl"); err != nil { + panic(err) + } else { + if buff, err := templ.ExecuteTmplFile(tmpl, Project.DB); err != nil { + panic(err) + } else { + //fmt.Println(string(buff)) + templ.WriteFile(AppConfig.OutdirDoc+"/test.txt", buff) + client := NewKrokiClient() + if result, err := client.FromString(string(buff), "dbml", kroki.SVG); err != nil { + panic(err) + } else { + //fmt.Println(result) + templ.WriteFile(AppConfig.OutdirDoc+"/test.svg", []byte(result)) + } + + } + } +} + +// Генерация отдельной таблицы с прилегающими ближайшими таблицами +func docDBGen(table structs.Table) { + // TODO +} diff --git a/lib/generate.go b/lib/generate.go index 910a0b6..14303b0 100644 --- a/lib/generate.go +++ b/lib/generate.go @@ -21,4 +21,12 @@ func Generate() { } Frontend() } + + if AppConfig.OutdirDoc != "" { + // Генерация документации + if err := os.MkdirAll(AppConfig.OutdirDoc, 0755); err != nil { + log.Fatal(err) + } + Documentation() + } } diff --git a/lib/kroki-client.go b/lib/kroki-client.go new file mode 100644 index 0000000..949051b --- /dev/null +++ b/lib/kroki-client.go @@ -0,0 +1,20 @@ +package lib + +import ( + "time" + + "github.com/yuzutech/kroki-go" +) + +var krokiClient *kroki.Client + +func NewKrokiClient() *kroki.Client { + if krokiClient == nil { + tmp := kroki.New(kroki.Configuration{ + URL: AppConfig.KrokiAddr, + Timeout: time.Second * 60, + }) + krokiClient = &tmp + } + return krokiClient +} diff --git a/lib/templ/template.go b/lib/templ/template.go index e62ca65..1b42df0 100644 --- a/lib/templ/template.go +++ b/lib/templ/template.go @@ -21,14 +21,20 @@ import ( var Content embed.FS var funcMap = template.FuncMap{ + + //"includeTemplPart": IncludeTemplPart, + "fieldName": FieldName, "fieldChildName": FieldChildName, "fieldNamePrepare": FieldNamePrepare, "fieldNameLowerPrepare": FieldNameLowerPrepare, "fieldJsonNameStr": FieldJsonNameStr, "fieldType": FieldType, + "fieldTypeStr": FieldTypeStr, "fieldStringToType": FieldStringToType, //"fieldDbTableType": FieldDbTableType, + "fieldTypeDB": FieldTypeDB, + "fieldTypeDBStr": FieldTypeDBStr, "fieldTypeParentTable": FieldTypeParentTable, "hasFieldType": HasFieldType, "fieldDescript": FieldDescript, @@ -71,6 +77,22 @@ var funcMap = template.FuncMap{ "fieldInTableByName": FieldInTableByName, } +func IncludeTemplPart(templName string, data interface{}) string { + var err error + var tmpl *template.Template + if tmpl, err = ReadTmplFile(templName); err != nil { + panic(err) + } + var out []byte + if out, err = ExecuteTmplFile(tmpl, data); err != nil { + panic(err) + } + /*arr:=strings.Split(string(out)) + var newArr []string + for*/ + return string(out) +} + func IsMethod(arr map[string][]string, method string) bool { if arr == nil { return false @@ -153,15 +175,12 @@ func FieldTypeParentTable(field *structs.Field) string { return FieldType(&structs.Field{Type: field.TypeParentTable}) } -func FieldType(field *structs.Field) string { - if field == nil { - log.Fatal("field is empty") +func FieldTypeStr(value string) string { + value = strings.ToLower(strings.Trim(value, " ")) + if value == "" { + return value } - field.Type = strings.ToLower(strings.Trim(field.Type, " ")) - if field.Type == "" { - field.Type = "text" - } - switch field.Type { + switch value { case "text": return "*string" case "string": @@ -186,11 +205,24 @@ func FieldType(field *structs.Field) string { return "[]byte" default: fkTmp := &structs.Field{ - Name: field.Type, + Name: value, } return FieldName(fkTmp) //log.Fatalf("Unknow format %s", field.Type) } +} + +func FieldType(field *structs.Field) string { + if field == nil { + log.Fatal("field is empty") + } + field.Type = strings.ToLower(strings.Trim(field.Type, " ")) + value := FieldTypeStr(field.Type) + if value == "" { + field.Type = "text" + value = "text" + } + return value //return "" } @@ -212,15 +244,14 @@ func HasFieldType(fields []structs.Field, typeName string) (has bool) { return false } -func FieldTypeDB(field *structs.Field) string { - field.Type = strings.ToLower(strings.Trim(field.Type, " ")) - switch field.Type { +func FieldTypeDBStr(value string, length *int) string { + switch value { case "text": return "TEXT" case "string": tmp := "VARCHAR" - if field.Length != nil && *field.Length == 0 { - tmp += fmt.Sprintf("(%d)", *field.Length) + if length != nil && *length == 0 { + tmp += fmt.Sprintf("(%d)", *length) } else { tmp += "(255)" } @@ -243,11 +274,16 @@ func FieldTypeDB(field *structs.Field) string { case "bool": return "int" default: - log.Fatalf("Unknow format %s", field.Type) + log.Fatalf("Unknow format %s", value) } return "" } +func FieldTypeDB(field *structs.Field) string { + field.Type = strings.ToLower(strings.Trim(field.Type, " ")) + return FieldTypeDBStr(field.Type, field.Length) +} + // Генерирование описания таблиц в БД func FieldDescript(field *structs.Field, fieldId bool) (str string) { str = "`" @@ -317,7 +353,6 @@ func ConfigParamTag(field *structs.ParamConfig) string { tag += fmt.Sprintf(" help:\"%s\"", field.Help) } tag += "`" - // TODO return tag } @@ -333,6 +368,46 @@ func WriteTmplFile(filename string, outname string) error { return nil } +// Чтение шаблона и его подготовка +func ReadTmplFile(filename string) (tmpl *template.Template, err error) { + var ( + buff []byte + ) + if buff, err = Content.ReadFile(filename); err != nil { + return + } + var ( + tmp string + //tmpl *template.Template + ) + if tmp, err = RandomHex(4); err != nil { + return + } + if _, ok := funcMap["includeTemplPart"]; !ok { + funcMap["includeTemplPart"] = IncludeTemplPart + } + tmpl, err = template.New(tmp).Funcs(funcMap).Parse(string(buff)) + return +} + +// Запись файла на диск +func WriteFile(outname string, data []byte) (err error) { + err = os.WriteFile(outname, data, 0755) + return +} + +// Выполнить шаблон +func ExecuteTmplFile(tmpl *template.Template, data interface{}) (out []byte, err error) { + var b bytes.Buffer + w := bufio.NewWriter(&b) + if err = tmpl.Execute(w, data); err != nil { + return + } + w.Flush() + out = b.Bytes() + return +} + // Использование шаблона func PrepareTmplFile(filename string, data interface{}, outname string) (err error) { dir := filepath.Dir(outname) @@ -341,36 +416,25 @@ func PrepareTmplFile(filename string, data interface{}, outname string) (err err } fmt.Printf("Generate: %s\n", outname) - var ( - buff []byte - ) - if buff, err = Content.ReadFile(filename); err != nil { - return err - } - var ( - tmp string - tmpl *template.Template - ) - if tmp, err = RandomHex(4); err != nil { - return err - } - if tmpl, err = template.New(tmp).Funcs(funcMap).Parse(string(buff)); err != nil { + /*var b bytes.Buffer + w := bufio.NewWriter(&b)*/ + var tmpl *template.Template + if tmpl, err = ReadTmplFile(filename); err != nil { + return + } + /*if err = tmpl.Execute(w, data); err != nil { return err } - var b bytes.Buffer - w := bufio.NewWriter(&b) - - if err = tmpl.Execute(w, data); err != nil { - return err + w.Flush()*/ + var out []byte + if out, err = ExecuteTmplFile(tmpl, data); err != nil { + return } - w.Flush() - if err = os.WriteFile(outname, b.Bytes(), 0755); err != nil { - return err - } - return + return WriteFile(outname, out) } +// Подготовка файла, если его нет на диске func PrepareTmplIsNotExists(filename string, data interface{}, outname string) (err error) { if err = MkdirIsNotExists(filepath.Dir(outname)); err != nil { diff --git a/lib/templ/tmpl/docs/db/entity.tmpl b/lib/templ/tmpl/docs/db/entity.tmpl new file mode 100644 index 0000000..16a9523 --- /dev/null +++ b/lib/templ/tmpl/docs/db/entity.tmpl @@ -0,0 +1,10 @@ +{{ $varNameField := fieldNamePrepare .Name }} +Table {{ fieldNameLowerPrepare $varNameField }} { + id {{ fieldTypeDBStr .Pk nil }} [primary key] + {{ range $index, $field := .Fields }} + {{ fieldNameLowerPrepare $field.Name }} {{ fieldTypeDB $field }} + {{ end }} + {{ range $index, $field := .FkFields }} + {{ fieldNameLowerPrepare $field.Name }}_id {{ fieldNameLowerPrepare $field.TypeParentTable }} + {{ end }} +} \ No newline at end of file diff --git a/lib/templ/tmpl/docs/db/full-schema.tmpl b/lib/templ/tmpl/docs/db/full-schema.tmpl new file mode 100644 index 0000000..83ce34b --- /dev/null +++ b/lib/templ/tmpl/docs/db/full-schema.tmpl @@ -0,0 +1,17 @@ +{{ includeTemplPart "tmpl/docs/db/user.tmpl" nil }} +{{ includeTemplPart "tmpl/docs/db/role.tmpl" nil }} +{{ includeTemplPart "tmpl/docs/db/user-role.tmpl" nil }} +{{ range $index, $table := .Tables }} +{{ includeTemplPart "tmpl/docs/db/entity.tmpl" $table }} +{{ end }} + +{{ range $indexi, $table := .Tables }} +{{ $varNameTable := fieldNamePrepare $table.Name }} +{{range $indexj, $field := $table.FkFields }} +{{ $fieldTypeParentTable := "" }} +{{ if eq $field.Name "Parent" }}{{ $fieldTypeParentTable = fieldNamePrepare $.Name }}{{ else }}{{ $fieldTypeParentTable = fieldType $field }}{{ end }} +Ref: {{ fieldNameLowerPrepare $varNameTable }}.{{ fieldNameLowerPrepare $field.Name }}_id > {{ fieldNameLowerPrepare $fieldTypeParentTable }}.id +{{ end }} +{{ end }} + +{{ includeTemplPart "tmpl/docs/db/user-role-relations.tmpl" nil }} \ No newline at end of file diff --git a/lib/templ/tmpl/docs/db/role.tmpl b/lib/templ/tmpl/docs/db/role.tmpl new file mode 100644 index 0000000..4029575 --- /dev/null +++ b/lib/templ/tmpl/docs/db/role.tmpl @@ -0,0 +1,5 @@ +Table role { + id UUID [primary key] + name VARCHAR(20) + description VARCHAR(20) +} \ No newline at end of file diff --git a/lib/templ/tmpl/docs/db/user-role-relations.tmpl b/lib/templ/tmpl/docs/db/user-role-relations.tmpl new file mode 100644 index 0000000..baf057b --- /dev/null +++ b/lib/templ/tmpl/docs/db/user-role-relations.tmpl @@ -0,0 +1,2 @@ +Ref: user_role.user_id > user.id +Ref: user_role.role_id > role.id \ No newline at end of file diff --git a/lib/templ/tmpl/docs/db/user-role.tmpl b/lib/templ/tmpl/docs/db/user-role.tmpl new file mode 100644 index 0000000..ba50e7b --- /dev/null +++ b/lib/templ/tmpl/docs/db/user-role.tmpl @@ -0,0 +1,5 @@ +Table user_role { + id UUID + user_id UUID + role_id UUID +} \ No newline at end of file diff --git a/lib/templ/tmpl/docs/db/user.tmpl b/lib/templ/tmpl/docs/db/user.tmpl new file mode 100644 index 0000000..d0d87d4 --- /dev/null +++ b/lib/templ/tmpl/docs/db/user.tmpl @@ -0,0 +1,11 @@ +Table user { + id UUID [primary key] + login VARCHAR + surname VARCHAR(100) + name VARCHAR(100) + farname VARCHAR(100) + email VARCHAR(200) + password VARCGAR + ldap BOOLEAN + attempt INT +} \ No newline at end of file From d1bfaccc64baf14651025efa5b5406f16e5b359c Mon Sep 17 00:00:00 2001 From: ymnuk Date: Tue, 7 Nov 2023 19:59:05 +0300 Subject: [PATCH 3/7] =?UTF-8?q?=D0=9E=D0=BF=D0=B8=D1=81=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=20=D1=82=D0=B0=D0=B1=D0=BB=D0=B8=D1=86=20=D0=B1=D0=B5?= =?UTF-8?q?=D0=B7=20=D1=81=D1=81=D1=8B=D0=BB=D0=BE=D0=BA=20=D0=B2=20=D0=B5?= =?UTF-8?q?=D0=B4=D0=B8=D0=BD=D0=BE=D0=BC=20=D1=84=D0=B0=D0=B9=D0=BB=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/launch.json | 5 ++- go.mod | 3 +- go.sum | 2 ++ lib/documentation.go | 33 +++++++++++++++++-- lib/md2html.go | 21 ++++++++++++ lib/prepare/prepare-db.go | 3 ++ .../tmpl/docs/db/entity-table-no-href.tmpl | 14 ++++++++ lib/templ/tmpl/docs/db/table-list-single.tmpl | 4 +++ lib/templ/tmpl/docs/db/table-list.tmpl | 0 .../tmpl/docs/{index.md.tmpl => index.tmpl} | 0 lib/templ/tmpl/docs/single-index.tmpl | 12 +++++++ lib/templ/tmpl/docs/styles.tmpl | 6 ++++ 12 files changed, 99 insertions(+), 4 deletions(-) create mode 100644 lib/md2html.go create mode 100644 lib/templ/tmpl/docs/db/entity-table-no-href.tmpl create mode 100644 lib/templ/tmpl/docs/db/table-list-single.tmpl create mode 100644 lib/templ/tmpl/docs/db/table-list.tmpl rename lib/templ/tmpl/docs/{index.md.tmpl => index.tmpl} (100%) create mode 100644 lib/templ/tmpl/docs/single-index.tmpl create mode 100644 lib/templ/tmpl/docs/styles.tmpl diff --git a/.vscode/launch.json b/.vscode/launch.json index 10406c8..5c53dcf 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -62,7 +62,10 @@ "--metafile", "/home/ymnuk/projects/zmap/zmap.yml", "--outdir-doc", - "../zmap/docs" + "../zmap/docs", + "--single-doc", + "--format-markdown", + "--format-html" ] } ] diff --git a/go.mod b/go.mod index 680488d..200840c 100644 --- a/go.mod +++ b/go.mod @@ -5,12 +5,13 @@ go 1.21 require ( github.com/alexflint/go-arg v1.4.3 github.com/creasty/defaults v1.7.0 + github.com/gomarkdown/markdown v0.0.0-20230922112808-5421fefb8386 github.com/satori/go.uuid v1.2.0 + github.com/yuzutech/kroki-go v0.8.1 gopkg.in/yaml.v3 v3.0.1 ) require ( github.com/alexflint/go-scalar v1.2.0 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/yuzutech/kroki-go v0.8.1 // indirect ) diff --git a/go.sum b/go.sum index 3f088d0..d673e8e 100644 --- a/go.sum +++ b/go.sum @@ -8,6 +8,8 @@ github.com/creasty/defaults v1.7.0 h1:eNdqZvc5B509z18lD8yc212CAqJNvfT1Jq6L8WowdB github.com/creasty/defaults v1.7.0/go.mod h1:iGzKe6pbEHnpMPtfDXZEr0NVxWnPTjb1bbDy08fPzYM= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/gomarkdown/markdown v0.0.0-20230922112808-5421fefb8386 h1:EcQR3gusLHN46TAD+G+EbaaqJArt5vHhNpXAa12PQf4= +github.com/gomarkdown/markdown v0.0.0-20230922112808-5421fefb8386/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= diff --git a/lib/documentation.go b/lib/documentation.go index feec0cf..db3a98f 100644 --- a/lib/documentation.go +++ b/lib/documentation.go @@ -1,6 +1,8 @@ package lib import ( + "text/template" + "git.ymnuktech.ru/ymnuk/yt-gen-app/lib/templ" "git.ymnuktech.ru/ymnuk/yt-gen-app/structs" "github.com/yuzutech/kroki-go" @@ -12,6 +14,33 @@ func Documentation() { } // Генерация общей схемы БД fullDocDBGen() + var err error + var tmpl *template.Template + var out []byte + if AppConfig.IsSingleDoc { + if tmpl, err = templ.ReadTmplFile("tmpl/docs/single-index.tmpl"); err != nil { + panic(err) + } + if out, err = templ.ExecuteTmplFile(tmpl, Project); err != nil { + panic(err) + } + if AppConfig.IsMarkdown { + if err = templ.WriteFile(AppConfig.OutdirDoc+"/index.md", out); err != nil { + panic(err) + } + } + if AppConfig.IsHtml { + var buff []byte + if buff, err = templ.Content.ReadFile("tmpl/docs/styles.tmpl"); err != nil { + panic(err) + } + //{{ includeTemplPart "tmpl/docs/styles.tmpl" nil }} + out = append(buff, out...) + if err = templ.WriteFile(AppConfig.OutdirDoc+"/index.html", mdToHTML(out)); err != nil { + panic(err) + } + } + } // Генерация каждой таблицы по отдельности с прилегающими ближайшими таблицами /*for i := range Project.DB.Tables { docDBGen(Project.DB.Tables[i]) @@ -39,13 +68,13 @@ func fullDocDBGen() { panic(err) } else { //fmt.Println(string(buff)) - templ.WriteFile(AppConfig.OutdirDoc+"/test.txt", buff) + //templ.WriteFile(AppConfig.OutdirDoc+"/test.txt", buff) client := NewKrokiClient() if result, err := client.FromString(string(buff), "dbml", kroki.SVG); err != nil { panic(err) } else { //fmt.Println(result) - templ.WriteFile(AppConfig.OutdirDoc+"/test.svg", []byte(result)) + templ.WriteFile(AppConfig.OutdirDoc+"/full-schemadb.svg", []byte(result)) } } diff --git a/lib/md2html.go b/lib/md2html.go new file mode 100644 index 0000000..6c4d154 --- /dev/null +++ b/lib/md2html.go @@ -0,0 +1,21 @@ +package lib + +import ( + "github.com/gomarkdown/markdown" + "github.com/gomarkdown/markdown/html" + "github.com/gomarkdown/markdown/parser" +) + +func mdToHTML(md []byte) []byte { + // create markdown parser with extensions + extensions := parser.CommonExtensions | parser.AutoHeadingIDs | parser.NoEmptyLineBeforeBlock + p := parser.NewWithExtensions(extensions) + doc := p.Parse(md) + + // create HTML renderer with extensions + htmlFlags := html.CommonFlags | html.HrefTargetBlank + opts := html.RendererOptions{Flags: htmlFlags} + renderer := html.NewRenderer(opts) + + return markdown.Render(doc, renderer) +} diff --git a/lib/prepare/prepare-db.go b/lib/prepare/prepare-db.go index 229b4d2..ce4ac55 100644 --- a/lib/prepare/prepare-db.go +++ b/lib/prepare/prepare-db.go @@ -84,6 +84,9 @@ func prepareDB(project *structs.Project) *structs.Project { TypeParentTable: project.DB.Tables[i].FKs[j].Type, //project.DB.Tables[i].Pk, Description: fmt.Sprintf("Foreign key for \\\"%s\\\" table", project.DB.Tables[i].FKs[j].TableName), } + if project.DB.Tables[i].FKs[j].Description != "" { + fkTmp.Description = project.DB.Tables[i].FKs[j].Description + } if strings.ToLower(project.DB.Tables[i].FKs[j].TableName) == "user" { fkTmp.TypeParentTable = "uuid" } diff --git a/lib/templ/tmpl/docs/db/entity-table-no-href.tmpl b/lib/templ/tmpl/docs/db/entity-table-no-href.tmpl new file mode 100644 index 0000000..75b5c21 --- /dev/null +++ b/lib/templ/tmpl/docs/db/entity-table-no-href.tmpl @@ -0,0 +1,14 @@ +### Поля + +|Поле|Тип|Описание| +|:---|:--|:-------| +|id|{{ fieldTypeDBStr .Pk nil }}|Первичный ключ| +{{ range $index, $field := .Fields }}|{{ fieldNameLowerPrepare $field.Name }}|{{ fieldTypeDB $field }}|{{ $field.Description }}| +{{ end }} + +### Внешние ключи + +|Ключ|Тип|Талица|Описание| +|:---|:--|:-----|:-------| +{{ range $index, $field := .FkFields }}|{{ fieldNameLowerPrepare $field.Name }}_id|{{ fieldNameLowerPrepare $field.TypeParentTable }}|{{ $tableNameVar := "" }}{{ if eq $field.Name "Parent" }}{{ $tableNameVar = fieldNamePrepare $.Name }}{{ else }}{{ $tableNameVar = fieldType $field }}{{ end }}{{ fieldNameLowerPrepare $tableNameVar }}|{{ $field.Description }}| +{{ end }} \ No newline at end of file diff --git a/lib/templ/tmpl/docs/db/table-list-single.tmpl b/lib/templ/tmpl/docs/db/table-list-single.tmpl new file mode 100644 index 0000000..5f50192 --- /dev/null +++ b/lib/templ/tmpl/docs/db/table-list-single.tmpl @@ -0,0 +1,4 @@ +|Название|Описание| +|:-------|:-------| +{{ range $index, $table := .Tables }}|{{ $varNameField := fieldNamePrepare $table.Name }}{{ fieldNameLowerPrepare $varNameField }}|{{ $table.Description }}| +{{end}} \ No newline at end of file diff --git a/lib/templ/tmpl/docs/db/table-list.tmpl b/lib/templ/tmpl/docs/db/table-list.tmpl new file mode 100644 index 0000000..e69de29 diff --git a/lib/templ/tmpl/docs/index.md.tmpl b/lib/templ/tmpl/docs/index.tmpl similarity index 100% rename from lib/templ/tmpl/docs/index.md.tmpl rename to lib/templ/tmpl/docs/index.tmpl diff --git a/lib/templ/tmpl/docs/single-index.tmpl b/lib/templ/tmpl/docs/single-index.tmpl new file mode 100644 index 0000000..a19437a --- /dev/null +++ b/lib/templ/tmpl/docs/single-index.tmpl @@ -0,0 +1,12 @@ +# База данных + +{{ includeTemplPart "tmpl/docs/db/table-list-single.tmpl" .DB }} + +![Полная структура БД](full-schemadb.svg "Полная структура БД") + +{{ range $index, $table := .DB.Tables }} +{{ $varNameField := fieldNamePrepare .Name }} +## Таблица {{ fieldNameLowerPrepare $varNameField }} + +{{ includeTemplPart "tmpl/docs/db/entity-table-no-href.tmpl" $table }} +{{ end }} diff --git a/lib/templ/tmpl/docs/styles.tmpl b/lib/templ/tmpl/docs/styles.tmpl new file mode 100644 index 0000000..788cd87 --- /dev/null +++ b/lib/templ/tmpl/docs/styles.tmpl @@ -0,0 +1,6 @@ + \ No newline at end of file From 63d2ddcfa7d2eb8a2a240b01e004f4573884e32e Mon Sep 17 00:00:00 2001 From: ymnuk Date: Tue, 7 Nov 2023 22:50:48 +0300 Subject: [PATCH 4/7] =?UTF-8?q?=D0=9F=D0=BE=D0=B4=D0=B3=D0=BE=D1=82.=20?= =?UTF-8?q?=D1=88=D0=B0=D0=B1=D0=BB=D0=BE=D0=BD=D0=B0=20=D0=B4=D0=BB=D1=8F?= =?UTF-8?q?=20=D1=84=D0=BE=D1=80=D0=BC=D0=B8=D1=80.=20=D0=B8=D0=BD=D0=B4.?= =?UTF-8?q?=20=D1=82=D0=B0=D0=B1=D0=BB=D0=B8=D1=86=20=D0=B8=20=D1=81=D0=B2?= =?UTF-8?q?=D1=8F=D0=B7=D0=B5=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/documentation.go | 74 +++++++++++++++++++- lib/templ/tmpl/docs/db/adjacents-tables.tmpl | 19 +++++ lib/templ/tmpl/docs/single-index.tmpl | 1 + structs/rest-struct.go | 5 ++ 4 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 lib/templ/tmpl/docs/db/adjacents-tables.tmpl diff --git a/lib/documentation.go b/lib/documentation.go index db3a98f..df0a2a2 100644 --- a/lib/documentation.go +++ b/lib/documentation.go @@ -1,10 +1,12 @@ package lib import ( + "log" "text/template" "git.ymnuktech.ru/ymnuk/yt-gen-app/lib/templ" "git.ymnuktech.ru/ymnuk/yt-gen-app/structs" + uuid "github.com/satori/go.uuid" "github.com/yuzutech/kroki-go" ) @@ -14,6 +16,10 @@ func Documentation() { } // Генерация общей схемы БД fullDocDBGen() + // Генерация схем для каждой таблицы + for _, table := range Project.DB.Tables { + docDBGen(&table) + } var err error var tmpl *template.Template var out []byte @@ -82,6 +88,72 @@ func fullDocDBGen() { } // Генерация отдельной таблицы с прилегающими ближайшими таблицами -func docDBGen(table structs.Table) { +func docDBGen(table *structs.Table) { + restStruct := structs.RestStruct{ + Table: table, + Children: GetChildrenTables(table), + Parents: GetParentsTables(table), + } + if tmpl, err := templ.ReadTmplFile("tmpl/docs/db/adjacents-tables.tmpl"); err != nil { + panic(err) + } else { + if buff, err := templ.ExecuteTmplFile(tmpl, restStruct); err != nil { + panic(err) + } else { + //fmt.Println(string(buff)) + //templ.WriteFile(AppConfig.OutdirDoc+"/test.txt", buff) + client := NewKrokiClient() + if result, err := client.FromString(string(buff), "dbml", kroki.SVG); err != nil { + panic(err) + } else { + //fmt.Println(result) + templ.WriteFile(AppConfig.OutdirDoc+"/"+templ.FieldNameLowerPrepare(restStruct.Table.Name)+".svg", []byte(result)) + } + + } + } // TODO } + +func GetParentsTables(table *structs.Table) (tables []structs.Table) { + for _, fk := range table.FKs { + for _, tbl := range Project.DB.Tables { + if fk.TableID == uuid.Nil { + // Это одна из трех таблиц: user, role, user_role + switch templ.FieldNameLowerPrepare(fk.TableName) { + case "user": + tables = append(tables, structs.Table{ + ID: uuid.Nil, + Name: "user", + Pk: "uuid", + }) + case "role": + tables = append(tables, structs.Table{ + ID: uuid.Nil, + Name: "role", + Pk: "uuid", + }) + default: + log.Fatalf("Not found standart table %s", templ.FieldNameLowerPrepare(fk.TableName)) + } + break + } + if fk.TableID == tbl.ID { + tables = append(tables, tbl) + break + } + } + } + return +} + +func GetChildrenTables(table *structs.Table) (tables []structs.Table) { + for _, tbl := range Project.DB.Tables { + for _, fk := range tbl.FKs { + if fk.TableID == table.ID { + tables = append(tables, tbl) + } + } + } + return +} diff --git a/lib/templ/tmpl/docs/db/adjacents-tables.tmpl b/lib/templ/tmpl/docs/db/adjacents-tables.tmpl new file mode 100644 index 0000000..d92258c --- /dev/null +++ b/lib/templ/tmpl/docs/db/adjacents-tables.tmpl @@ -0,0 +1,19 @@ +{{ includeTemplPart "tmpl/docs/db/entity.tmpl" .Table }} + +{{ range $indexi, $table := .Children }} +{{ includeTemplPart "tmpl/docs/db/entity.tmpl" $table }} +{{ end }} + +{{ range $indexi, $table := .Parents }} +{{ includeTemplPart "tmpl/docs/db/entity.tmpl" $table }} +{{ end }} + +// TODO +{{ range $indexi, $table := .Parents }} +{{ $varNameTable := fieldNamePrepare $table.Name }} +{{range $indexj, $field := $table.FkFields }} +{{ $fieldTypeParentTable := "" }} +{{ if eq $field.Name "Parent" }}{{ $fieldTypeParentTable = fieldNamePrepare $.Name }}{{ else }}{{ $fieldTypeParentTable = fieldType $field }}{{ end }} +Ref: {{ fieldNameLowerPrepare $varNameTable }}.{{ fieldNameLowerPrepare $field.Name }}_id > {{ fieldNameLowerPrepare $fieldTypeParentTable }}.id +{{ end }} +{{ end }} \ No newline at end of file diff --git a/lib/templ/tmpl/docs/single-index.tmpl b/lib/templ/tmpl/docs/single-index.tmpl index a19437a..21890be 100644 --- a/lib/templ/tmpl/docs/single-index.tmpl +++ b/lib/templ/tmpl/docs/single-index.tmpl @@ -1,3 +1,4 @@ + # База данных {{ includeTemplPart "tmpl/docs/db/table-list-single.tmpl" .DB }} diff --git a/structs/rest-struct.go b/structs/rest-struct.go index 7df8bcb..2c64c00 100644 --- a/structs/rest-struct.go +++ b/structs/rest-struct.go @@ -6,4 +6,9 @@ type RestStruct struct { Project *Project Rest *Rest PathParams []Field + + // Поля для формирования документации к БД + Table *Table + Children []Table + Parents []Table } From abe127ff2189ae0b6377777861337d0465958edf Mon Sep 17 00:00:00 2001 From: Ymnuk Date: Wed, 8 Nov 2023 12:50:39 +0300 Subject: [PATCH 5/7] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=88=D0=B0=D0=B1=D0=BB=D0=BE=D0=BD?= =?UTF-8?q?=D0=B0=20=D1=81=D1=82=D0=B0=D1=82=D0=B8=D1=87=D0=BD=D1=8B=D1=85?= =?UTF-8?q?=20=D1=84=D0=B0=D0=B9=D0=BB=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/documentation.go | 3 ++ lib/templ/tmpl/backend/route/route.tmpl | 34 ++++++++++++++----- lib/templ/tmpl/docs/db/adjacents-tables.tmpl | 20 ++++++++--- .../tmpl/docs/db/entity-table-no-href.tmpl | 2 ++ lib/templ/tmpl/docs/db/full-schema.tmpl | 2 +- 5 files changed, 48 insertions(+), 13 deletions(-) diff --git a/lib/documentation.go b/lib/documentation.go index df0a2a2..61bf8a7 100644 --- a/lib/documentation.go +++ b/lib/documentation.go @@ -1,6 +1,7 @@ package lib import ( + "fmt" "log" "text/template" @@ -98,12 +99,14 @@ func docDBGen(table *structs.Table) { panic(err) } else { if buff, err := templ.ExecuteTmplFile(tmpl, restStruct); err != nil { + fmt.Println(string(buff)) panic(err) } else { //fmt.Println(string(buff)) //templ.WriteFile(AppConfig.OutdirDoc+"/test.txt", buff) client := NewKrokiClient() if result, err := client.FromString(string(buff), "dbml", kroki.SVG); err != nil { + fmt.Println(string(buff)) panic(err) } else { //fmt.Println(result) diff --git a/lib/templ/tmpl/backend/route/route.tmpl b/lib/templ/tmpl/backend/route/route.tmpl index c8d6899..36b456b 100644 --- a/lib/templ/tmpl/backend/route/route.tmpl +++ b/lib/templ/tmpl/backend/route/route.tmpl @@ -1,20 +1,22 @@ package route import ( - "{{ .Name }}/route/api" "embed" + "mime" "net/http" + "path/filepath" + "strings" + "zmap/route/api" "github.com/labstack/echo/v4" - "github.com/labstack/echo/v4/middleware" - _ "{{ .Name }}/docs" + _ "zmap/docs" echoSwagger "github.com/swaggo/echo-swagger" ) //go:embed static -var content embed.FS +var Content embed.FS func Init(e *echo.Echo) { @@ -22,9 +24,25 @@ func Init(e *echo.Echo) { api.Init(e.Group("/api")) - var contentHandler = echo.WrapHandler(http.FileServer(http.FS(content))) - var contentRewrite = middleware.Rewrite(map[string]string{"/*": "/static/$1"}) //e.GET("/", main) - e.GET("/*", contentHandler, contentRewrite) - e.GET("*", contentHandler, contentRewrite) + e.GET("/*", defaultHandler) + e.GET("*", defaultHandler) +} + +func defaultHandler(c echo.Context) error { + buff, err := Content.ReadFile(strings.ReplaceAll("static/"+c.Request().URL.Path, "//", "/")) + if err != nil { + buff, err = Content.ReadFile("static/index.html") + if err != nil { + return c.String(http.StatusNotFound, "Page not found") + } + return c.Blob(http.StatusOK, http.DetectContentType(buff), buff) + } + contentType := http.DetectContentType(buff) + tmpArr := strings.Split(contentType, ";") + if len(tmpArr) > 0 && strings.Trim(tmpArr[0], " ") == "text/plain" { + ext1 := filepath.Ext(c.Request().URL.Path) + contentType = mime.TypeByExtension(ext1) + } + return c.Blob(http.StatusOK, contentType, buff) } diff --git a/lib/templ/tmpl/docs/db/adjacents-tables.tmpl b/lib/templ/tmpl/docs/db/adjacents-tables.tmpl index d92258c..b9c7ec7 100644 --- a/lib/templ/tmpl/docs/db/adjacents-tables.tmpl +++ b/lib/templ/tmpl/docs/db/adjacents-tables.tmpl @@ -8,12 +8,24 @@ {{ includeTemplPart "tmpl/docs/db/entity.tmpl" $table }} {{ end }} -// TODO {{ range $indexi, $table := .Parents }} -{{ $varNameTable := fieldNamePrepare $table.Name }} -{{range $indexj, $field := $table.FkFields }} +{{ $varNameTable := fieldNamePrepare $.Table.Name }} +{{ range $indexj, $field := $.Table.FKs }} +{{ if eq $field.TableID $table.ID }} {{ $fieldTypeParentTable := "" }} -{{ if eq $field.Name "Parent" }}{{ $fieldTypeParentTable = fieldNamePrepare $.Name }}{{ else }}{{ $fieldTypeParentTable = fieldType $field }}{{ end }} +{{ if eq $field.Name "Parent" }}{{ $fieldTypeParentTable = fieldNamePrepare $.Name }}{{ else }}{{ $newField := index $.Table.FkFields $indexj }}{{ $fieldTypeParentTable = fieldType $newField }}{{ end }} Ref: {{ fieldNameLowerPrepare $varNameTable }}.{{ fieldNameLowerPrepare $field.Name }}_id > {{ fieldNameLowerPrepare $fieldTypeParentTable }}.id {{ end }} +{{ end }} +{{ end }} + +{{ range $indexi, $table := .Children }} +{{ range $indexj, $field := $table.FKs }} +{{ if eq $field.TableID $.Table.ID }} +{{ $varNameTable := fieldNamePrepare $table.Name }} +{{ $fieldTypeParentTable := "" }} +{{ if eq $field.Name "Parent" }}{{ $fieldTypeParentTable = fieldNamePrepare $.Name }}{{ else }}{{ $newField := index $table.FkFields $indexj }}{{ $fieldTypeParentTable = fieldType $newField }}{{ end }} +Ref: {{ fieldNameLowerPrepare $varNameTable }}.{{ fieldNameLowerPrepare $field.Name }}_id > {{ fieldNameLowerPrepare $fieldTypeParentTable }}.id +{{ end }} +{{ end }} {{ end }} \ No newline at end of file diff --git a/lib/templ/tmpl/docs/db/entity-table-no-href.tmpl b/lib/templ/tmpl/docs/db/entity-table-no-href.tmpl index 75b5c21..e66f456 100644 --- a/lib/templ/tmpl/docs/db/entity-table-no-href.tmpl +++ b/lib/templ/tmpl/docs/db/entity-table-no-href.tmpl @@ -1,3 +1,5 @@ +![Таблица {{ fieldNameLowerPrepare $.Name }}]({{ fieldNameLowerPrepare $.Name }}.svg "Таблица {{ fieldNameLowerPrepare $.Name }}") + ### Поля |Поле|Тип|Описание| diff --git a/lib/templ/tmpl/docs/db/full-schema.tmpl b/lib/templ/tmpl/docs/db/full-schema.tmpl index 83ce34b..ec69b68 100644 --- a/lib/templ/tmpl/docs/db/full-schema.tmpl +++ b/lib/templ/tmpl/docs/db/full-schema.tmpl @@ -7,7 +7,7 @@ {{ range $indexi, $table := .Tables }} {{ $varNameTable := fieldNamePrepare $table.Name }} -{{range $indexj, $field := $table.FkFields }} +{{ range $indexj, $field := $table.FkFields }} {{ $fieldTypeParentTable := "" }} {{ if eq $field.Name "Parent" }}{{ $fieldTypeParentTable = fieldNamePrepare $.Name }}{{ else }}{{ $fieldTypeParentTable = fieldType $field }}{{ end }} Ref: {{ fieldNameLowerPrepare $varNameTable }}.{{ fieldNameLowerPrepare $field.Name }}_id > {{ fieldNameLowerPrepare $fieldTypeParentTable }}.id From 2fa119ad4e17bef3b4024e8cc3c78569e2ef44fa Mon Sep 17 00:00:00 2001 From: Ymnuk Date: Thu, 9 Nov 2023 16:29:29 +0300 Subject: [PATCH 6/7] =?UTF-8?q?=D0=93=D0=B5=D0=BD=D0=B5=D1=80.=20=D0=B4?= =?UTF-8?q?=D0=BE=D0=BA=D1=83=D0=BC.=20=D1=81=D1=82=D1=80=D1=83=D0=BA?= =?UTF-8?q?=D1=82=D1=83=D1=80=D1=8B=20=D0=91=D0=94=20=D0=B2=20=D0=BE=D1=82?= =?UTF-8?q?=D0=B4=D0=B5=D0=BB=D1=8C=D0=BD=D1=8B=D1=85=20=D1=84=D0=B0=D0=B9?= =?UTF-8?q?=D0=BB=D0=B0=D1=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/launch.json | 1 - lib/documentation.go | 49 +++++++++++++++++++ lib/templ/tmpl/docs/db/entity-table-href.tmpl | 22 +++++++++ lib/templ/tmpl/docs/db/table-list.tmpl | 4 ++ lib/templ/tmpl/docs/index.tmpl | 7 ++- 5 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 lib/templ/tmpl/docs/db/entity-table-href.tmpl diff --git a/.vscode/launch.json b/.vscode/launch.json index 5c53dcf..7fb26c5 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -63,7 +63,6 @@ "/home/ymnuk/projects/zmap/zmap.yml", "--outdir-doc", "../zmap/docs", - "--single-doc", "--format-markdown", "--format-html" ] diff --git a/lib/documentation.go b/lib/documentation.go index 61bf8a7..d76b34f 100644 --- a/lib/documentation.go +++ b/lib/documentation.go @@ -47,6 +47,55 @@ func Documentation() { panic(err) } } + } else { + if tmpl, err = templ.ReadTmplFile("tmpl/docs/index.tmpl"); err != nil { + panic(err) + } + if out, err = templ.ExecuteTmplFile(tmpl, Project); err != nil { + panic(err) + } + if AppConfig.IsMarkdown { + if err = templ.WriteFile(AppConfig.OutdirDoc+"/index.md", out); err != nil { + panic(err) + } + } + if AppConfig.IsHtml { + var buff []byte + if buff, err = templ.Content.ReadFile("tmpl/docs/styles.tmpl"); err != nil { + panic(err) + } + //{{ includeTemplPart "tmpl/docs/styles.tmpl" nil }} + out = append(buff, out...) + if err = templ.WriteFile(AppConfig.OutdirDoc+"/index.html", mdToHTML(out)); err != nil { + panic(err) + } + } + // Генерация каждого отдельного файла для каждой таблицы + if tmpl, err = templ.ReadTmplFile("tmpl/docs/db/entity-table-href.tmpl"); err != nil { + panic(err) + } + for _, table := range Project.DB.Tables { + // TODO + if out, err = templ.ExecuteTmplFile(tmpl, table); err != nil { + panic(err) + } + if AppConfig.IsMarkdown { + if err = templ.WriteFile(AppConfig.OutdirDoc+"/"+templ.FieldNameLowerPrepare(table.Name)+".md", out); err != nil { + panic(err) + } + } + if AppConfig.IsHtml { + var buff1 []byte + if buff1, err = templ.Content.ReadFile("tmpl/docs/styles.tmpl"); err != nil { + panic(err) + } + //{{ includeTemplPart "tmpl/docs/styles.tmpl" nil }} + out = append(buff1, out...) + if err = templ.WriteFile(AppConfig.OutdirDoc+"/"+templ.FieldNameLowerPrepare(table.Name)+".html", mdToHTML(out)); err != nil { + panic(err) + } + } + } } // Генерация каждой таблицы по отдельности с прилегающими ближайшими таблицами /*for i := range Project.DB.Tables { diff --git a/lib/templ/tmpl/docs/db/entity-table-href.tmpl b/lib/templ/tmpl/docs/db/entity-table-href.tmpl new file mode 100644 index 0000000..03848b5 --- /dev/null +++ b/lib/templ/tmpl/docs/db/entity-table-href.tmpl @@ -0,0 +1,22 @@ + + +# {{ fieldNameLowerPrepare $.Name }} + +![Таблица {{ fieldNameLowerPrepare $.Name }}]({{ fieldNameLowerPrepare $.Name }}.svg "Таблица {{ fieldNameLowerPrepare $.Name }}") + +## Поля + +|Поле|Тип|Описание| +|:---|:--|:-------| +|id|{{ fieldTypeDBStr .Pk nil }}|Первичный ключ| +{{ range $index, $field := .Fields }}|{{ fieldNameLowerPrepare $field.Name }}|{{ fieldTypeDB $field }}|{{ $field.Description }}| +{{ end }} + +## Внешние ключи + +|Ключ|Тип|Талица|Описание| +|:---|:--|:-----|:-------| +{{ range $index, $field := .FkFields }}|{{ fieldNameLowerPrepare $field.Name }}_id|{{ fieldNameLowerPrepare $field.TypeParentTable }}|{{ $tableNameVar := "" }}{{ if eq $field.Name "Parent" }}{{ $tableNameVar = fieldNamePrepare $.Name }}{{ else }}{{ $tableNameVar = fieldType $field }}{{ end }}{{ fieldNameLowerPrepare $tableNameVar }}|{{ $field.Description }}| +{{ end }} + +[На главную](index.md) \ No newline at end of file diff --git a/lib/templ/tmpl/docs/db/table-list.tmpl b/lib/templ/tmpl/docs/db/table-list.tmpl index e69de29..e90c4df 100644 --- a/lib/templ/tmpl/docs/db/table-list.tmpl +++ b/lib/templ/tmpl/docs/db/table-list.tmpl @@ -0,0 +1,4 @@ +|Название|Описание| +|:-------|:-------| +{{ range $index, $table := .Tables }}|{{ $varNameField := fieldNamePrepare $table.Name }}[{{ fieldNameLowerPrepare $varNameField }}]({{ fieldNameLowerPrepare $varNameField }}.md)|{{ $table.Description }}| +{{end}} \ No newline at end of file diff --git a/lib/templ/tmpl/docs/index.tmpl b/lib/templ/tmpl/docs/index.tmpl index 7581886..20c85f9 100644 --- a/lib/templ/tmpl/docs/index.tmpl +++ b/lib/templ/tmpl/docs/index.tmpl @@ -1 +1,6 @@ -# Help \ No newline at end of file + +# База данных + +{{ includeTemplPart "tmpl/docs/db/table-list.tmpl" .DB }} + +![Полная структура БД](full-schemadb.svg "Полная структура БД") From 60354202f6d92cc8fe39eb20145846c3c7eac72f Mon Sep 17 00:00:00 2001 From: Ymnuk Date: Fri, 10 Nov 2023 10:08:27 +0300 Subject: [PATCH 7/7] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D1=80=D0=B0=D1=81=D1=88=D0=B8=D1=80=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F=20html=20=D0=BF=D1=80=D0=B8=20=D1=8D=D0=BA=D1=81?= =?UTF-8?q?=D0=BF=D0=BE=D1=80=D1=82=D0=B5=20=D0=B2=20html?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/launch.json | 3 +-- lib/documentation.go | 9 +++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index 7fb26c5..a84ab74 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -63,8 +63,7 @@ "/home/ymnuk/projects/zmap/zmap.yml", "--outdir-doc", "../zmap/docs", - "--format-markdown", - "--format-html" + "--format-markdown" ] } ] diff --git a/lib/documentation.go b/lib/documentation.go index d76b34f..5511cf2 100644 --- a/lib/documentation.go +++ b/lib/documentation.go @@ -3,6 +3,7 @@ package lib import ( "fmt" "log" + "strings" "text/template" "git.ymnuktech.ru/ymnuk/yt-gen-app/lib/templ" @@ -66,7 +67,9 @@ func Documentation() { } //{{ includeTemplPart "tmpl/docs/styles.tmpl" nil }} out = append(buff, out...) - if err = templ.WriteFile(AppConfig.OutdirDoc+"/index.html", mdToHTML(out)); err != nil { + out = []byte(strings.ReplaceAll(string(out), ".md", ".html")) + out = mdToHTML(out) + if err = templ.WriteFile(AppConfig.OutdirDoc+"/index.html", out); err != nil { panic(err) } } @@ -91,7 +94,9 @@ func Documentation() { } //{{ includeTemplPart "tmpl/docs/styles.tmpl" nil }} out = append(buff1, out...) - if err = templ.WriteFile(AppConfig.OutdirDoc+"/"+templ.FieldNameLowerPrepare(table.Name)+".html", mdToHTML(out)); err != nil { + out = []byte(strings.ReplaceAll(string(out), ".md", ".html")) + out = mdToHTML(out) + if err = templ.WriteFile(AppConfig.OutdirDoc+"/"+templ.FieldNameLowerPrepare(table.Name)+".html", out); err != nil { panic(err) } }