internal/database: bake postgres actions into the binary with go-bindata

This commit is contained in:
Cadey Ratio 2018-01-21 10:00:13 -08:00
parent 0c5cc8f2d9
commit 6b12210014
3 changed files with 386 additions and 9 deletions

View File

@ -0,0 +1,375 @@
// Code generated by go-bindata.
// sources:
// migrations/1513981282_certificates.down.sql
// migrations/1513981282_certificates.up.sql
// migrations/1513981599_routes.down.sql
// migrations/1513981599_routes.up.sql
// migrations/1513982254_tokens.down.sql
// migrations/1513982254_tokens.up.sql
// migrations/postgres.sql
// DO NOT EDIT!
package dmigrations
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 _migrations1513981282_certificatesDownSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\x09\xf2\x0f\x50\xf0\xf4\x73\x71\x8d\x50\x70\x4e\x2d\x2a\xc9\x4c\xcb\x4c\x4e\x2c\x49\x2d\x8e\x4f\xc9\xcf\x4d\xcc\xcc\xb3\xe6\x02\xcb\x87\x38\x3a\xf9\xb8\xa2\xc8\x5b\x73\x01\x02\x00\x00\xff\xff\xb8\xef\x1e\x9f\x39\x00\x00\x00")
func migrations1513981282_certificatesDownSqlBytes() ([]byte, error) {
return bindataRead(
_migrations1513981282_certificatesDownSql,
"migrations/1513981282_certificates.down.sql",
)
}
func migrations1513981282_certificatesDownSql() (*asset, error) {
bytes, err := migrations1513981282_certificatesDownSqlBytes()
if err != nil {
return nil, err
}
info := bindataFileInfo{name: "migrations/1513981282_certificates.down.sql", size: 57, mode: os.FileMode(420), modTime: time.Unix(1516557003, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
var _migrations1513981282_certificatesUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x90\x31\x4f\xc3\x30\x10\x85\x77\xff\x8a\xa7\x4e\x89\x04\x03\x48\xb0\x74\x72\x93\xab\xb0\x48\xec\x92\xd8\x90\x4e\x91\x95\x18\xe4\xa1\x2d\x4a\x9c\xfe\x7e\x44\x1a\x02\x61\x40\x78\xf3\xe9\x7b\xf7\x9d\x5e\x52\x10\xd7\x04\xaa\x34\xc9\x52\x28\x09\xb1\x85\x54\x1a\x54\x89\x52\x97\x58\x0d\x83\x6f\xaf\x4f\x7d\xff\xbe\x5a\x33\x36\xc1\x9a\x6f\x32\xfa\x05\x26\xae\x0b\xfe\xd5\x37\x36\xb8\x9e\x01\x11\x7c\x8b\xaf\x67\x8c\x48\xe7\xcf\xae\x10\x39\x2f\xf6\x78\xa4\x3d\x52\xda\x72\x93\x69\x7c\x4a\xea\x37\x77\x74\x9d\x0d\xae\x3e\xdf\x1c\x9a\x28\x66\xc0\x15\xda\xd3\xc1\xfa\xe3\x98\x7b\xe6\x45\xf2\xc0\x8b\xe8\xf6\xee\x3e\x1e\xc5\xd2\x64\xd9\x05\xb2\xc1\x4e\xcb\x35\x55\x7a\x36\x2d\xa0\xa6\x73\x36\xb8\xb6\xb6\x01\x5a\xe4\x54\x6a\x9e\xef\x7e\x42\xf3\x2d\x52\xbd\x4c\x72\xd7\xfa\x29\xf1\xef\x88\x6d\x82\x3f\xbb\xd1\xbe\x51\x2a\x23\x2e\x97\xa7\xcc\x91\xd0\x0d\x8e\x01\xf1\x77\xa9\x46\x8a\x27\x43\x10\x32\xa5\xea\x8f\x6e\xeb\xa9\x12\x25\x17\x63\x44\x97\x79\xbc\x66\x1f\x01\x00\x00\xff\xff\xcf\x95\x0a\x45\xd2\x01\x00\x00")
func migrations1513981282_certificatesUpSqlBytes() ([]byte, error) {
return bindataRead(
_migrations1513981282_certificatesUpSql,
"migrations/1513981282_certificates.up.sql",
)
}
func migrations1513981282_certificatesUpSql() (*asset, error) {
bytes, err := migrations1513981282_certificatesUpSqlBytes()
if err != nil {
return nil, err
}
info := bindataFileInfo{name: "migrations/1513981282_certificates.up.sql", size: 466, mode: os.FileMode(420), modTime: time.Unix(1516557003, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
var _migrations1513981599_routesDownSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\x09\xf2\x0f\x50\x08\x71\x74\xf2\x71\x55\x08\xca\x2f\x2d\x49\x2d\xb6\xe6\x02\x04\x00\x00\xff\xff\xf9\xea\x76\x2b\x13\x00\x00\x00")
func migrations1513981599_routesDownSqlBytes() ([]byte, error) {
return bindataRead(
_migrations1513981599_routesDownSql,
"migrations/1513981599_routes.down.sql",
)
}
func migrations1513981599_routesDownSql() (*asset, error) {
bytes, err := migrations1513981599_routesDownSqlBytes()
if err != nil {
return nil, err
}
info := bindataFileInfo{name: "migrations/1513981599_routes.down.sql", size: 19, mode: os.FileMode(420), modTime: time.Unix(1516557003, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
var _migrations1513981599_routesUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8c\x90\x3f\x6f\x83\x30\x14\xc4\x77\x7f\x8a\x53\x26\x90\xda\xa1\xa9\xda\x25\x93\x13\x5e\x54\xab\x60\x52\x63\xb7\x64\x42\x08\xac\x96\x21\x50\x81\xc9\xe7\xaf\xa0\x40\xff\x0e\xf1\xe6\xa7\xdf\xdd\x7b\x77\x3b\x45\x5c\x13\x28\xd5\x24\x13\x11\x4b\x88\x3d\x64\xac\x41\xa9\x48\x74\x82\x55\xdf\x57\xe5\x75\xd3\x75\xef\xab\x0d\x63\x13\xac\xf9\x36\xa4\x5f\xa0\x6a\x7a\x67\x3b\x06\x78\xa8\x4a\xcc\xcf\x18\x11\x2c\x9f\x83\x12\x11\x57\x47\x3c\xd2\x11\x01\xed\xb9\x09\x35\x06\xfb\xec\xd5\xd6\xb6\xcd\x9d\xcd\xce\x37\xa7\xc2\xf3\x19\x70\x85\xa2\xb5\xb9\x6b\xda\x41\xf7\xcc\xd5\xee\x81\x2b\xef\x76\xed\x63\x5c\x29\x4d\x18\x8e\xd0\x5b\xd3\xb9\x3a\x3f\xd9\x6f\xd0\xfa\xee\xde\xff\x09\x8d\x4e\xb6\xcc\x72\x07\x2d\x22\x4a\x34\x8f\x0e\x83\xed\x0c\x2d\xb7\xc8\xf8\x65\x5a\x6e\xcb\x6a\x52\x5c\x2c\xc9\x0b\x57\x9d\xed\x98\x73\x1b\xc7\x21\x71\xf9\x19\xfa\x8f\xc4\xb5\xbd\x65\x80\xff\x55\xa7\x91\xe2\xc9\x10\x84\x0c\x28\xfd\xb7\xd5\x6c\xc9\xd9\xd4\xd3\x08\xde\x3c\xf3\x37\xec\x23\x00\x00\xff\xff\x28\x30\xd1\x48\xc4\x01\x00\x00")
func migrations1513981599_routesUpSqlBytes() ([]byte, error) {
return bindataRead(
_migrations1513981599_routesUpSql,
"migrations/1513981599_routes.up.sql",
)
}
func migrations1513981599_routesUpSql() (*asset, error) {
bytes, err := migrations1513981599_routesUpSqlBytes()
if err != nil {
return nil, err
}
info := bindataFileInfo{name: "migrations/1513981599_routes.up.sql", size: 452, mode: os.FileMode(420), modTime: time.Unix(1516557003, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
var _migrations1513982254_tokensDownSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x72\x09\xf2\x0f\x50\xf0\xf4\x73\x71\x8d\x50\x08\xc9\xcf\x4e\xcd\x2b\x8e\x4f\xca\x4f\xa9\xb4\xe6\xe2\x02\x4b\x84\x38\x3a\xf9\xb8\x42\x25\xac\xb9\x00\x01\x00\x00\xff\xff\x35\x06\x52\x0d\x2c\x00\x00\x00")
func migrations1513982254_tokensDownSqlBytes() ([]byte, error) {
return bindataRead(
_migrations1513982254_tokensDownSql,
"migrations/1513982254_tokens.down.sql",
)
}
func migrations1513982254_tokensDownSql() (*asset, error) {
bytes, err := migrations1513982254_tokensDownSqlBytes()
if err != nil {
return nil, err
}
info := bindataFileInfo{name: "migrations/1513982254_tokens.down.sql", size: 44, mode: os.FileMode(420), modTime: time.Unix(1516557003, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
var _migrations1513982254_tokensUpSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x74\x90\x4f\x4b\xc3\x40\x10\xc5\xef\xfb\x29\x86\x9e\x12\xd0\x83\x15\xbd\xf4\xb4\x6d\xa7\xb8\x98\x6e\x6a\x32\xab\x29\x22\x21\x26\x83\x04\xb1\x1b\xb2\x49\xd1\x6f\x2f\x5d\x62\x6c\xfd\xb3\xb7\x07\xbf\xfd\xbd\xe1\x2d\x12\x94\x84\x80\x19\xa1\x4e\x55\xac\x41\xad\x40\xc7\x04\x98\xa9\x94\x52\x98\xf4\x7d\x5d\x9d\x5b\xe7\x9a\xc9\x4c\x88\x01\x26\x39\x8f\xf0\x07\x48\xf6\x95\x77\x4e\x00\x04\x50\x57\xf0\xf5\x8c\x51\xcb\x31\x6c\x12\xb5\x96\xc9\x16\x6e\x71\x0b\x4b\x5c\x49\x13\x11\x1c\xf4\xf9\x0b\xef\xb8\x2d\x3a\xce\xf7\x17\x6f\x65\x10\x0a\x80\x33\x78\xb6\xd5\xc7\xf0\xef\x5e\x26\x8b\x1b\x99\x04\xd3\xab\xeb\xd0\x57\x6a\x13\x45\x1e\x2a\x5b\x2e\x3a\xdb\x1e\x43\x97\xd3\x10\x4e\x21\x57\xda\x86\x9d\x37\x11\x66\xf4\xf8\x34\x68\x7f\x9b\xb8\xca\x8b\x0e\x48\xad\x31\x25\xb9\xde\x1c\x43\xe3\xc1\x3a\x7e\x18\x2e\xe4\xf7\xa6\x6e\xd9\xfd\xfb\xc5\x43\x45\xd9\xd5\x7b\xf6\x7d\xf3\x38\x8e\x50\xea\xd3\xf2\xd1\xdb\xb5\x3d\x0b\x80\xf0\x7b\x65\xa3\xd5\x9d\x41\x50\x7a\x89\xd9\x9f\x63\xe7\x7e\x23\xbb\x1b\x22\x04\x87\x1c\xce\xc4\x67\x00\x00\x00\xff\xff\x43\x54\xbb\x34\xd3\x01\x00\x00")
func migrations1513982254_tokensUpSqlBytes() ([]byte, error) {
return bindataRead(
_migrations1513982254_tokensUpSql,
"migrations/1513982254_tokens.up.sql",
)
}
func migrations1513982254_tokensUpSql() (*asset, error) {
bytes, err := migrations1513982254_tokensUpSqlBytes()
if err != nil {
return nil, err
}
info := bindataFileInfo{name: "migrations/1513982254_tokens.up.sql", size: 467, mode: os.FileMode(420), modTime: time.Unix(1516557003, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}
var _migrationsPostgresSql = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xb4\x94\xdf\xeb\xda\x30\x14\xc5\xdf\xf3\x57\xdc\x37\x15\x9a\x87\x3d\x0d\x26\x52\x44\x33\x56\xa8\x0a\xb5\xdb\x1e\x25\x36\xd7\x2d\xac\x36\x92\x44\x99\xff\xfd\x48\x1b\xb5\xa9\x3f\x28\xe3\x2b\xf4\xa1\xa4\xdc\x73\x3e\xf7\xf4\xb4\x94\x42\xc5\xf7\xf8\x05\x64\x65\x50\x5b\x5a\xa0\xb6\x72\x27\x0b\x6e\x91\x90\x64\xb9\x66\x59\x0e\xc9\x32\x5f\xc1\xec\xf6\xc0\x10\x80\xa1\x50\x7b\x2e\xab\x08\x04\xb7\x7c\x44\x7e\x4c\xd3\xef\x6c\xed\xce\xe3\x08\xe2\xd1\x98\x90\xab\xf0\x4e\x56\x82\xaa\x0a\x43\xe9\x35\x4b\xd9\x2c\x77\x03\x52\x44\xd0\x16\x8b\xa0\xd0\xc8\x2d\x8a\x0d\xb7\x11\xa0\x90\x97\x5b\x5e\x58\x79\xc2\x11\xf9\x9a\xad\x16\x21\xce\xcf\x6f\x2c\x63\x5e\x64\x12\x93\x34\x59\x24\x39\x7c\x6a\x43\x68\xdc\xab\x13\xde\x63\xcc\x59\xca\x72\xf6\x5f\x92\x3e\x30\xad\x8e\xdd\xa8\x08\x40\xe6\x4e\xcd\xb0\xde\x44\xe9\x08\x7e\x2b\x63\xdd\x58\xbf\xa4\x6a\x4d\xba\x3d\x53\x29\xba\x49\xdd\x29\xf6\x8b\xab\xe1\xf1\x5b\x49\xf1\x78\xa3\x7b\x7f\x67\xf2\x0e\x82\xcb\xe8\x0b\x0e\x5e\x96\x0d\x87\xa1\x3b\xa5\xe9\xd1\xa0\x7e\x07\x89\xd7\x98\xc4\x6d\x00\x81\x25\x5a\xbc\x45\x11\xf6\xa4\x3d\x4f\xa0\x4e\x13\xa6\xcb\x79\x9f\xb2\x58\xf5\x07\xab\xb0\x2c\xb9\x3b\xaa\xbf\xa8\xad\x12\xe7\xd6\x52\xa6\x50\x07\x34\x11\xe0\xdf\x83\xd4\x68\x36\xdc\x76\xcb\xd3\x5c\x41\x85\x7e\xa1\xad\xb1\xbd\x51\x98\xd7\x13\x83\x20\xb3\xab\x59\x27\x34\x8f\xf9\xba\x40\x81\xbb\xeb\x8f\x73\x7c\x1b\x85\x13\x7a\xce\xe1\xfa\x53\x73\x3c\xef\xcf\x87\x91\x3c\x2c\x51\xeb\x97\xe3\xdf\x46\xbb\x44\xbd\xf2\xf4\x12\x0d\x84\xf0\xeb\xbc\xd0\xb9\xd1\x02\x05\x59\x59\xd4\x27\x5e\xc2\xe0\x33\x08\x7e\x36\x83\x31\xf9\x17\x00\x00\xff\xff\x85\x3d\x18\x01\xed\x05\x00\x00")
func migrationsPostgresSqlBytes() ([]byte, error) {
return bindataRead(
_migrationsPostgresSql,
"migrations/postgres.sql",
)
}
func migrationsPostgresSql() (*asset, error) {
bytes, err := migrationsPostgresSqlBytes()
if err != nil {
return nil, err
}
info := bindataFileInfo{name: "migrations/postgres.sql", size: 1517, mode: os.FileMode(420), modTime: time.Unix(1516557003, 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){
"migrations/1513981282_certificates.down.sql": migrations1513981282_certificatesDownSql,
"migrations/1513981282_certificates.up.sql": migrations1513981282_certificatesUpSql,
"migrations/1513981599_routes.down.sql": migrations1513981599_routesDownSql,
"migrations/1513981599_routes.up.sql": migrations1513981599_routesUpSql,
"migrations/1513982254_tokens.down.sql": migrations1513982254_tokensDownSql,
"migrations/1513982254_tokens.up.sql": migrations1513982254_tokensUpSql,
"migrations/postgres.sql": migrationsPostgresSql,
}
// 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{
"migrations": &bintree{nil, map[string]*bintree{
"1513981282_certificates.down.sql": &bintree{migrations1513981282_certificatesDownSql, map[string]*bintree{}},
"1513981282_certificates.up.sql": &bintree{migrations1513981282_certificatesUpSql, map[string]*bintree{}},
"1513981599_routes.down.sql": &bintree{migrations1513981599_routesDownSql, map[string]*bintree{}},
"1513981599_routes.up.sql": &bintree{migrations1513981599_routesUpSql, map[string]*bintree{}},
"1513982254_tokens.down.sql": &bintree{migrations1513982254_tokensDownSql, map[string]*bintree{}},
"1513982254_tokens.up.sql": &bintree{migrations1513982254_tokensUpSql, map[string]*bintree{}},
"postgres.sql": &bintree{migrationsPostgresSql, 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, "/")...)...)
}

20
mage.go
View File

@ -144,13 +144,6 @@ func Package() {
}
}
// Version is the version as git reports.
func Version() {
ver, err := gitTag()
qod.ANE(err)
qod.Printlnf("route-%s", ver)
}
// Test runs all of the functional and unit tests for the project.
func Test() {
ctx, cancel := context.WithCancel(context.Background())
@ -165,6 +158,7 @@ func Tools(ctx context.Context) {
"github.com/golang/dep/cmd/dep",
"github.com/golang/protobuf/protoc-gen-go",
"github.com/twitchtv/twirp/protoc-gen-twirp",
"github.com/jteeuwen/go-bindata/go-bindata",
}
for _, t := range tools {
@ -174,17 +168,25 @@ func Tools(ctx context.Context) {
// Generate runs code generators and the like.
func Generate(ctx context.Context) {
dir := filepath.Join(wd, "proto")
protoDir := filepath.Join(wd, "proto")
databaseDir := filepath.Join(wd, "internal", "database")
os.Mkdir(filepath.Join(databaseDir, "dmigrations"), 0777)
Tools(ctx)
shouldWork(ctx, nil, dir, "sh", "./regen.sh")
shouldWork(ctx, nil, protoDir, "sh", "./regen.sh")
shouldWork(ctx, nil, databaseDir, "go-bindata", "-pkg", "dmigrations", "-o", "./dmigrations/bindata.go", "./migrations")
}
// Vars shows the various variables that this magefile uses.
func Vars() {
ver, err := gitTag()
qod.ANE(err)
qod.Printlnf("arches:\t%v", arches)
qod.Printlnf("goarch:\t%s", runtime.GOARCH)
qod.Printlnf("goos:\t%s", runtime.GOOS)
qod.Printlnf("wd:\t%s", wd)
qod.Printlnf("ver:\t%s", ver)
}