From 1cea854e1c9bfd3bcf05b9db03ecbd350d44bfa3 Mon Sep 17 00:00:00 2001 From: Tom Limoncelli Date: Fri, 4 Jun 2021 15:50:47 -0400 Subject: [PATCH] MAINT: Adopt go 1.16's embed feature (#1162) * MAINT: Switch from esc to embed * Simplify * Update minimum go version in docs and pipelines * go generate --- Dockerfile | 2 +- README.md | 2 +- build/azure-pipelines/go-env.yaml | 2 +- build/generate/generate.go | 23 -- docs/_includes/matrix.html | 4 +- docs/getting-started.md | 2 +- go.mod | 3 +- go.sum | 5 - pkg/js/js.go | 20 +- pkg/js/static.go | 364 ------------------------------ 10 files changed, 25 insertions(+), 402 deletions(-) delete mode 100644 pkg/js/static.go diff --git a/Dockerfile b/Dockerfile index 4ebf2156e..380d733ae 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.14-alpine AS build-env +FROM golang:1.16-alpine AS build-env WORKDIR /go/src/github.com/StackExchange/dnscontrol ADD . . RUN apk update && apk add git diff --git a/README.md b/README.md index a2b4a89c5..5adeb02dd 100644 --- a/README.md +++ b/README.md @@ -119,7 +119,7 @@ See [Getting Started](https://stackexchange.github.io/dnscontrol/getting-started ## From source -DNSControl can be built with Go version 1.14 or higher. +DNSControl can be built with Go version 1.16 or higher. The `go get` command will download the source, compile it, and install `dnscontrol` in your `$GOBIN` directory. diff --git a/build/azure-pipelines/go-env.yaml b/build/azure-pipelines/go-env.yaml index 2ec28759e..9d2f56c44 100644 --- a/build/azure-pipelines/go-env.yaml +++ b/build/azure-pipelines/go-env.yaml @@ -3,4 +3,4 @@ steps: - task: GoTool@0 inputs: - version: '1.14' + version: '1.16' diff --git a/build/generate/generate.go b/build/generate/generate.go index 71da1ccaf..6334655a2 100644 --- a/build/generate/generate.go +++ b/build/generate/generate.go @@ -2,32 +2,9 @@ package main import ( "log" - "os" - - "github.com/mjibson/esc/embed" ) func main() { - conf := &embed.Config{ - ModTime: "0", - OutputFile: "pkg/js/static.go", - Package: "js", - Prefix: "pkg/js", - Private: true, - Files: []string{`pkg/js/helpers.js`}, - } - - var err error - out := os.Stdout - if conf.OutputFile != "" { - if out, err = os.Create(conf.OutputFile); err != nil { - log.Fatal(err) - } - defer out.Close() - } - - embed.Run(conf, out) - if err := generateFeatureMatrix(); err != nil { log.Fatal(err) } diff --git a/docs/_includes/matrix.html b/docs/_includes/matrix.html index 92cd209ae..79036fe52 100644 --- a/docs/_includes/matrix.html +++ b/docs/_includes/matrix.html @@ -1543,8 +1543,8 @@ - - + + diff --git a/docs/getting-started.md b/docs/getting-started.md index 6e4e2a50d..6de6830a0 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -9,7 +9,7 @@ title: Getting Started ## From source -DNSControl can be built with Go version 1.14 or higher. +DNSControl can be built with Go version 1.16 or higher. The `go get` command will download the source, compile it, and install `dnscontrol` in your `$GOBIN` directory. diff --git a/go.mod b/go.mod index 154bacbf7..b3c10bbb7 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/StackExchange/dnscontrol/v3 -go 1.14 +go 1.16 require ( github.com/Azure/azure-sdk-for-go v55.1.0+incompatible @@ -46,7 +46,6 @@ require ( github.com/miekg/dns v1.1.42 github.com/mitchellh/mapstructure v1.4.1 // indirect github.com/mittwald/go-powerdns v0.5.2 - github.com/mjibson/esc v0.2.0 github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04 github.com/nrdcg/goinwx v0.8.1 github.com/oracle/oci-go-sdk/v32 v32.0.0 diff --git a/go.sum b/go.sum index 5605e5651..d1f3c4a11 100644 --- a/go.sum +++ b/go.sum @@ -375,11 +375,8 @@ github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mittwald/go-powerdns v0.5.2 h1:kfqr9ZNIuxOjjBaoJcOFiy/19VmKEUgfJPmObDglPJU= github.com/mittwald/go-powerdns v0.5.2/go.mod h1:bI/sZBAWyTViDknOTp19VfDxVEnh1U7rWPx2aRKtlzg= -github.com/mjibson/esc v0.2.0 h1:k96hdaR9Z+nMcnDwNrOvhdBqtjyMrbVyxLpsRCdP2mA= -github.com/mjibson/esc v0.2.0/go.mod h1:9Hw9gxxfHulMF5OJKCyhYD7PzlSdhzXyaGEBRPH1OPs= github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04 h1:o6uBwrhM5C8Ll3MAAxrQxRHEu7FkapwTuI2WmL1rw4g= github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04/go.mod h1:5sN+Lt1CaY4wsPvgQH/jsuJi4XO2ssZbdsIizr4CVC8= -github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 h1:W6apQkHrMkS0Muv8G/TipAy/FJl/rCYT0+EuS8+Z0z4= github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms= github.com/nkovacs/streamquote v1.0.0/go.mod h1:BN+NaZ2CmdKqUuTUXUEm9j95B2TRbpOWpxbJYzzgUsc= github.com/nrdcg/goinwx v0.8.1 h1:20EQ/JaGFnSKwiDH2JzjIpicffl3cPk6imJBDqVBVtU= @@ -515,7 +512,6 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180406214816-61147c48b25b/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -697,7 +693,6 @@ golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.1 h1:wGiQel/hW0NnEkJUk8lbzkX2gFJU6PFxf1v5OlCfuOs= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/pkg/js/js.go b/pkg/js/js.go index a76f8135d..da1b87b33 100644 --- a/pkg/js/js.go +++ b/pkg/js/js.go @@ -1,9 +1,11 @@ package js import ( + _ "embed" "encoding/json" "fmt" "io/ioutil" + "log" "os" "path/filepath" "strings" @@ -21,6 +23,10 @@ import ( "github.com/StackExchange/dnscontrol/v3/pkg/transform" ) +//go:embed helpers.js +var helpersJsStatic string +var helpersJsFileName = "pkg/js/helpers.js" + // currentDirectory is the current directory as used by require(). // This is used to emulate nodejs-style require() directory handling. // If require("a/b/c.js") is called, any require() statement in c.js @@ -101,9 +107,19 @@ func ExecuteJavascript(file string, devMode bool, variables map[string]string) ( return conf, nil } -// GetHelpers returns the filename of helpers.js, or the esc'ed version. +// GetHelpers returns the contents of helpers.js, or the embedded version. func GetHelpers(devMode bool) string { - return _escFSMustString(devMode, "/helpers.js") + if devMode { + // Load the file: + b, err := ioutil.ReadFile(helpersJsFileName) + if err != nil { + log.Fatal(err) + } + return string(b) + } + + // Return the embedded bytes: + return helpersJsStatic } func require(call otto.FunctionCall) otto.Value { diff --git a/pkg/js/static.go b/pkg/js/static.go deleted file mode 100644 index da0f29d32..000000000 --- a/pkg/js/static.go +++ /dev/null @@ -1,364 +0,0 @@ -// Code generated by "esc"; DO NOT EDIT. - -package js - -import ( - "bytes" - "compress/gzip" - "encoding/base64" - "fmt" - "io" - "io/ioutil" - "net/http" - "os" - "path" - "sync" - "time" -) - -type _escLocalFS struct{} - -var _escLocal _escLocalFS - -type _escStaticFS struct{} - -var _escStatic _escStaticFS - -type _escDirectory struct { - fs http.FileSystem - name string -} - -type _escFile struct { - compressed string - size int64 - modtime int64 - local string - isDir bool - - once sync.Once - data []byte - name string -} - -func (_escLocalFS) Open(name string) (http.File, error) { - f, present := _escData[path.Clean(name)] - if !present { - return nil, os.ErrNotExist - } - return os.Open(f.local) -} - -func (_escStaticFS) prepare(name string) (*_escFile, error) { - f, present := _escData[path.Clean(name)] - if !present { - return nil, os.ErrNotExist - } - var err error - f.once.Do(func() { - f.name = path.Base(name) - if f.size == 0 { - return - } - var gr *gzip.Reader - b64 := base64.NewDecoder(base64.StdEncoding, bytes.NewBufferString(f.compressed)) - gr, err = gzip.NewReader(b64) - if err != nil { - return - } - f.data, err = ioutil.ReadAll(gr) - }) - if err != nil { - return nil, err - } - return f, nil -} - -func (fs _escStaticFS) Open(name string) (http.File, error) { - f, err := fs.prepare(name) - if err != nil { - return nil, err - } - return f.File() -} - -func (dir _escDirectory) Open(name string) (http.File, error) { - return dir.fs.Open(dir.name + name) -} - -func (f *_escFile) File() (http.File, error) { - type httpFile struct { - *bytes.Reader - *_escFile - } - return &httpFile{ - Reader: bytes.NewReader(f.data), - _escFile: f, - }, nil -} - -func (f *_escFile) Close() error { - return nil -} - -func (f *_escFile) Readdir(count int) ([]os.FileInfo, error) { - if !f.isDir { - return nil, fmt.Errorf(" escFile.Readdir: '%s' is not directory", f.name) - } - - fis, ok := _escDirs[f.local] - if !ok { - return nil, fmt.Errorf(" escFile.Readdir: '%s' is directory, but we have no info about content of this dir, local=%s", f.name, f.local) - } - limit := count - if count <= 0 || limit > len(fis) { - limit = len(fis) - } - - if len(fis) == 0 && count > 0 { - return nil, io.EOF - } - - return fis[0:limit], nil -} - -func (f *_escFile) Stat() (os.FileInfo, error) { - return f, nil -} - -func (f *_escFile) Name() string { - return f.name -} - -func (f *_escFile) Size() int64 { - return f.size -} - -func (f *_escFile) Mode() os.FileMode { - return 0 -} - -func (f *_escFile) ModTime() time.Time { - return time.Unix(f.modtime, 0) -} - -func (f *_escFile) IsDir() bool { - return f.isDir -} - -func (f *_escFile) Sys() interface{} { - return f -} - -// _escFS returns a http.Filesystem for the embedded assets. If useLocal is true, -// the filesystem's contents are instead used. -func _escFS(useLocal bool) http.FileSystem { - if useLocal { - return _escLocal - } - return _escStatic -} - -// _escDir returns a http.Filesystem for the embedded assets on a given prefix dir. -// If useLocal is true, the filesystem's contents are instead used. -func _escDir(useLocal bool, name string) http.FileSystem { - if useLocal { - return _escDirectory{fs: _escLocal, name: name} - } - return _escDirectory{fs: _escStatic, name: name} -} - -// _escFSByte returns the named file from the embedded assets. If useLocal is -// true, the filesystem's contents are instead used. -func _escFSByte(useLocal bool, name string) ([]byte, error) { - if useLocal { - f, err := _escLocal.Open(name) - if err != nil { - return nil, err - } - b, err := ioutil.ReadAll(f) - _ = f.Close() - return b, err - } - f, err := _escStatic.prepare(name) - if err != nil { - return nil, err - } - return f.data, nil -} - -// _escFSMustByte is the same as _escFSByte, but panics if name is not present. -func _escFSMustByte(useLocal bool, name string) []byte { - b, err := _escFSByte(useLocal, name) - if err != nil { - panic(err) - } - return b -} - -// _escFSString is the string version of _escFSByte. -func _escFSString(useLocal bool, name string) (string, error) { - b, err := _escFSByte(useLocal, name) - return string(b), err -} - -// _escFSMustString is the string version of _escFSMustByte. -func _escFSMustString(useLocal bool, name string) string { - return string(_escFSMustByte(useLocal, name)) -} - -var _escData = map[string]*_escFile{ - - "/helpers.js": { - name: "helpers.js", - local: "pkg/js/helpers.js", - size: 33075, - modtime: 0, - compressed: ` -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 -/6TRG/0zgQAA -`, - }, -} - -var _escDirs = map[string][]os.FileInfo{}