You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
177 lines
3.2 KiB
177 lines
3.2 KiB
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
|
|
}
|
|
|