From 779846fe9a24f2bf73c14b221a46c33d8481754b Mon Sep 17 00:00:00 2001 From: andrey1s Date: Sat, 24 Sep 2022 15:51:48 +0300 Subject: [PATCH] init scripts generate mime and extension --- scripts/command/mime.go | 60 +++++++++ scripts/go.mod | 9 ++ scripts/go.sum | 24 ++++ scripts/main.go | 24 ++++ scripts/mime/generate.go | 177 +++++++++++++++++++++++++++ scripts/mime/tpl/extension.text.tmpl | 19 +++ scripts/mime/tpl/mime.text.tmpl | 19 +++ scripts/mime/varmane.go | 32 +++++ 8 files changed, 364 insertions(+) create mode 100644 scripts/command/mime.go create mode 100644 scripts/go.mod create mode 100644 scripts/go.sum create mode 100644 scripts/main.go create mode 100644 scripts/mime/generate.go create mode 100644 scripts/mime/tpl/extension.text.tmpl create mode 100644 scripts/mime/tpl/mime.text.tmpl create mode 100644 scripts/mime/varmane.go diff --git a/scripts/command/mime.go b/scripts/command/mime.go new file mode 100644 index 0000000..7d518b2 --- /dev/null +++ b/scripts/command/mime.go @@ -0,0 +1,60 @@ +package command + +import ( + "context" + "fmt" + + "gitoa.ru/go-4devs/console" + "gitoa.ru/go-4devs/console/input" + "gitoa.ru/go-4devs/console/input/argument" + "gitoa.ru/go-4devs/console/input/option" + "gitoa.ru/go-4devs/console/output" + "gitoa.ru/go-4devs/mime/scripts/mime" +) + +const ( + ArgFile = "file" + OptExtTpl = "ext-tpl" + OptExtPackage = "ext-package" + OptExtResult = "ext-result" + OptMimeTpl = "mime-tpl" + OptMimePackage = "mime-package" + OptMimeResult = "mime-result" +) + +func Mime() *console.Command { + return &console.Command{ + Name: "mime", + Description: "generate mime from file", + Configure: func(ctx context.Context, cfg *input.Definition) error { + cfg.SetArgument(ArgFile, "file", argument.Required) + cfg.SetOptions( + option.String(OptExtTpl, "extension template", option.Default("mime/tpl/extension.text.tmpl")), + option.String(OptExtPackage, "extension package", option.Default("mime")), + option.String(OptExtResult, "extension result", option.Default("../extension.go")), + option.String(OptMimeTpl, "mime template", option.Default("mime/tpl/mime.text.tmpl")), + option.String(OptMimePackage, "mime package", option.Default("mime")), + option.String(OptMimeResult, "mime result", option.Default("../mime.go")), + ) + + return nil + }, + Execute: func(ctx context.Context, input input.Input, output output.Output) error { + file := input.Argument(ctx, ArgFile).String() + opts := []mime.Option{ + mime.WithExtTpl(input.Option(ctx, OptExtTpl).String()), + mime.WithExtPacakge(input.Option(ctx, OptExtPackage).String()), + mime.WithExtResult(input.Option(ctx, OptExtResult).String()), + mime.WithMimeTpl(input.Option(ctx, OptMimeTpl).String()), + mime.WithMimePackage(input.Option(ctx, OptMimePackage).String()), + mime.WithMimeResult(input.Option(ctx, OptMimeResult).String()), + } + + if err := mime.Generate(file, opts...); err != nil { + return fmt.Errorf("generate:%w", err) + } + + return nil + }, + } +} diff --git a/scripts/go.mod b/scripts/go.mod new file mode 100644 index 0000000..6db3e34 --- /dev/null +++ b/scripts/go.mod @@ -0,0 +1,9 @@ +module gitoa.ru/go-4devs/mime/scripts + +go 1.19 + +require ( + github.com/achiku/varfmt v0.0.0-20160708124000-f820e1efecee + gitoa.ru/go-4devs/closer v0.1.1 + gitoa.ru/go-4devs/console v0.1.2 +) diff --git a/scripts/go.sum b/scripts/go.sum new file mode 100644 index 0000000..1de705f --- /dev/null +++ b/scripts/go.sum @@ -0,0 +1,24 @@ +github.com/achiku/varfmt v0.0.0-20160708124000-f820e1efecee h1:IfTwtLm+DUeY8kZ8NKSxGRr2kaCe8qqIpJz4Uwh1efU= +github.com/achiku/varfmt v0.0.0-20160708124000-f820e1efecee/go.mod h1:RKS7P4TSY/jV2QjH/ZxoAE2l4EEXZRPwQ/tIzXiFrk0= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +gitoa.ru/go-4devs/closer v0.1.1 h1:3mTzBBmAVZB9Im5FcRzk6QUak3Ko+tWiNyFkTuKzIx4= +gitoa.ru/go-4devs/closer v0.1.1/go.mod h1:S+QAdgSt4CVLH3v3YZK1Mukl7SVn2Z0CYj0oJQMTZG4= +gitoa.ru/go-4devs/console v0.1.2 h1:SsQWLSClXFwWFseH6CGKQfmCtG84aHOiaFHG3oZlJ8s= +gitoa.ru/go-4devs/console v0.1.2/go.mod h1:ddqmjQ0yr9v+oa5E3Bu3X/SUcws/ENR5f5cz1g5fHbk= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/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= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/scripts/main.go b/scripts/main.go new file mode 100644 index 0000000..e985a6d --- /dev/null +++ b/scripts/main.go @@ -0,0 +1,24 @@ +package main + +import ( + "context" + "syscall" + + "gitoa.ru/go-4devs/closer" + "gitoa.ru/go-4devs/console" + "gitoa.ru/go-4devs/mime/scripts/command" +) + +func main() { + ctx, cancel := context.WithCancel(context.Background()) + closer.AddLast(func() error { + cancel() + return nil + }) + + go func() { + closer.Wait(ctx, syscall.SIGTERM, syscall.SIGINT) + }() + + console.Execute(ctx, command.Mime()) +} diff --git a/scripts/mime/generate.go b/scripts/mime/generate.go new file mode 100644 index 0000000..67571f7 --- /dev/null +++ b/scripts/mime/generate.go @@ -0,0 +1,177 @@ +package mime + +import ( + "encoding/json" + "fmt" + "go/format" + "io/ioutil" + "os" + "path" + "text/template" +) + +type Config struct { + Source string + + Mimes map[string][]string + MimePrefix string + MimeTpl string + MimeResult string + MimePackage string + + Extensions map[string][]string + ExtPrefix string + ExtTpl string + ExtResult string + ExtPackage string +} + +func WithExtTpl(name string) Option { + return func(c *Config) { + c.ExtTpl = name + } +} + +func WithExtPacakge(name string) Option { + return func(c *Config) { + c.ExtPackage = name + } +} + +func WithExtResult(name string) Option { + return func(c *Config) { + c.ExtResult = name + } +} + +func WithMimeTpl(name string) Option { + return func(c *Config) { + c.MimeTpl = name + } +} + +func WithMimePackage(name string) Option { + return func(c *Config) { + c.MimePackage = name + } +} + +func WithMimeResult(name string) Option { + return func(c *Config) { + c.MimeResult = name + } +} + +type Option func(*Config) + +func funcMap() template.FuncMap { + return template.FuncMap{ + "name": VarName, + "value": Value, + } +} + +func Generate(fileName string, opts ...Option) error { + cfg := Config{ + Source: fileName, + + ExtPrefix: "Ext", + ExtTpl: "mime/tpl/extension.text.tmpl", + ExtResult: "extension.go", + Extensions: make(map[string][]string), + ExtPackage: "mime", + + MimeTpl: "mime/tpl/mime.text.tmpl", + Mimes: make(map[string][]string), + MimePrefix: "", + MimeResult: "mime.go", + MimePackage: "mime", + } + + for _, opt := range opts { + opt(&cfg) + } + + data, err := os.ReadFile(fileName) + if err != nil { + return fmt.Errorf("read file:%w", err) + } + + if err := json.Unmarshal(data, &cfg.Mimes); err != nil { + return fmt.Errorf("unmarshal:%w", err) + } + + cfg.Extensions = extensions(cfg.Mimes) + + template, err := template.New("mimes").Funcs(funcMap()).ParseFiles(cfg.ExtTpl, cfg.MimeTpl) + if err != nil { + return fmt.Errorf("ext template:%w", err) + } + + extFile, err := os.Create(cfg.ExtResult) + if err != nil { + return fmt.Errorf("ext file:%w", err) + } + + if err := template.ExecuteTemplate(extFile, path.Base(cfg.ExtTpl), cfg); err != nil { + return fmt.Errorf("ext execute:%w", err) + } + + if err := Format(extFile.Name()); err != nil { + return fmt.Errorf("format ext:%w", err) + } + + mimeFile, err := os.Create(cfg.MimeResult) + if err != nil { + return fmt.Errorf("mime file:%w", err) + } + + if err := template.ExecuteTemplate(mimeFile, path.Base(cfg.MimeTpl), cfg); err != nil { + return fmt.Errorf("mime execute:%w", err) + } + + if err := Format(mimeFile.Name()); err != nil { + return fmt.Errorf("format mime:%w", err) + } + + return nil +} + +// Format file and write it. +func Format(name string) error { + in, err := ioutil.ReadFile(name) + if err != nil { + return err + } + out, err := format.Source(in) + if err != nil { + return err + } + + file, err := os.Create(name) + if err != nil { + return fmt.Errorf("ext file:%w", err) + } + + if _, err := file.Write(out); err != nil { + return fmt.Errorf("write:%w", err) + } + + return nil +} + +func extensions(mimes map[string][]string) map[string][]string { + out := make(map[string][]string) + + for mime, exts := range mimes { + for _, ext := range exts { + if _, ok := out[ext]; ok { + out[ext] = append(out[ext], mime) + continue + } + out[ext] = []string{ext} + } + } + + return out +} diff --git a/scripts/mime/tpl/extension.text.tmpl b/scripts/mime/tpl/extension.text.tmpl new file mode 100644 index 0000000..1c9a347 --- /dev/null +++ b/scripts/mime/tpl/extension.text.tmpl @@ -0,0 +1,19 @@ +// Code generated by gitoa.ru/go-4devs/mime and sourse {{.Source}} +package {{.ExtPackage}} + +const ( +{{- range $key, $value := .Extensions }} + {{ name $.ExtPrefix $key }} = "{{ $key }}" +{{- end}} +) + +func Mime(name string) []string { + switch name { +{{- range $key, $value := .Extensions }} + case {{ name $.ExtPrefix $key }}: + return {{ value $value }} +{{- end}} + } + + return nil +} diff --git a/scripts/mime/tpl/mime.text.tmpl b/scripts/mime/tpl/mime.text.tmpl new file mode 100644 index 0000000..c95bc48 --- /dev/null +++ b/scripts/mime/tpl/mime.text.tmpl @@ -0,0 +1,19 @@ +// Code generated by gitoa.ru/go-4devs/mime and sourse {{.Source}} +package {{.MimePackage}} + +const ( +{{- range $key, $value := .Mimes }} + {{ name $.MimePrefix $key }} = "{{ $key }}" +{{- end}} +) + +func Extension(name string) []string { + switch name { +{{- range $key, $value := .Mimes }} + case {{ name $.MimePrefix $key }}: + return {{ value $value }} +{{- end}} + } + + return nil +} diff --git a/scripts/mime/varmane.go b/scripts/mime/varmane.go new file mode 100644 index 0000000..a344e1d --- /dev/null +++ b/scripts/mime/varmane.go @@ -0,0 +1,32 @@ +package mime + +import ( + "fmt" + "strings" + "unicode" + + "github.com/achiku/varfmt" +) + +func VarName(prefix, name string) string { + rules := map[string]string{ + "+": "_plus", + "-": "_dash_", + "/": "_", + ".": "_dot_", + } + + for old, new := range rules { + name = strings.ReplaceAll(name, old, new) + } + + if unicode.IsUpper(rune(name[0])) { + name = " " + name + } + + return varfmt.PublicVarName(prefix + "_" + name) +} + +func Value(val []string) string { + return fmt.Sprintf("%#v", val) +}