aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md7
-rw-r--r--Dockerfile.scratch1
-rw-r--r--Makefile7
-rw-r--r--bindata.go258
-rw-r--r--go.mod1
-rw-r--r--go.sum3
-rw-r--r--handler.go17
-rw-r--r--handler_test.go22
-rw-r--r--tools.go1
9 files changed, 293 insertions, 24 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4786b15..32aa730 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## [Unreleased]
+### Fixed
+- Templates are now bundled with the binary rather than requiring a copy of the
+ sally source.
+
## 1.0.0 - 2019-01-03
- Initial tagged release.
+
+[Unreleased]: https://github.com/uber-go/sally/compare/v1.0.0...HEAD
diff --git a/Dockerfile.scratch b/Dockerfile.scratch
index f6cf130..f78f304 100644
--- a/Dockerfile.scratch
+++ b/Dockerfile.scratch
@@ -3,5 +3,4 @@ FROM scratch
EXPOSE 8080
ADD sally.yaml /
ADD _tmp/sally /
-ADD templates /templates
ENTRYPOINT ["/sally"]
diff --git a/Makefile b/Makefile
index 7c25a34..efa0d0a 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,6 @@
GOLINT = go run github.com/golang/lint/golint
STATICCHECK = go run honnef.co/go/tools/cmd/staticcheck
+GOBINDATA = go run github.com/go-bindata/go-bindata/go-bindata
.PHONY: all
all: test
@@ -8,6 +9,12 @@ all: test
build:
go build
+.PHONY: generate
+generate: bindata.go
+
+bindata.go: templates/*
+ $(GOBINDATA) templates
+
.PHONY: install
install:
go install .
diff --git a/bindata.go b/bindata.go
new file mode 100644
index 0000000..a2b1492
--- /dev/null
+++ b/bindata.go
@@ -0,0 +1,258 @@
+// Code generated by go-bindata. DO NOT EDIT.
+// sources:
+// templates/index.html
+// templates/package.html
+package main
+
+import (
+ "bytes"
+ "compress/gzip"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "strings"
+ "time"
+)
+
+func bindataRead(data []byte, name string) ([]byte, error) {
+ gz, err := gzip.NewReader(bytes.NewBuffer(data))
+ if err != nil {
+ return nil, fmt.Errorf("Read %q: %v", name, err)
+ }
+
+ var buf bytes.Buffer
+ _, err = io.Copy(&buf, gz)
+ clErr := gz.Close()
+
+ if err != nil {
+ return nil, fmt.Errorf("Read %q: %v", name, err)
+ }
+ if clErr != nil {
+ return nil, err
+ }
+
+ return buf.Bytes(), nil
+}
+
+type asset struct {
+ bytes []byte
+ info os.FileInfo
+}
+
+type bindataFileInfo struct {
+ name string
+ size int64
+ mode os.FileMode
+ modTime time.Time
+}
+
+func (fi bindataFileInfo) Name() string {
+ return fi.name
+}
+func (fi bindataFileInfo) Size() int64 {
+ return fi.size
+}
+func (fi bindataFileInfo) Mode() os.FileMode {
+ return fi.mode
+}
+func (fi bindataFileInfo) ModTime() time.Time {
+ return fi.modTime
+}
+func (fi bindataFileInfo) IsDir() bool {
+ return false
+}
+func (fi bindataFileInfo) Sys() interface{} {
+ return nil
+}
+
+var _templatesIndexHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xac\x54\x3f\x6f\xdb\x3e\x10\xdd\x7f\x9f\xe2\x7e\x84\xb3\x35\xbc\xa2\xe8\x14\xd0\xee\x50\x17\x5d\x0a\xd4\x48\xdb\xa1\x23\x4d\x9e\x25\xc6\x14\x69\x90\x27\xa5\x46\xa0\xef\x5e\x58\x72\xe2\x44\xae\xe4\x00\xad\x16\x89\xba\xf7\xde\xfd\xe5\xa9\xff\x97\x5f\x3f\x7e\xff\xb9\xfa\x04\x25\x57\x7e\xf1\x9f\xea\x5f\x00\x00\xaa\x24\x6d\xfb\xcf\xee\xe8\x5d\xd8\x42\x22\x3f\x17\x99\xf7\x9e\x72\x49\xc4\x02\xca\x44\x9b\xb9\x28\x99\x77\xf9\x06\xd1\xd8\x70\x97\xa5\xf1\xb1\xb6\x1b\xaf\x13\x49\x13\x2b\xd4\x77\xfa\x17\x7a\xb7\xce\x98\xb7\xe4\x89\x63\xc0\x77\xf2\xad\x7c\xff\x74\x94\x95\x0b\xd2\xe4\x2c\x00\x8f\xae\xf1\xe4\x5b\xad\xa3\xdd\x3f\x0b\xc3\xba\x06\x8c\xd7\x39\xcf\x85\x89\x81\xb5\x0b\x94\xc4\xc9\x3e\xc4\xa4\x78\x3f\xb0\x76\x08\xd6\x6b\x4f\x8f\x98\xfa\x7a\x53\x7b\x7f\x7d\xef\x2c\x97\x7f\x00\xf7\x84\x97\xd5\x38\xb7\xa7\x71\xe3\x51\x60\xb1\xd2\x66\xab\x0b\x52\xc8\xe5\x65\xf0\xb7\x58\x27\xf3\x4a\xec\x32\x9a\xba\xa2\xc0\x9a\x5d\x0c\xd3\x14\x85\x63\x91\x1e\x78\xa3\x39\x2a\x7e\xd9\x86\xe1\xf3\xf0\x00\x49\x87\x82\x60\xb6\xa5\xfd\x1b\x98\x35\xda\xd7\x04\x37\x73\x90\xc7\xa4\x33\xb4\xed\x14\x7b\xe6\xaa\x5d\x4c\xbc\xd2\x5c\x1e\x68\xbb\xe4\x02\x6f\x40\x5c\x35\x78\xd5\x08\x98\xc9\x1f\xb7\x5f\x3a\xed\x29\x99\x57\x34\xc1\x2e\x06\xbe\xda\x56\x21\x4f\x34\xf6\x91\x36\x09\xe8\x40\xfa\x78\x17\x10\x0f\x2e\xba\x02\xc8\x5b\xda\x45\x68\x5b\xb1\x38\xfb\xa5\x50\x5f\x70\xfa\xcf\xc3\x2a\xa2\x8d\x46\xc6\x54\xe0\x59\x0d\x46\xa6\xfe\x4c\xcc\x55\x05\xe4\x64\x2e\xa8\x7d\xc8\xac\xb9\xce\x32\x37\x85\x00\xed\x79\x2e\x3e\xc7\x65\x34\x4f\xd7\x7b\x3a\xed\xbf\xaa\xcb\xf8\x78\x43\x3f\x67\x14\xec\xd8\x08\x29\x1c\x19\x72\x85\xdd\xba\x18\x2c\x19\xb4\xae\x79\xb6\x97\x4e\x47\x85\xbd\x8c\xc2\x7e\x99\xfe\x0e\x00\x00\xff\xff\xb1\x54\x5d\xd8\x64\x05\x00\x00")
+
+func templatesIndexHtmlBytes() ([]byte, error) {
+ return bindataRead(
+ _templatesIndexHtml,
+ "templates/index.html",
+ )
+}
+
+func templatesIndexHtml() (*asset, error) {
+ bytes, err := templatesIndexHtmlBytes()
+ if err != nil {
+ return nil, err
+ }
+
+ info := bindataFileInfo{name: "templates/index.html", size: 1380, mode: os.FileMode(420), modTime: time.Unix(1546544917, 0)}
+ a := &asset{bytes: bytes, info: info}
+ return a, nil
+}
+
+var _templatesPackageHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\xd1\x3f\x4f\xf3\x30\x10\x06\xf0\xfd\xfd\x14\xf7\x86\xb9\x35\x33\x38\x5d\x0a\x62\xa9\xa0\xaa\x60\x60\x34\xc9\xd3\xd8\x92\xed\x0b\xf6\xa5\x12\x8a\xf2\xdd\x51\x70\xa5\x82\x28\x82\xc9\x7f\xf5\xbb\x47\x77\xfa\xff\xcd\xc3\xfa\xf1\x79\x7b\x4b\x56\x82\x5f\xfd\xd3\x65\x21\x22\xd2\x16\xa6\x2d\xdb\x8f\x63\x80\x18\x8a\x26\xa0\xae\x3a\x5e\xb8\xd0\x73\x92\x8a\x1a\x8e\x82\x28\x75\x35\x8e\xb4\x5c\x9b\xc8\xd1\x35\xc6\x3f\xed\x36\x34\x4d\xd4\x39\x21\x2b\xd2\xe7\x2b\xa5\xe6\xf7\x1d\x7a\xa6\x69\xaa\x7e\x54\x33\x0f\xa9\xc1\x2f\xea\x19\xf1\xdc\x9d\x92\x04\xa8\x60\xb2\x20\x8d\xaa\x75\xe9\x8f\xbf\xd4\xb8\x77\x1e\xd3\xc5\x66\xf4\x2e\xe2\x7b\xd8\x19\x59\xe0\x75\x70\x87\xba\x4a\xd8\x27\x64\xfb\x29\xf0\xe5\x35\x0d\xc9\xd7\x73\x85\x3b\x6e\xb9\x29\x99\x8f\x88\x56\xa7\x9e\xea\x17\x6e\xdf\x4e\xf6\x3d\x8b\x75\xb1\x23\x61\xca\x00\x59\x24\x2c\x69\xeb\x61\x32\x48\x1b\xb2\x09\xfb\xd2\x8d\x2f\x6a\xe0\x03\xc8\x78\x8e\x9d\x56\x66\xb5\x3c\x16\x29\xb2\x56\x65\x96\xef\x01\x00\x00\xff\xff\x69\xc7\x6b\xa3\xe3\x01\x00\x00")
+
+func templatesPackageHtmlBytes() ([]byte, error) {
+ return bindataRead(
+ _templatesPackageHtml,
+ "templates/package.html",
+ )
+}
+
+func templatesPackageHtml() (*asset, error) {
+ bytes, err := templatesPackageHtmlBytes()
+ if err != nil {
+ return nil, err
+ }
+
+ info := bindataFileInfo{name: "templates/package.html", size: 483, mode: os.FileMode(420), modTime: time.Unix(1546544917, 0)}
+ a := &asset{bytes: bytes, info: info}
+ return a, nil
+}
+
+// Asset loads and returns the asset for the given name.
+// It returns an error if the asset could not be found or
+// could not be loaded.
+func Asset(name string) ([]byte, error) {
+ cannonicalName := strings.Replace(name, "\\", "/", -1)
+ if f, ok := _bindata[cannonicalName]; ok {
+ a, err := f()
+ if err != nil {
+ return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err)
+ }
+ return a.bytes, nil
+ }
+ return nil, fmt.Errorf("Asset %s not found", name)
+}
+
+// MustAsset is like Asset but panics when Asset would return an error.
+// It simplifies safe initialization of global variables.
+func MustAsset(name string) []byte {
+ a, err := Asset(name)
+ if err != nil {
+ panic("asset: Asset(" + name + "): " + err.Error())
+ }
+
+ return a
+}
+
+// AssetInfo loads and returns the asset info for the given name.
+// It returns an error if the asset could not be found or
+// could not be loaded.
+func AssetInfo(name string) (os.FileInfo, error) {
+ cannonicalName := strings.Replace(name, "\\", "/", -1)
+ if f, ok := _bindata[cannonicalName]; ok {
+ a, err := f()
+ if err != nil {
+ return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err)
+ }
+ return a.info, nil
+ }
+ return nil, fmt.Errorf("AssetInfo %s not found", name)
+}
+
+// AssetNames returns the names of the assets.
+func AssetNames() []string {
+ names := make([]string, 0, len(_bindata))
+ for name := range _bindata {
+ names = append(names, name)
+ }
+ return names
+}
+
+// _bindata is a table, holding each asset generator, mapped to its name.
+var _bindata = map[string]func() (*asset, error){
+ "templates/index.html": templatesIndexHtml,
+ "templates/package.html": templatesPackageHtml,
+}
+
+// AssetDir returns the file names below a certain
+// directory embedded in the file by go-bindata.
+// For example if you run go-bindata on data/... and data contains the
+// following hierarchy:
+// data/
+// foo.txt
+// img/
+// a.png
+// b.png
+// then AssetDir("data") would return []string{"foo.txt", "img"}
+// AssetDir("data/img") would return []string{"a.png", "b.png"}
+// AssetDir("foo.txt") and AssetDir("notexist") would return an error
+// AssetDir("") will return []string{"data"}.
+func AssetDir(name string) ([]string, error) {
+ node := _bintree
+ if len(name) != 0 {
+ cannonicalName := strings.Replace(name, "\\", "/", -1)
+ pathList := strings.Split(cannonicalName, "/")
+ for _, p := range pathList {
+ node = node.Children[p]
+ if node == nil {
+ return nil, fmt.Errorf("Asset %s not found", name)
+ }
+ }
+ }
+ if node.Func != nil {
+ return nil, fmt.Errorf("Asset %s not found", name)
+ }
+ rv := make([]string, 0, len(node.Children))
+ for childName := range node.Children {
+ rv = append(rv, childName)
+ }
+ return rv, nil
+}
+
+type bintree struct {
+ Func func() (*asset, error)
+ Children map[string]*bintree
+}
+var _bintree = &bintree{nil, map[string]*bintree{
+ "templates": &bintree{nil, map[string]*bintree{
+ "index.html": &bintree{templatesIndexHtml, map[string]*bintree{}},
+ "package.html": &bintree{templatesPackageHtml, map[string]*bintree{}},
+ }},
+}}
+
+// RestoreAsset restores an asset under the given directory
+func RestoreAsset(dir, name string) error {
+ data, err := Asset(name)
+ if err != nil {
+ return err
+ }
+ info, err := AssetInfo(name)
+ if err != nil {
+ return err
+ }
+ err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755))
+ if err != nil {
+ return err
+ }
+ err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode())
+ if err != nil {
+ return err
+ }
+ err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime())
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+// RestoreAssets restores an asset under the given directory recursively
+func RestoreAssets(dir, name string) error {
+ children, err := AssetDir(name)
+ // File
+ if err != nil {
+ return RestoreAsset(dir, name)
+ }
+ // Dir
+ for _, child := range children {
+ err = RestoreAssets(dir, filepath.Join(name, child))
+ if err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func _filePath(dir, name string) string {
+ cannonicalName := strings.Replace(name, "\\", "/", -1)
+ return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
+}
+
diff --git a/go.mod b/go.mod
index 86ea6f5..06701c8 100644
--- a/go.mod
+++ b/go.mod
@@ -2,6 +2,7 @@ module go.uber.org/sally
require (
github.com/davecgh/go-spew v1.1.1 // indirect
+ github.com/go-bindata/go-bindata v1.0.0
github.com/golang/lint v0.0.0-20181217174547-8f45f776aaf1
github.com/julienschmidt/httprouter v1.2.0
github.com/kisielk/gotool v1.0.0 // indirect
diff --git a/go.sum b/go.sum
index a011e9b..722d79e 100644
--- a/go.sum
+++ b/go.sum
@@ -1,5 +1,7 @@
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/go-bindata/go-bindata v1.0.0 h1:upAQEGKG3hFv00/4cU/VhzF+NpCHz+Jk3rO946wWr+A=
+github.com/go-bindata/go-bindata v1.0.0/go.mod h1:xK8Dsgwmeed+BBsSy2XTopBn/8uK2HWuGSnA11C3Joo=
github.com/golang/lint v0.0.0-20181217174547-8f45f776aaf1 h1:6DVPu65tee05kY0/rciBQ47ue+AnuY8KTayV6VHikIo=
github.com/golang/lint v0.0.0-20181217174547-8f45f776aaf1/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
github.com/julienschmidt/httprouter v1.2.0 h1:TDTW5Yz1mjftljbcKqRcrYhd4XeOoI98t+9HbQbYf7g=
@@ -11,6 +13,7 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
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=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
diff --git a/handler.go b/handler.go
index 0c95b43..4c409fb 100644
--- a/handler.go
+++ b/handler.go
@@ -8,17 +8,12 @@ import (
"github.com/julienschmidt/httprouter"
)
-var indexTemplate, packageTemplate *template.Template
-
-func init() {
- tmpls := template.Must(template.ParseGlob("templates/*.html"))
- if indexTemplate = tmpls.Lookup("index.html"); indexTemplate == nil {
- panic("Missing index.html template")
- }
- if packageTemplate = tmpls.Lookup("package.html"); packageTemplate == nil {
- panic("Missing package.html template")
- }
-}
+var (
+ indexTemplate = template.Must(
+ template.New("index.html").Parse(string(MustAsset("templates/index.html"))))
+ packageTemplate = template.Must(
+ template.New("package.html").Parse(string(MustAsset("templates/package.html"))))
+)
// CreateHandler creates a Sally http.Handler
func CreateHandler(config *Config) http.Handler {
diff --git a/handler_test.go b/handler_test.go
index ce5e290..ab8cd67 100644
--- a/handler_test.go
+++ b/handler_test.go
@@ -1,6 +1,10 @@
package main
-import "testing"
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
var config = `
@@ -15,17 +19,11 @@ packages:
func TestIndex(t *testing.T) {
rr := CallAndRecord(t, config, "/")
- AssertResponse(t, rr, 200, `
-<!DOCTYPE html>
-<html>
- <body>
- <ul>
- <li>thriftrw - github.com/thriftrw/thriftrw-go</li>
- <li>yarpc - github.com/yarpc/yarpc-go</li>
- </ul>
- </body>
-</html>
-`)
+ assert.Equal(t, 200, rr.Code)
+
+ body := rr.Body.String()
+ assert.Contains(t, body, "github.com/thriftrw/thriftrw-go")
+ assert.Contains(t, body, "github.com/yarpc/yarpc-go")
}
func TestPackageShouldExist(t *testing.T) {
diff --git a/tools.go b/tools.go
index d2af1bd..23aa5b2 100644
--- a/tools.go
+++ b/tools.go
@@ -3,6 +3,7 @@
package main
import (
+ _ "github.com/go-bindata/go-bindata/go-bindata"
_ "github.com/golang/lint/golint"
_ "honnef.co/go/tools/cmd/staticcheck"
)