Build scripts for generate / travis validation

This commit is contained in:
Craig Peterson 2017-01-12 07:20:37 -07:00
parent 7ba051d750
commit 7942a49953
8 changed files with 551 additions and 18 deletions

18
build/generate.go Normal file
View file

@ -0,0 +1,18 @@
package main
import (
"github.com/mjibson/esc/embed"
)
func main() {
//go:generate esc -modtime 0 -o js/static.go -pkg js -include helpers\.js -ignore go -prefix js js
conf := &embed.Config{
ModTime: "0",
OutputFile: "js/static.go",
Package: "js",
Prefix: "js",
Private: true,
Files: []string{`js/helpers.js`},
}
embed.Run(conf)
}

84
build/validate.go Normal file
View file

@ -0,0 +1,84 @@
package main
import (
"fmt"
"os"
"os/exec"
"strings"
)
var status = ""
func appendErrorStatus(s string) {
if status != "" {
status += ", "
}
status += s
}
func main() {
if err := checkGoFmt(); err != nil {
fmt.Println(err)
appendErrorStatus("needs gofmt")
}
if err := checkGoGenerate(); err != nil {
fmt.Println(err)
appendErrorStatus("needs go generate")
}
}
func checkGoFmt() error {
cmd := exec.Command("gofmt", "-s", "-l", ".")
out, err := cmd.CombinedOutput()
if err != nil {
return err
}
if len(out) == 0 {
return nil
}
files := strings.Split(string(out), "\n")
fList := ""
for _, f := range files {
if strings.HasPrefix(f, "vendor") {
continue
}
if fList != "" {
fList += "\n"
}
fList += f
}
if fList == "" {
return nil
}
return fmt.Errorf("ERROR: The following files need to have gofmt run on them:\n%s", fList)
}
func checkGoGenerate() error {
cmd := exec.Command("go", "generate")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err := cmd.Run()
if err != nil {
return err
}
modified, err := getModifiedFiles()
if err != nil {
return err
}
if len(modified) != 0 {
return fmt.Errorf("ERROR: The following files were modified by go generate:\n%s", strings.Join(modified, "\n"))
}
return nil
}
func getModifiedFiles() ([]string, error) {
cmd := exec.Command("git", strings.Split("diff --name-only", " ")...)
out, err := cmd.CombinedOutput()
if err != nil {
return nil, err
}
if len(out) == 0 {
return nil, nil
}
return strings.Split(string(out), "\n"), nil
}

View file

