1
0
Fork 0
mirror of https://github.com/Luzifer/share.git synced 2024-10-18 13:24:23 +00:00

Include frontend in binary, allow bootstrap

Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
Knut Ahlers 2017-12-02 19:37:29 +01:00
parent 8f80d158ca
commit b50097965c
Signed by: luzifer
GPG key ID: DC2729FDD34BE99E
3 changed files with 453 additions and 20 deletions

7
Makefile Normal file
View file

@ -0,0 +1,7 @@
default:
pack: generate
go-bindata frontend
generate:
coffee -c frontend/app.coffee

395
bindata.go Normal file
View file

@ -0,0 +1,395 @@
// Code generated by go-bindata. DO NOT EDIT.
// sources:
// frontend/app.coffee
// frontend/app.js
// frontend/index.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 fileInfoEx
}
type fileInfoEx interface {
os.FileInfo
MD5Checksum() string
}
type bindataFileInfo struct {
name string
size int64
mode os.FileMode
modTime time.Time
md5checksum string
}
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) MD5Checksum() string {
return fi.md5checksum
}
func (fi bindataFileInfo) IsDir() bool {
return false
}
func (fi bindataFileInfo) Sys() interface{} {
return nil
}
var _frontendAppCoffee = []byte(
"\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x84\x53\x4d\x4f\x1b\x31\x10\xbd\xfb\x57\xcc\x01\xc9\x59\x35\x71\x8a\xca" +
"\x09\x69\x2b\x55\xb0\x40\x24\x12\xaa\x10\x6e\x55\x91\x59\xcf\xae\xdd\x6e\xc6\x91\xed\x74\xc3\xbf\xaf\xec\xfd\x68" +
"\x52\xa8\x7a\xf3\xcc\xbc\x79\xf3\xf1\xc6\x95\x69\xf0\x69\x7d\x0f\x39\xec\x49\x61\x65\x08\x15\x63\xcb\xc7\xdb\xe7" +
"\xd5\xc3\xe6\xf9\xe6\xe1\x69\x75\x0d\x39\xf0\x1b\xd3\x20\x90\x0d\x50\xd9\x3d\x29\x3e\x02\xbe\x16\xeb\xe5\x62\xb3" +
"\x29\x12\x68\x65\x03\xc8\xa6\xb1\x2d\x2a\x08\x16\x64\x59\xa2\xf7\x10\x0b\x74\x09\xb7\xc5\xaa\x58\x2f\xae\x9e\x8b" +
"\xf5\x3a\xc2\x1f\xed\x16\x83\x36\x54\x43\x8b\x14\xa0\x75\x96\x6a\xce\xd8\x19\xcc\x3e\x33\x80\xb3\x49\x6b\x48\xd9" +
"\x36\x13\x2f\x86\x14\x70\x2d\xbd\x2e\xb5\xa4\x1a\xf9\x14\xa2\x71\x6f\xa5\x62\x30\x3e\x27\x19\x03\x00\x60\x83\x0d" +
"\x79\xc7\x13\xcb\x43\x0e\x1d\x99\x68\x6c\x29\x83\xb1\x24\x22\x4c\xf8\xfd\x8b\x0f\xce\x50\x3d\x39\x8f\xd9\xb8\x7d" +
"\x41\x15\x27\x5d\x50\x65\x27\x31\x31\x63\xec\xc4\x09\x39\x74\xfe\x8e\xdb\x54\x3d\x7d\x0e\x9c\xa7\xf2\x0e\xc3\xde" +
"\x11\x68\x49\xaa\xc1\xc2\x39\xeb\x96\xe8\xbd\xac\x11\x4e\x56\xca\xfa\xc6\xba\xc5\xc7\x57\x9c\x58\xc8\x1f\xf2\x90" +
"\xac\x69\x22\x8b\xeb\xb1\xea\x12\xf8\x5d\xf1\xe5\xba\xe3\xf7\xfb\xb4\xd4\xcb\xa1\x42\x6c\x2e\x05\x30\xd6\xba\x3c" +
"\x2e\xcc\xd8\x11\x26\x36\xae\x64\x90\x53\xf0\x41\x86\xbd\x9f\xc2\x41\xbb\x7e\x8a\xf0\xba\x8b\x1b\x3a\x68\x27\x6a" +
"\x0c\x6b\xf4\x3b\x4b\x1e\xef\x50\x2a\x74\xc0\xaf\x2c\x05\xa4\x30\xdb\xbc\xee\x90\xc7\xbe\x4b\x4b\xde\x36\x28\x1a" +
"\x5b\x0f\x33\xb0\xa4\x17\x17\x5e\xdb\x76\xd6\x58\xa9\x0c\xd5\x3c\x13\xda\x28\x4c\xb2\xc4\x58\x84\x36\x86\x7e\xce" +
"\xb4\xc3\x8a\x67\x42\x86\xe0\x80\x27\x63\x3a\xf2\xfc\x05\xf5\xae\x1c\x91\xf1\xfd\x1e\x90\xe4\x16\x79\x26\x02\x1e" +
"\xc2\x10\x3d\xd2\x75\xf0\x34\xd2\x87\x05\x29\x3c\x3c\x54\x13\x3e\xe7\x19\x7c\x80\xf3\x8c\x75\x12\xc6\xf9\xc5\x56" +
"\x86\x52\xc3\xfc\xbb\xd9\xca\x1a\xbf\xcd\xe7\x69\xa9\xe3\x4c\xc9\xcb\xb3\x64\xf4\x87\xd6\x29\xfd\x1e\xc5\x2f\xa3" +
"\xd0\xbe\xa1\x48\xde\x7f\x51\x8c\xa8\x1a\x09\x9d\x29\xff\xe0\xd8\x91\xa2\x51\xc4\x83\x76\x83\x86\xbd\x7c\xdb\xfe" +
"\xc0\x72\xf0\xad\x89\x1d\x44\x21\x3b\x44\xaa\xd2\x6a\x24\xb8\xf8\x78\x01\x21\x3e\x4e\xcf\xf0\x28\xfe\xe9\x34\x3e" +
"\x7e\xec\xee\xba\x1a\xdf\x5d\xf0\xd1\x17\x66\xe9\xf3\xbd\xb9\xf3\xbe\x9d\x93\xc6\x97\x63\x8b\x93\x3e\x9c\x0d\x9f" +
"\x9c\x8b\x74\xb9\x83\x82\x43\xf6\xff\xef\x29\xc5\x86\xdc\x7e\x59\xbf\x03\x00\x00\xff\xff\x1c\x3b\xdb\x6c\xcc\x04" +
"\x00\x00")
func frontendAppCoffeeBytes() ([]byte, error) {
return bindataRead(
_frontendAppCoffee,
"frontend/app.coffee",
)
}
func frontendAppCoffee() (*asset, error) {
bytes, err := frontendAppCoffeeBytes()
if err != nil {
return nil, err
}
info := bindataFileInfo{name: "frontend/app.coffee", size: 1228, md5checksum: "", mode: os.FileMode(436), modTime: time.Unix(1512238164, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
var _frontendAppJs = []byte(
"\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x54\x4d\x6f\x32\x37\x10\xbe\xf3\x2b\xe6\x10\xc9\x5e\x75\x63\x42\x9b" +
"\x13\x68\x0f\x55\x42\x12\xa4\x40\x2a\x42\x6e\x55\x23\xb3\x9e\xdd\x75\xbb\xd8\xc8\x36\x81\xa8\xe2\xbf\x57\xf6\x7e" +
"\xb0\x0b\x49\xdf\xf7\x66\xcf\xc7\x33\xf3\x78\x1e\xcf\x70\x08\x8f\xa8\xd0\x70\x87\x02\xd6\x9f\x70\xa7\xb3\x0c\xf1" +
"\x35\x35\x72\xeb\x60\xc4\x46\xbf\xb2\xdb\x01\xcd\x76\x2a\x75\x52\x2b\x1a\xc1\xbf\x03\x80\x0f\x6e\x60\xfe\xfa\xf8" +
"\xfe\x38\x5d\x4c\x97\xb3\xbb\xf7\xe9\x72\x19\x07\xc3\xe2\x65\xf5\xfe\xf0\xf2\xb6\xb8\x3f\x5d\xff\x98\x2e\xe7\xb3" +
"\xd5\x6a\x7a\x1f\x03\x6e\xd6\x28\x1e\x64\x89\x33\x95\xe9\x18\x32\x59\xe2\xdb\xf2\x39\x86\x82\x2b\x51\xe2\xd4\x7b" +
"\xdb\x8b\x31\xda\xf4\x2e\x73\xb4\x96\xe7\xe8\x6d\xb6\x78\xd6\x5c\x4c\x06\x03\x68\x30\x20\x81\x0f\x2d\x05\xdc\x04" +
"\x63\xaf\x13\x48\x80\xf8\x9a\xa0\xb4\x83\x4c\xef\x94\x20\xbd\xa0\xb6\x3f\x1f\xb8\xd0\x0e\x78\x59\xea\x3d\x0a\x70" +
"\x1a\x78\x9a\xa2\xb5\xa1\xc8\x29\xa9\x43\xda\xa7\xbc\xea\x0d\xba\x42\xaa\x1c\xf6\xa8\x1c\xec\x8d\x56\x79\x15\x7c" +
"\x75\xfe\x6c\xde\xb4\x97\x4a\xe8\x7d\xc4\xd6\x52\x09\x4a\x3c\x97\xb4\xe0\x2a\x47\x72\x22\x16\x4d\x42\xac\x41\xb7" +
"\x33\xaa\xb5\xd2\x60\x3e\x46\x01\xba\x31\x42\x02\x17\x35\xfc\x70\x7c\xc7\x15\x8a\x3f\x41\x02\x55\x59\x56\xea\x94" +
"\xfb\x60\xe6\x01\x98\xdd\xad\xad\x33\x52\xe5\x74\xd4\xaf\xd9\x1b\x14\xf5\x10\x55\xf1\x50\xbb\xe7\xec\x36\x10\xe2" +
"\xea\x26\x64\x06\xb4\x2a\x9d\x24\x40\x48\x63\xee\xb0\x3a\x1f\x2c\xed\x4d\xad\xee\xe7\xd8\x72\xa8\x86\x7c\xe2\x55" +
"\xe3\x5c\x31\xfe\x37\x3f\x84\x52\x71\x5b\xc3\x0f\x44\x8b\x31\x90\xa7\xe9\xef\xf7\x24\xae\xad\x76\x17\xa6\x39\xee" +
"\xc9\xad\xf6\xa1\x6f\x64\xdc\xed\xaa\x2a\xdf\xa1\xdd\xc9\xea\x92\x16\xdc\xf1\x18\xac\xe3\x6e\x67\x63\x38\x14\xa6" +
"\x3b\x06\xf7\xb9\xad\xdb\xf5\x27\x48\xbc\x9f\xe5\xe8\x96\x68\xb7\x5a\x59\x7c\x42\x2e\xd0\x50\x72\xa7\x95\x43\xe5" +
"\xae\x57\x9f\x5b\x24\x35\xf5\x54\x2b\xab\x4b\x64\xa5\xce\x69\xfd\x00\xb5\xe7\x8a\x12\x66\x0b\xbd\xbf\x2e\x35\x17" +
"\x52\xe5\x24\x62\x85\x14\x48\x3b\x6e\x9f\x50\x4a\xf5\xcf\x75\x61\x30\x23\x11\xe3\xce\x19\x4a\xc2\xa5\xfd\x77\x5f" +
"\x85\x5b\x93\xb6\xd1\xfe\xfc\x5d\xb0\xe2\x1b\x24\x11\x73\x78\x70\x4d\x73\x1d\x35\x35\x96\x92\x5b\x37\x53\x02\x0f" +
"\x2f\x19\x25\x43\x12\xc1\x2f\x30\x8a\x6a\x24\x2f\x10\xff\x28\x6c\xc3\x5d\x5a\xd0\xe1\x5f\x72\xc3\x73\xfc\x73\x38" +
"\x8c\x4e\x5a\x69\x89\x06\x1f\x89\xc2\xa5\xa1\xd9\x48\xa0\x2b\x94\x0b\xd0\x0f\x29\x50\x7f\x03\x1a\x7c\x3f\x01\xda" +
"\x28\xad\xc9\xcb\xfd\xb6\x94\x69\x2f\xb3\x27\x11\x2f\x9f\xae\x44\x0e\x85\x69\x14\xd2\x15\xc7\xa6\xd2\x7d\x55\xaa" +
"\xbe\x40\x02\x97\x4b\x03\xc0\xee\xa5\x4b\x0b\xf0\x48\xac\x0f\x14\x94\xc2\x2d\xc2\xed\xcd\xed\xb8\xb5\xb4\x4d\xf7" +
"\xfe\xd4\xe4\x3c\xe3\xb7\xff\xc9\x68\xd7\xe2\x29\x4b\x60\xc6\x77\xa5\xfb\x26\xa9\xb3\x16\x9b\x94\x63\xfd\x89\xe8" +
"\xf9\x46\xbb\xf8\xfb\x35\xfd\xaf\xdf\x72\xde\xbe\x4d\xfb\x34\x4d\x7c\xbb\x56\x09\x0b\x5f\xb8\xd1\x64\x17\xef\x87" +
"\x1f\xe6\x7c\xc0\x0d\x52\x7f\xbc\xc7\x88\xa5\xbc\x2c\xa9\x2b\xa4\x8d\x26\x83\xff\x02\x00\x00\xff\xff\x53\x89\x65" +
"\xf1\x37\x07\x00\x00")
func frontendAppJsBytes() ([]byte, error) {
return bindataRead(
_frontendAppJs,
"frontend/app.js",
)
}
func frontendAppJs() (*asset, error) {
bytes, err := frontendAppJsBytes()
if err != nil {
return nil, err
}
info := bindataFileInfo{name: "frontend/app.js", size: 1847, md5checksum: "", mode: os.FileMode(436), modTime: time.Unix(1512239484, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
var _frontendIndexHtml = []byte(
"\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xbc\x57\xeb\x53\xdb\x48\x12\xff\x9e\xbf\xa2\xa3\xfd\xb0\xbb\x49\x24\xf9" +
"\x01\x18\x13\xd9\x75\x04\x7c\x04\xc2\x23\x3c\x42\x80\xad\xfd\x30\xd2\xb4\xa4\x81\xd1\x8c\x32\x33\x92\x2d\xb6\xee" +
"\x7f\xbf\x1a\xc9\x32\x86\x65\x89\x73\xbb\x75\xa9\x4a\x99\x1e\xf5\xeb\xd7\xdd\xd3\xdd\x13\xbc\xde\x3d\xd9\xb9\xb8" +
"\xfe\x3c\x81\xd4\x64\x7c\xfc\x2a\xb0\x3f\xc0\x89\x48\x46\x0e\x0a\x67\xfc\x0a\x20\x48\x91\x50\xfb\x07\x40\x90\xa1" +
"\x21\x10\xa5\x44\x69\x34\x23\xa7\x30\xb1\xbb\xe9\x2c\x7f\x4a\x8d\xc9\x5d\xfc\x56\xb0\x72\xe4\x5c\xb9\x5f\xb6\xdd" +
"\x1d\x99\xe5\xc4\xb0\x90\xa3\x03\x91\x14\x06\x85\x19\x39\xfb\x93\x11\xd2\x04\x1f\x49\x0a\x92\xe1\xc8\x29\x19\x4e" +
"\x73\xa9\xcc\x12\xf3\x94\x51\x93\x8e\x28\x96\x2c\x42\xb7\x26\xde\x01\x13\xcc\x30\xc2\x5d\x1d\x11\x8e\xa3\x6e\xab" +
"\xe8\xb5\xeb\xc2\x45\x8a\x40\x42\x59\x22\xf4\xa1\x56\x6c\x48\xa2\xe1\x4d\x56\x68\xf3\x06\x22\x99\x21\xc4\x4c\x69" +
"\x03\x4c\x80\x49\x11\x2c\xb6\xf7\x40\x44\x05\xd2\xa4\xa8\x6a\xba\xb5\x0d\x56\xa8\x91\x79\x43\x62\x83\xea\x8d\x15" +
"\xd1\xd8\xa8\x74\xdd\xb9\x55\xc3\x0c\xc7\xf1\x79\x4a\x14\xc2\xbf\x80\x17\xf7\x2c\x46\xe5\x31\x19\xf8\xcd\x97\x57" +
"\x0f\xce\x7d\x90\xd2\x68\xa3\x48\xfe\x20\xcd\x99\xb8\x03\x85\x7c\xe4\x68\x53\x71\xd4\x29\xa2\x71\x20\x55\x18\x8f" +
"\x1c\x1b\x4d\xbd\xe5\xfb\x11\x15\xb7\xda\x8b\xb8\x2c\x68\xcc\x89\x42\x2f\x92\x99\x4f\x6e\xc9\xcc\xe7\x2c\xd4\xbe" +
"\x99\x32\x63\x50\xb9\x61\xab\xdd\xef\x7b\x7d\x6f\xe0\x47\x5a\xfb\x8b\x33\x2f\x63\xc2\x8b\xb4\x76\x6a\xb3\xcd\x3f" +
"\x26\x0c\x26\x8a\x99\x6a\xe4\xe8\x94\xf4\xd6\x37\xdc\x61\x77\x63\x12\x1e\x25\x83\xce\xd9\x69\x35\x3c\xfc\xc8\xf6" +
"\xee\xae\xee\xf7\x36\xd3\xf3\x64\x38\xa1\xc7\xd5\x70\xb0\x47\xee\x8f\xf7\x7c\xc2\xae\xbb\xd3\x91\x03\x91\x92\x5a" +
"\x4b\xc5\x12\x26\x46\x0e\x11\x52\x54\x99\x2c\xb4\x03\xfe\x3f\x87\xad\xf6\x7f\x4a\x4c\x94\xce\x41\x51\xa2\xee\x78" +
"\xf5\x0c\x2e\x78\x11\x98\x89\xc5\x10\x3f\x75\xf3\x83\xcd\x9d\x7b\x35\x9b\x5c\xfb\x57\xc3\xb5\xcd\xcb\xcf\x57\x43" +
"\x4d\x66\x51\x5f\x1f\xab\xfb\xb4\xfa\xb2\xbe\x7f\xf5\xf6\x3a\x79\x19\xd8\x3f\x86\x2c\x96\xc2\xb8\x64\x8a\x5a\x66" +
"\xe8\xaf\x79\x03\xaf\x53\x27\x6c\xf9\x78\xb5\x9c\xe1\x8d\x52\x07\xd1\x74\x37\xf2\xfb\xc5\x6e\xaa\xa9\xd9\xe8\xea" +
"\xc3\x9e\x3c\xf9\x70\xdd\xdf\xe8\x7d\x3b\xea\x73\x29\xba\x49\x35\x99\xdd\x1d\x76\x56\x81\x56\x03\x1a\xcf\x2d\xa6" +
"\x5d\xf8\x03\x0c\xce\x8c\x4b\x38\x4b\xc4\x16\x44\x28\x0c\xaa\xf7\x50\xbb\xa9\xd9\x3d\x6e\xc1\x60\x3d\x9f\xbd\x87" +
"\xff\xb4\x12\xbd\xef\x4b\xf4\xd6\x96\x25\x3c\x7b\xdd\x08\x13\xa8\xe0\x0f\xc8\x88\x4a\x98\x70\x8d\xcc\xb7\xa0\xdf" +
"\x79\xc4\xa6\x53\x39\x75\x13\x14\xa8\x58\xf4\x6e\x4e\xb2\x8c\x24\xd8\x12\x25\xa3\x28\x5b\x02\x95\x92\x56\x21\x65" +
"\x3a\xe7\xa4\xda\x02\x21\x05\xb6\xda\x02\x7f\x8e\xf2\xe1\x6a\x7e\xbc\x38\x3a\x5c\x07\x9d\xb2\x0c\x88\xa0\x70\x86" +
"\x3a\x97\x82\x7a\xb7\x1a\x62\xa9\x60\x7f\xb2\x09\xba\xc8\x6d\x6b\x02\x19\xcf\x99\x91\x63\x86\xc2\xe8\x5a\x20\x43" +
"\xca\x08\x7c\x2b\x50\x31\x5c\x6a\x0e\x56\xf5\xd7\xed\xb3\xe3\xfd\xe3\xbd\xad\x65\xa5\x54\xa2\x16\x3f\x1b\x98\x4a" +
"\x75\x07\x2c\x86\x4a\x16\x60\x9b\x5f\xdd\x94\x72\x92\x20\x94\x8c\x40\xcc\x38\x6e\xf9\xfe\x23\x75\xbf\xb1\x18\xb8" +
"\x81\xfd\x09\x0c\x7f\x6f\xd3\x14\xe8\x48\xb1\xdc\x80\x56\xd1\xca\xf5\x67\x1b\xfd\xba\x4e\x59\xe9\xf7\xbd\x81\xd7" +
"\x7f\xa0\xeb\xaa\xbb\x7d\x54\x74\xcf\x17\x5e\xff\xa0\xf2\xf7\xc2\xf3\x43\x95\x74\xe4\xb0\x5a\xbf\x59\x17\xdd\x62" +
"\xda\xf9\x36\xbb\x99\xec\x7c\x1c\xec\x6c\x9c\x9c\xe6\x97\x1f\x92\xe3\x7f\x5f\x93\xce\x0b\x77\x6a\x1c\xf8\x8d\xf3" +
"\x7f\x07\x8b\x5a\x04\xd6\xef\x7a\x6b\x5e\x6f\x71\xb0\x2a\x94\x64\x83\x6d\xc7\xe5\x4d\xfe\x56\xec\x9e\xf6\x2e\xe8" +
"\xc5\x99\x7f\x79\xf9\xe9\x20\xee\x87\x7b\x4a\xae\x15\xe1\x7a\x5c\x7e\x3d\xff\x7a\x79\xc6\x7a\xc7\x93\x95\xa1\x04" +
"\xaf\x7f\x43\x41\x59\xfc\x7b\x93\xbd\xc0\x6f\xe7\x68\x10\x4a\x5a\xcd\x79\x04\x29\x21\xe2\x44\xeb\x91\x23\x48\x19" +
"\x12\x05\xcd\x8f\x4b\x31\x26\x05\x37\xce\x22\x2c\x94\x2d\x38\x17\x17\xc6\x8d\x79\xc1\xe8\x82\xa7\x9d\x32\xca\x16" +
"\xa4\xfd\x6f\x64\x92\x70\x84\x04\x0d\x24\x4a\x16\x39\xd2\xba\x9a\x43\xb4\xf3\x02\x32\x19\x32\x8e\xed\x0d\x59\x14" +
"\xd9\x53\x6b\x73\x87\xac\xf7\xa8\x96\x6c\x59\x20\x85\x31\x52\x80\xa9\x72\x1c\x39\x0d\xe1\x3c\x11\x9b\xbb\x10\x49" +
"\xce\x49\xae\x91\x3a\x40\x89\x21\xf3\x63\x0b\xa5\x39\x6f\x8f\x89\x4a\xec\x66\xf1\x53\xa8\x5d\x9c\x91\x2c\xe7\xe8" +
"\xce\x15\xb5\x9c\x6e\xd7\x01\xa2\x18\x71\x71\x96\x13\x41\x91\x8e\x9c\x98\x70\x8d\x8f\x3c\xb3\x65\x94\x13\xd1\xfa" +
"\xa2\x95\x2b\x05\xaf\x9c\xf1\x45\xe3\x8d\x20\x25\x4b\x88\x61\x52\x04\xbe\xe5\x7b\x41\x94\x45\x52\xb8\x21\x51\x75" +
"\x76\xff\x2f\xac\x81\xdf\x44\xf2\xd1\x19\x79\x12\xd6\xd0\xe6\xb8\x9d\x38\x3f\x39\xe3\x80\xb5\x0c\x31\x81\x98\xb8" +
"\xda\xae\x23\xf3\x40\xa5\x8c\x52\x14\x23\xc7\xa8\x02\xad\x41\xb6\xac\xf9\xb9\xbd\x85\x2c\x15\x82\x4f\x59\x39\xef" +
"\x93\x2d\x55\x17\x99\xef\x3d\xa9\xc2\x87\x26\xe5\x0b\x52\x8e\x61\xde\x5b\x9f\x2b\x5b\xa8\x3b\x34\x97\x84\x32\x91" +
"\x3c\x54\x78\xda\x5d\xb2\xfb\x14\x4f\xce\x84\x95\x8c\x89\x9b\x17\x36\xdb\xdf\x81\x16\xf8\xad\xb6\x65\x04\x2f\x78" +
"\x33\x1f\x2c\xab\x79\x53\x37\x22\x97\xca\xa9\xb0\x20\x56\xf7\xc5\xaa\xed\x8d\x03\xb2\xc8\xdb\x42\x2d\xe3\x68\x77" +
"\x0a\xd7\x7e\xa8\xdb\xbe\xdd\x87\x9d\x71\x21\xea\x1d\x92\xda\x9c\x04\x7e\xda\xfb\x21\x48\xf5\x70\x7c\x00\xc4\xb2" +
"\xa4\x69\xaa\x0b\xab\x2c\x4b\xdc\xa6\x53\x6a\x56\x22\x2c\x9c\xd0\xaa\x8d\xc3\x8a\x96\xea\xc9\xfb\x6c\xab\xc2\x2c" +
"\x44\xba\x6c\xe4\xe9\x81\xdb\xdd\x08\xab\xe1\x72\x0b\xab\x95\xd5\x3b\xb8\x92\x5c\x3f\xba\x05\x5a\x16\x2a\xc2\x27" +
"\x28\x9e\x71\xbb\x71\xbd\x56\x34\x7e\x54\xba\x3f\x02\xaa\xde\x20\x56\xab\x07\x9c\x45\x9c\x64\x75\x43\x71\x23\xa6" +
"\x22\xfe\x03\xf5\x59\xd7\xc4\x22\x5c\x8d\xcd\xbf\x48\xb5\xbd\x77\xb7\xa7\x05\xaa\x0a\x7e\x11\x18\xa1\xd6\x44\x55" +
"\x75\x47\x5f\x3c\x2c\x7e\xd6\x70\x40\x4a\x72\xde\xcc\xd0\x9c\x17\x09\x13\xfa\xd7\x87\xbb\xf9\x3f\x0c\xd7\x5b\xbb" +
"\xd4\x54\x7e\xd7\xeb\xf6\xbc\xb5\x39\xf5\xec\x60\xfd\xf3\x58\xbd\x91\x7a\x12\x9e\x1d\x86\xc7\xa7\xf7\x87\xb9\xf8" +
"\xb4\x7f\x37\xa1\xea\x73\x39\xe0\x27\xd5\x70\xa7\x37\x48\x3f\x9e\xbe\xbd\xca\x37\xc9\xda\xd1\x6c\xfb\xf4\x07\xc6" +
"\xaa\xeb\xc2\xbe\x88\x78\x41\x11\x08\xe7\xf6\x81\x96\x33\x8e\xb4\x45\x0b\xbf\x84\xc8\xe5\xf4\xd7\x77\x20\x15\xb0" +
"\x39\x23\x13\x94\x95\x8c\x16\x84\xd7\x65\xae\x81\x68\x10\x88\x14\xe9\xdf\x8a\xcd\x5f\x3d\xbd\x6e\x9f\xbe\xbc\xbe" +
"\x1f\xab\x2f\xeb\x37\x13\xfc\x14\xef\x1d\x9f\xdc\x92\x4e\x67\x70\x74\xb4\xdb\xbf\xfe\xb0\xdf\xd9\xee\x9f\x9c\xdf" +
"\x9c\x9c\x86\xb8\xb7\x71\xdf\x8b\x7b\xd7\x9d\xb4\xd8\x5c\x29\x56\x7f\xc6\x44\xf2\xdc\xfa\xf1\x28\x9e\x81\xdf\x2c" +
"\x23\x81\xdf\xbc\xff\x5f\xfd\x37\x00\x00\xff\xff\x85\x7c\x46\x23\x11\x10\x00\x00")
func frontendIndexHtmlBytes() ([]byte, error) {
return bindataRead(
_frontendIndexHtml,
"frontend/index.html",
)
}
func frontendIndexHtml() (*asset, error) {
bytes, err := frontendIndexHtmlBytes()
if err != nil {
return nil, err
}
info := bindataFileInfo{name: "frontend/index.html", size: 4113, md5checksum: "", mode: os.FileMode(436), modTime: time.Unix(1512237987, 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, &os.PathError{Op: "open", Path: name, Err: os.ErrNotExist}
}
// MustAsset is like Asset but panics when Asset would return an error.
// It simplifies safe initialization of global variables.
// nolint: deadcode
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, &os.PathError{Op: "open", Path: name, Err: os.ErrNotExist}
}
// AssetNames returns the names of the assets.
// nolint: deadcode
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){
"frontend/app.coffee": frontendAppCoffee,
"frontend/app.js": frontendAppJs,
"frontend/index.html": frontendIndexHtml,
}
// 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, &os.PathError{Op: "open", Path: name, Err: os.ErrNotExist}
}
}
}
if node.Func != nil {
return nil, &os.PathError{Op: "open", Path: name, Err: os.ErrNotExist}
}
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{
"frontend": {nil, map[string]*bintree{
"app.coffee": {frontendAppCoffee, map[string]*bintree{}},
"app.js": {frontendAppJs, map[string]*bintree{}},
"index.html": {frontendIndexHtml, 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
}
return os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime())
}
// 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, "/")...)...)
}

71
main.go
View file

@ -1,9 +1,12 @@
package main
//go:generate make pack
import (
"bytes"
"crypto/sha1"
"fmt"
"io"
"io/ioutil"
"mime"
"os"
@ -19,8 +22,9 @@ import (
var (
cfg = struct {
BaseURL string `flag:"base-url" default:"" description:"URL to prepend before filename" validate:"nonzero"`
BaseURL string `flag:"base-url" default:"" description:"URL to prepend before filename"`
BasePath string `flag:"base-path" default:"file/{{ printf \"%.2s\" .Hash }}/{{.Hash}}" description:"Path to upload the file to"`
Bootstrap bool `flag:"bootstrap" default:"false" description:"Upload frontend files into bucket"`
Bucket string `flag:"bucket" default:"" description:"S3 bucket to upload files to" validate:"nonzero"`
VersionAndExit bool `flag:"version" default:"false" description:"Prints current version and exits"`
}{}
@ -40,34 +44,61 @@ func init() {
}
func main() {
if cfg.Bootstrap {
for _, asset := range []string{"index.html", "app.js"} {
if _, err := executeUpload(asset, asset, bytes.NewReader(MustAsset("frontend/"+asset))); err != nil {
log.WithError(err).Fatalf("Unable to upload bootstrap asset %q", asset)
}
}
log.Info("Bucket bootstrap finished: Frontend uploaded.")
return
}
if len(rconfig.Args()) == 1 {
log.Fatalf("Usage: share <file to upload>")
}
if cfg.BaseURL == "" {
log.Error("No BaseURL configured, output will be no complete URL")
}
inFile := rconfig.Args()[1]
inFileHandle, err := os.Open(inFile)
if err != nil {
log.WithError(err).Fatal("Unable to open source file")
}
upFile, err := calculateUploadFilename(inFile)
if err != nil {
log.WithError(err).Fatal("Unable to calculate upload filename")
}
url, err := executeUpload(inFile, upFile, inFileHandle)
if err != nil {
log.WithError(err).Fatal("Failed to upload file")
}
fmt.Println(url)
}
func calculateUploadFilename(inFile string) (string, error) {
upFile := path.Join(cfg.BasePath, path.Base(inFile))
fileHash, err := hashFile(inFile)
if err != nil {
return "", err
}
return executeTemplate(upFile, map[string]interface{}{
"Hash": fileHash,
})
}
func executeUpload(inFile, upFile string, inFileHandle io.ReadSeeker) (string, error) {
mimeType := mime.TypeByExtension(path.Ext(inFile))
if mimeType == "" {
mimeType = "application/octet-stream"
}
inFileHandle, err := os.Open(inFile)
if err != nil {
log.WithError(err).Fatal("Unable to open source file")
}
fileHash, err := hashFile(inFile)
if err != nil {
log.WithError(err).Fatal("Unable to calculate file hash")
}
upFile, err = executeTemplate(upFile, map[string]interface{}{
"Hash": fileHash,
})
if err != nil {
log.WithError(err).Fatal("Unable to assemble target path")
}
log.Infof("Uploading %q to %q with type %q", inFile, upFile, mimeType)
log.Debugf("Uploading %q to %q with type %q", inFile, upFile, mimeType)
sess := session.Must(session.NewSession())
svc := s3.New(sess)
@ -78,10 +109,10 @@ func main() {
ContentType: aws.String(mimeType),
Key: aws.String(upFile),
}); err != nil {
log.WithError(err).Fatalf("Unable to put file into S3")
return "", err
}
fmt.Printf("%s%s", cfg.BaseURL, upFile)
return fmt.Sprintf("%s%s", cfg.BaseURL, upFile), nil
}
func hashFile(inFile string) (string, error) {