Browse Source

types (#1)

Co-authored-by: andrey1s <andrey@4devs.pro>
Reviewed-on: https://gitoa.ru/go-4devs/mime/pulls/1
Co-authored-by: andrey <andrey@4devs.io>
Co-committed-by: andrey <andrey@4devs.io>
pull/2/head
andrey 4 months ago
parent
commit
8ff25d212d
  1. 42
      .drone.yml
  2. 43
      .golangci.yml
  3. 1
      README.md
  4. 17048
      extension.go
  5. 13352
      mime.go
  6. 1666
      mime.json
  7. 3394
      mime.yaml
  8. 36
      mime_example_test.go
  9. 2
      scripts/command/mime.go
  10. 1
      scripts/go.mod
  11. 3
      scripts/go.sum
  12. 2
      scripts/main.go
  13. 148
      scripts/mime/generate.go
  14. 55
      scripts/mime/tpl/extension.text.tmpl
  15. 54
      scripts/mime/tpl/mime.text.tmpl
  16. 11
      scripts/mime/varmane.go

42
.drone.yml

@ -0,0 +1,42 @@
kind: pipeline
name: default
steps:
- name: golangci-lint
image: golangci/golangci-lint:v1.49
volumes:
- name: deps
path: /go/src/mod
commands:
- golangci-lint run --timeout 5m
- name: test
image: golang
volumes:
- name: deps
path: /go/src/mod
commands:
- go test ./...
- name: scripts golangci-lint
image: golangci/golangci-lint:v1.49
volumes:
- name: deps
path: /go/src/mod
commands:
- cd scripts
- golangci-lint run --timeout 5m
- name: scripts test
image: golang
volumes:
- name: deps
path: /go/src/mod
commands:
- cd scripts
- go test ./...
volumes:
- name: deps
temp: {}

43
.golangci.yml

@ -0,0 +1,43 @@
linters-settings:
dupl:
threshold: 100
funlen:
lines: 100
statements: 50
goconst:
min-len: 2
min-occurrences: 2
gocyclo:
min-complexity: 15
golint:
min-confidence: 0
govet:
check-shadowing: true
lll:
line-length: 140
maligned:
suggest-new: true
misspell:
locale: US
varnamelen:
min-name-length: 2
linters:
enable-all: true
disable:
- varcheck
- maligned
- scopelint
- nosnakecase
- ifshort
- golint
- interfacer
- structcheck
- deadcode
- exhaustivestruct
- exhaustruct
# is disabled because of generics. You can track the evolution of the generics support by following the https://github.com/golangci/golangci-lint/issues/2649
- rowserrcheck
- sqlclosecheck
- wastedassign

1
README.md

@ -1,2 +1,3 @@
# mime
[![Build Status](https://drone.gitoa.ru/api/badges/go-4devs/mime/status.svg)](https://drone.gitoa.ru/go-4devs/mime)

17048
extension.go

File diff suppressed because it is too large

13352
mime.go

File diff suppressed because it is too large

1666
mime.json

File diff suppressed because it is too large

3394
mime.yaml

File diff suppressed because it is too large

36
mime_example_test.go

@ -0,0 +1,36 @@
package mime_test
import (
"fmt"
"gitoa.ru/go-4devs/mime"
)
func ExampleMime_String() {
fmt.Printf("%v", mime.TextHTML)
// Output:
// text/html
}
func ExampleMime_Is() {
fmt.Printf("%v\n%v",
mime.TextHTML.Is(mime.ApplicationJSON, mime.ApplicationJavascript),
mime.TextHTML.Is(mime.ApplicationJavascript, mime.TextHTML),
)
// Output:
// false
// true
}
func ExampleMime_ExtTypes() {
fmt.Printf("%v\n%v",
mime.TextHTML.ExtTypes(),
mime.ApplicationJavascript.ExtTypes(),
)
// Output:
// [html htm shtml]
// [js mjs jsm]
}

2
scripts/command/mime.go

@ -27,7 +27,7 @@ func Mime() *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.SetArgument(ArgFile, "yaml 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")),

1
scripts/go.mod

@ -6,4 +6,5 @@ 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
gopkg.in/yaml.v3 v3.0.1
)

3
scripts/go.sum

@ -3,8 +3,10 @@ github.com/achiku/varfmt v0.0.0-20160708124000-f820e1efecee/go.mod h1:RKS7P4TSY/
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 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
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 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
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=
@ -18,6 +20,7 @@ gitoa.ru/go-4devs/closer v0.1.1/go.mod h1:S+QAdgSt4CVLH3v3YZK1Mukl7SVn2Z0CYj0oJQ
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 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
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=

2
scripts/main.go

@ -11,8 +11,10 @@ import (
func main() {
ctx, cancel := context.WithCancel(context.Background())
closer.AddLast(func() error {
cancel()
return nil
})

148
scripts/mime/generate.go

@ -1,31 +1,105 @@
package mime
import (
"encoding/json"
"errors"
"fmt"
"go/format"
"io/ioutil"
"os"
"path"
"text/template"
"gopkg.in/yaml.v3"
)
var (
ErrDuplicate = errors.New("duplicate")
ErrNotFound = errors.New("not found")
)
const (
NameExt = "ext"
NameMime = "mime"
)
type Config struct {
Source string
Mimes map[string][]string
Mimes []Data `yaml:"mime"`
MimePrefix string
MimeTpl string
MimeResult string
MimePackage string
Extensions map[string][]string
Extensions []Data `yaml:"ext"`
ExtPrefix string
ExtTpl string
ExtResult string
ExtPackage string
}
type Data struct {
Name string `yaml:"name"`
ID int `yaml:"id"`
Value []string `yaml:"value,omitempty"`
}
func (c *Config) Base(name string) string {
switch name {
case NameExt:
return path.Base(c.ExtTpl)
case NameMime:
return path.Base(c.MimeTpl)
}
return ""
}
func (c *Config) Result(name string) string {
switch name {
case NameExt:
return c.ExtResult
case NameMime:
return c.MimeResult
}
return ""
}
func (c *Config) ValidateAndFillExt() error {
mimes := make(map[string]int)
mimeIDs := make(map[int]string)
extIndex := make(map[string]int)
for idx, ext := range c.Extensions {
if _, ok := extIndex[ext.Name]; ok {
return fmt.Errorf("extension %v %w: with id %v", ext.Name, ErrDuplicate, c.Extensions[extIndex[ext.Name]].ID)
}
extIndex[ext.Name] = idx
}
for _, mime := range c.Mimes {
if _, ok := mimes[mime.Name]; ok {
return fmt.Errorf("mime %v %w: with id %v", mime.Name, ErrDuplicate, mimes[mime.Name])
}
if _, ok := mimeIDs[mime.ID]; ok {
return fmt.Errorf("ID %v %w: with name %v", mime.ID, ErrDuplicate, mimeIDs[mime.ID])
}
for _, ext := range mime.Value {
idx, ok := extIndex[ext]
if !ok {
return fmt.Errorf("%w ext by %v", ErrNotFound, mime.Name)
}
c.Extensions[idx].Value = append(c.Extensions[idx].Value, mime.Name)
}
}
return nil
}
func WithExtTpl(name string) Option {
return func(c *Config) {
c.ExtTpl = name
@ -78,11 +152,9 @@ func Generate(fileName string, opts ...Option) error {
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",
@ -92,46 +164,47 @@ func Generate(fileName string, opts ...Option) error {
opt(&cfg)
}
data, err := os.ReadFile(fileName)
if err != nil {
return fmt.Errorf("read file:%w", err)
data, cerr := os.ReadFile(fileName)
if cerr != nil {
return fmt.Errorf("read file:%w", cerr)
}
if err := json.Unmarshal(data, &cfg.Mimes); err != nil {
return fmt.Errorf("unmarshal:%w", err)
if uerr := yaml.Unmarshal(data, &cfg); uerr != nil {
return fmt.Errorf("unmarshal:%w", uerr)
}
cfg.Extensions = extensions(cfg.Mimes)
if validErr := cfg.ValidateAndFillExt(); validErr != nil {
return fmt.Errorf("config:%w", validErr)
}
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 exErr := Create(template, NameExt, cfg); exErr != nil {
return fmt.Errorf("ext create:%w", exErr)
}
if err := template.ExecuteTemplate(extFile, path.Base(cfg.ExtTpl), cfg); err != nil {
return fmt.Errorf("ext execute:%w", err)
if mimeErr := Create(template, NameMime, cfg); mimeErr != nil {
return fmt.Errorf("mime create:%w", mimeErr)
}
if err := Format(extFile.Name()); err != nil {
return fmt.Errorf("format ext:%w", err)
}
return nil
}
mimeFile, err := os.Create(cfg.MimeResult)
func Create(tpl *template.Template, name string, cfg Config) error {
extFile, err := os.Create(cfg.Result(name))
if err != nil {
return fmt.Errorf("mime file:%w", err)
return fmt.Errorf("ext file:%w", err)
}
if err := template.ExecuteTemplate(mimeFile, path.Base(cfg.MimeTpl), cfg); err != nil {
return fmt.Errorf("mime execute:%w", err)
if exErr := tpl.ExecuteTemplate(extFile, cfg.Base(name), cfg); exErr != nil {
return fmt.Errorf("ext execute:%w", exErr)
}
if err := Format(mimeFile.Name()); err != nil {
return fmt.Errorf("format mime:%w", err)
if formatErr := Format(extFile.Name()); formatErr != nil {
return fmt.Errorf("format ext:%w", formatErr)
}
return nil
@ -139,13 +212,14 @@ func Generate(fileName string, opts ...Option) error {
// Format file and write it.
func Format(name string) error {
in, err := ioutil.ReadFile(name)
in, err := os.ReadFile(name)
if err != nil {
return err
return fmt.Errorf("read file:%w", err)
}
out, err := format.Source(in)
if err != nil {
return err
return fmt.Errorf("format source:%w", err)
}
file, err := os.Create(name)
@ -159,19 +233,3 @@ func Format(name string) error {
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
}

55
scripts/mime/tpl/extension.text.tmpl

@ -1,19 +1,58 @@
// Code generated by gitoa.ru/go-4devs/mime and sourse {{.Source}}
package {{.ExtPackage}}
import "fmt"
type Ext int
type ExtTypes []Ext
func (v Ext) Is(types ...Ext) bool {
for _, ext := range types {
if ext == v {
return true
}
}
return false
}
func (v Ext) String() string {
switch v {
{{- range $value := .Extensions }}
case {{ name $.ExtPrefix $value.Name }}:
return "{{- $value.Name -}}"
{{- end}}
}
return fmt.Sprintf("Ext(%d)",v)
}
func (v Ext) MimeTypes() MimeTypes{
switch v {
{{- range $value := .Extensions }}
case {{ name $.ExtPrefix $value.Name }}:
return MimeTypes{ {{- value $.MimePrefix $value.Value -}} }
{{- end}}
}
return nil
}
const (
{{- range $key, $value := .Extensions }}
{{ name $.ExtPrefix $key }} = "{{ $key }}"
{{- range $value := .Extensions }}
{{ name $.ExtPrefix $value.Name }} Ext = {{ $value.ID }}
{{- end}}
)
func Mime(name string) []string {
func ExtFromString(name string) Ext {
switch name {
{{- range $key, $value := .Extensions }}
case {{ name $.ExtPrefix $key }}:
return {{ value $value }}
{{- range $value := .Extensions }}
case "{{- $value.Name -}}":
return {{ name $.ExtPrefix $value.Name }}
{{- end}}
}
return nil
return 0
}

54
scripts/mime/tpl/mime.text.tmpl

@ -1,19 +1,57 @@
// Code generated by gitoa.ru/go-4devs/mime and sourse {{.Source}}
package {{.MimePackage}}
import "fmt"
type Mime int
type MimeTypes []Mime
func (v Mime) Is(types ...Mime) bool {
for _, mime := range types {
if mime == v {
return true
}
}
return false
}
func (v Mime) String() string {
switch v {
{{- range $value := .Mimes }}
case {{ name $.MimePrefix $value.Name }}:
return "{{- $value.Name -}}"
{{- end}}
}
return fmt.Sprintf("Mime(%d)",v)
}
func (v Mime) ExtTypes() ExtTypes{
switch v {
{{- range $value := .Mimes }}
case {{ name $.MimePrefix $value.Name }}:
return []Ext{ {{- value $.ExtPrefix $value.Value -}} }
{{- end}}
}
return nil
}
const (
{{- range $key, $value := .Mimes }}
{{ name $.MimePrefix $key }} = "{{ $key }}"
{{- range $value := .Mimes }}
{{ name $.MimePrefix $value.Name }} Mime = {{ $value.ID }}
{{- end}}
)
func Extension(name string) []string {
func MimeFromString(name string) Mime {
switch name {
{{- range $key, $value := .Mimes }}
case {{ name $.MimePrefix $key }}:
return {{ value $value }}
{{- range $value := .Mimes }}
case "{{- $value.Name -}}":
return {{ name $.MimePrefix $value.Name }}
{{- end}}
}
return nil
return 0
}

11
scripts/mime/varmane.go

@ -1,7 +1,7 @@
package mime
import (
"fmt"
"bytes"
"strings"
"unicode"
@ -27,6 +27,11 @@ func VarName(prefix, name string) string {
return varfmt.PublicVarName(prefix + "_" + name)
}
func Value(val []string) string {
return fmt.Sprintf("%#v", val)
func Value(prefix string, val []string) string {
var out bytes.Buffer
for _, name := range val {
out.WriteString(VarName(prefix, name) + ",")
}
return out.String()
}

Loading…
Cancel
Save