@ -16,7 +16,7 @@ func ExecuteJavascript(script string, devMode bool) (*models.DNSConfig, error) {
helperJs := GetHelpers(devMode)
// run helper script to prime vm and initialize variables
if _, err := vm.Run(string(helperJs)); err != nil {
if _, err := vm.Run(helperJs); err != nil {
return nil, err
}

View file

@ -129,27 +129,27 @@ func (f *_escFile) Sys() interface{} {
return f
}
// FS returns a http.Filesystem for the embedded assets. If useLocal is true,
// _escFS returns a http.Filesystem for the embedded assets. If useLocal is true,
// the filesystem's contents are instead used.
func FS(useLocal bool) http.FileSystem {
func _escFS(useLocal bool) http.FileSystem {
if useLocal {
return _escLocal
}
return _escStatic
}
// Dir returns a http.Filesystem for the embedded assets on a given prefix dir.
// _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 Dir(useLocal bool, name string) http.FileSystem {
func _escDir(useLocal bool, name string) http.FileSystem {
if useLocal {
return _escDirectory{fs: _escLocal, name: name}
}
return _escDirectory{fs: _escStatic, name: name}
}
// FSByte returns the named file from the embedded assets. If useLocal is
// _escFSByte returns the named file from the embedded assets. If useLocal is
// true, the filesystem's contents are instead used.
func FSByte(useLocal bool, name string) ([]byte, error) {
func _escFSByte(useLocal bool, name string) ([]byte, error) {
if useLocal {
f, err := _escLocal.Open(name)
if err != nil {
@ -166,24 +166,24 @@ func FSByte(useLocal bool, name string) ([]byte, error) {
return f.data, nil
}
// FSMustByte is the same as FSByte, but panics if name is not present.
func FSMustByte(useLocal bool, name string) []byte {
b, err := FSByte(useLocal, name)
// _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
}
// FSString is the string version of FSByte.
func FSString(useLocal bool, name string) (string, error) {
b, err := FSByte(useLocal, name)
// _escFSString is the string version of _escFSByte.
func _escFSString(useLocal bool, name string) (string, error) {
b, err := _escFSByte(useLocal, name)
return string(b), err
}
// FSMustString is the string version of FSMustByte.
func FSMustString(useLocal bool, name string) string {
return string(FSMustByte(useLocal, name))
// _escFSMustString is the string version of _escFSMustByte.
func _escFSMustString(useLocal bool, name string) string {
return string(_escFSMustByte(useLocal, name))
}
var _escData = map[string]*_escFile{
@ -193,7 +193,7 @@ var _escData = map[string]*_escFile{
size: 7196,
modtime: 0,
compressed: `
H4sIAAAAAAAA/7RZfU/jzBH/P59iaqkXu/gc4A5aOU+qpgc8OpUEBKFFiiK02JtkOdtr7a6TUhQ+e7Uv
H4sIAAAJbogA/7RZfU/jzBH/P59iaqkXu/gc4A5aOU+qpgc8OpUEBKFFiiK02JtkOdtr7a6TUhQ+e7Uv
ttdxcoD0HH+E2Dsvv3nZ2dmJU3AMXDASCaff6awQg4hmcxjASwcAgOEF4YIhxkOYznz1Ls74Q87oisS4
8ZqmiGTqRWdjZMV4jopEDNmCwwCms36nMy+ySBCaAcmIICgh/8Oup5U1NO/T/hME2yjk86avwbWAbCwo
Y7y+KVW5GUqxL55z7KdYIM/AIXNw5UuvgiefYDAAZzQc3w0vHa1ooz6l7QwvpDFSXAhKqGIJ1acPUnio

View file

@ -30,7 +30,7 @@ import (
_ "github.com/StackExchange/dnscontrol/providers/route53"
)
//go:generate esc -modtime 0 -o js/static.go -pkg js -include helpers\.js -ignore go -prefix js js
//go:generate go run build/generate.go
// One of these config options must be set.
var jsFile = flag.String("js", "dnsconfig.js", "Javascript file containing dns config")

20
vendor/github.com/mjibson/esc/LICENSE generated vendored Normal file
View file

@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2014 Matt Jibson
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

405
vendor/github.com/mjibson/esc/embed/embed.go generated vendored Normal file
View file

@ -0,0 +1,405 @@
//Package embed implements all file embedding logic for github.com/mjibson/esc
package embed
import (
"bytes"
"compress/gzip"
"encoding/base64"
"fmt"
"io/ioutil"
"log"
"os"
"path"
"path/filepath"
"regexp"
"sort"
"strconv"
"strings"
"text/template"
)
//Config contains all information needed to run esc
type Config struct {
//Output file, else stdout
OutputFile string
//Package declaration for generated file
Package string
//Prefix to strip from filenames
Prefix string
//Regexp for files we should ignore (for example \\\\.DS_Store)
Ignore string
//Regexp for files to include. If provided, only files that match will be included
Include string
//Unix timestamp to override as modification time for all files
ModTime string
//If true, do not export autogenerated functions
Private bool
//List of files or directories to embed
Files []string
}
var modTime *int64
type headerTemplateParams struct {
PackageName string
FunctionPrefix string
}
type _escFile struct {
data []byte
local string
fileinfo os.FileInfo
}
func Run(conf *Config) {
var err error
if conf.ModTime != "" {
i, err := strconv.ParseInt(conf.ModTime, 10, 64)
if err != nil {
log.Fatalf("modtime must be an integer: %v", err)
}
modTime = &i
}
var fnames, dirnames []string
content := make(map[string]_escFile)
prefix := filepath.ToSlash(conf.Prefix)
var ignoreRegexp *regexp.Regexp
if conf.Ignore != "" {
ignoreRegexp, err = regexp.Compile(conf.Ignore)
if err != nil {
log.Fatal(err)
}
}
var includeRegexp *regexp.Regexp
if conf.Include != "" {
includeRegexp, err = regexp.Compile(conf.Include)
if err != nil {
log.Fatal(err)
}
}
for _, base := range conf.Files {
files := []string{base}
for len(files) > 0 {
fname := files[0]
files = files[1:]
if ignoreRegexp != nil && ignoreRegexp.MatchString(fname) {
continue
}
f, err := os.Open(fname)
if err != nil {
log.Fatal(err)
}
fi, err := f.Stat()
if err != nil {
log.Fatal(err)
}
if fi.IsDir() {
fis, err := f.Readdir(0)
if err != nil {
log.Fatal(err)
}
for _, fi := range fis {
files = append(files, filepath.Join(fname, fi.Name()))
}
} else if includeRegexp == nil || includeRegexp.MatchString(fname) {
b, err := ioutil.ReadAll(f)
if err != nil {
log.Fatal(err)
}
fpath := filepath.ToSlash(fname)
n := strings.TrimPrefix(fpath, prefix)
n = path.Join("/", n)
content[n] = _escFile{data: b, local: fpath, fileinfo: fi}
fnames = append(fnames, n)
}
f.Close()
}
}
sort.Strings(fnames)
w := os.Stdout
if conf.OutputFile != "" {
if w, err = os.Create(conf.OutputFile); err != nil {
log.Fatal(err)
}
defer w.Close()
}
headerText, err := header(conf.Package, !(conf.Private))
if nil != err {
log.Fatalf("failed to expand autogenerated code: %s", err)
}
if _, err := w.Write(headerText); err != nil {
log.Fatalf("failed to write output: %s", err)
}
dirs := map[string]bool{"/": true}
for _, fname := range fnames {
f := content[fname]
for b := path.Dir(fname); b != "/"; b = path.Dir(b) {
dirs[b] = true
}
var buf bytes.Buffer
gw := gzip.NewWriter(&buf)
if _, err := gw.Write(f.data); err != nil {
log.Fatal(err)
}
if err := gw.Close(); err != nil {
log.Fatal(err)
}
t := f.fileinfo.ModTime().Unix()
if modTime != nil {
t = *modTime
}
fmt.Fprintf(w, `
%q: {
local: %q,
size: %v,
modtime: %v,
compressed: %s,
},%s`, fname, f.local, len(f.data), t, segment(&buf), "\n")
}
for d := range dirs {
dirnames = append(dirnames, d)
}
sort.Strings(dirnames)
for _, dir := range dirnames {
local := path.Join(prefix, dir)
if len(local) == 0 {
local = "."
}
fmt.Fprintf(w, `
%q: {
isDir: true,
local: %q,
},%s`, dir, local, "\n")
}
fmt.Fprint(w, footer)
}
func segment(s *bytes.Buffer) string {
var b bytes.Buffer
b64 := base64.NewEncoder(base64.StdEncoding, &b)
b64.Write(s.Bytes())
b64.Close()
res := "`\n"
chunk := make([]byte, 80)
for n, _ := b.Read(chunk); n > 0; n, _ = b.Read(chunk) {
res += string(chunk[0:n]) + "\n"
}
return res + "`"
}
func header(packageName string, enableExports bool) ([]byte, error) {
functionPrefix := ""
if !enableExports {
functionPrefix = "_esc"
}
headerParams := headerTemplateParams{
PackageName: packageName,
FunctionPrefix: functionPrefix,
}
tmpl, err := template.New("").Parse(headerTemplate)
if nil != err {
return nil, err
}
var b bytes.Buffer
err = tmpl.Execute(&b, headerParams)
if nil != err {
return nil, err
}
return b.Bytes(), nil
}
const (
headerTemplate = `package {{.PackageName}}
import (
"bytes"
"compress/gzip"
"encoding/base64"
"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) {
return nil, 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
}
// {{.FunctionPrefix}}FS returns a http.Filesystem for the embedded assets. If useLocal is true,
// the filesystem's contents are instead used.
func {{.FunctionPrefix}}FS(useLocal bool) http.FileSystem {
if useLocal {
return _escLocal
}
return _escStatic
}
// {{.FunctionPrefix}}Dir 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 {{.FunctionPrefix}}Dir(useLocal bool, name string) http.FileSystem {
if useLocal {
return _escDirectory{fs: _escLocal, name: name}
}
return _escDirectory{fs: _escStatic, name: name}
}
// {{.FunctionPrefix}}FSByte returns the named file from the embedded assets. If useLocal is
// true, the filesystem's contents are instead used.
func {{.FunctionPrefix}}FSByte(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
}
// {{.FunctionPrefix}}FSMustByte is the same as {{.FunctionPrefix}}FSByte, but panics if name is not present.
func {{.FunctionPrefix}}FSMustByte(useLocal bool, name string) []byte {
b, err := {{.FunctionPrefix}}FSByte(useLocal, name)
if err != nil {
panic(err)
}
return b
}
// {{.FunctionPrefix}}FSString is the string version of {{.FunctionPrefix}}FSByte.
func {{.FunctionPrefix}}FSString(useLocal bool, name string) (string, error) {
b, err := {{.FunctionPrefix}}FSByte(useLocal, name)
return string(b), err
}
// {{.FunctionPrefix}}FSMustString is the string version of {{.FunctionPrefix}}FSMustByte.
func {{.FunctionPrefix}}FSMustString(useLocal bool, name string) string {
return string({{.FunctionPrefix}}FSMustByte(useLocal, name))
}
var _escData = map[string]*_escFile{
`
footer = `}
`
)

6
vendor/vendor.json vendored
View file

@ -230,6 +230,12 @@
"revision": "db96a2b759cdef4f11a34506a42eb8d1290c598e",
"revisionTime": "2016-07-26T03:20:27Z"
},
{
"checksumSHA1": "x4C8qUa39JVIwhD+5nacBaQHcII=",
"path": "github.com/mjibson/esc/embed",
"revision": "703e8aee0a5417c480f8d6a3f072c9eb4f8904ea",
"revisionTime": "2017-01-12T13:50:19Z"
},
{
"checksumSHA1": "nS4kKHjMlJpQg3sixqelpCg1jyk=",
"path": "github.com/prasmussen/gandi-api/client",