[add] setup
This commit is contained in:
parent
39b59f0cf1
commit
93ba063cb4
19 changed files with 2088 additions and 101 deletions
4
Makefile
4
Makefile
|
|
@ -271,11 +271,15 @@ release: clean
|
||||||
echo "BASE=__yao_admin_root" > .tmp/xgen/v1.0/packages/xgen/.env
|
echo "BASE=__yao_admin_root" > .tmp/xgen/v1.0/packages/xgen/.env
|
||||||
cd .tmp/xgen/v1.0 && pnpm install && pnpm run build
|
cd .tmp/xgen/v1.0 && pnpm install && pnpm run build
|
||||||
|
|
||||||
|
# Setup UI
|
||||||
|
cd .tmp/xgen/v1.0/packages/setup && pnpm install && pnpm run build
|
||||||
|
|
||||||
# Packing
|
# Packing
|
||||||
mkdir -p .tmp/data/xgen
|
mkdir -p .tmp/data/xgen
|
||||||
cp -r ./ui .tmp/data/ui
|
cp -r ./ui .tmp/data/ui
|
||||||
cp -r ./yao .tmp/data/yao
|
cp -r ./yao .tmp/data/yao
|
||||||
cp -r .tmp/xgen/v0.9/dist .tmp/data/xgen/v0.9
|
cp -r .tmp/xgen/v0.9/dist .tmp/data/xgen/v0.9
|
||||||
|
cp -r .tmp/xgen/v1.0/packages/xgen/build .tmp/data/xgen/setup
|
||||||
cp -r .tmp/xgen/v1.0/packages/xgen/dist .tmp/data/xgen/v1.0
|
cp -r .tmp/xgen/v1.0/packages/xgen/dist .tmp/data/xgen/v1.0
|
||||||
go-bindata -fs -pkg data -o data/bindata.go -prefix ".tmp/data/" .tmp/data/...
|
go-bindata -fs -pkg data -o data/bindata.go -prefix ".tmp/data/" .tmp/data/...
|
||||||
rm -rf .tmp/data
|
rm -rf .tmp/data
|
||||||
|
|
|
||||||
40
cmd/start.go
40
cmd/start.go
|
|
@ -22,6 +22,7 @@ import (
|
||||||
"github.com/yaoapp/yao/engine"
|
"github.com/yaoapp/yao/engine"
|
||||||
"github.com/yaoapp/yao/fs"
|
"github.com/yaoapp/yao/fs"
|
||||||
"github.com/yaoapp/yao/service"
|
"github.com/yaoapp/yao/service"
|
||||||
|
"github.com/yaoapp/yao/setup"
|
||||||
"github.com/yaoapp/yao/share"
|
"github.com/yaoapp/yao/share"
|
||||||
"github.com/yaoapp/yao/studio"
|
"github.com/yaoapp/yao/studio"
|
||||||
)
|
)
|
||||||
|
|
@ -35,6 +36,19 @@ var startCmd = &cobra.Command{
|
||||||
Long: L("Start Engine"),
|
Long: L("Start Engine"),
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
|
||||||
|
// Setup
|
||||||
|
if setup.Check() {
|
||||||
|
go setup.Start()
|
||||||
|
select {
|
||||||
|
case <-setup.Done:
|
||||||
|
setup.Stop()
|
||||||
|
break
|
||||||
|
case <-setup.Canceled:
|
||||||
|
os.Exit(1)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// recive interrupt signal
|
// recive interrupt signal
|
||||||
interrupt := make(chan os.Signal, 1)
|
interrupt := make(chan os.Signal, 1)
|
||||||
signal.Notify(interrupt, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT)
|
signal.Notify(interrupt, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT)
|
||||||
|
|
@ -58,10 +72,6 @@ var startCmd = &cobra.Command{
|
||||||
}
|
}
|
||||||
|
|
||||||
host := config.Conf.Host
|
host := config.Conf.Host
|
||||||
if host == "0.0.0.0" {
|
|
||||||
host = "127.0.0.1"
|
|
||||||
}
|
|
||||||
|
|
||||||
dataRoot, _ := fs.Root(config.Conf)
|
dataRoot, _ := fs.Root(config.Conf)
|
||||||
|
|
||||||
fmt.Println(color.WhiteString("\n---------------------------------"))
|
fmt.Println(color.WhiteString("\n---------------------------------"))
|
||||||
|
|
@ -73,15 +83,29 @@ var startCmd = &cobra.Command{
|
||||||
}
|
}
|
||||||
|
|
||||||
if share.App.XGen == "1.0" {
|
if share.App.XGen == "1.0" {
|
||||||
|
|
||||||
root, _ := adminRoot()
|
root, _ := adminRoot()
|
||||||
fmt.Println(color.WhiteString(L(" XGen")), color.GreenString(" 1.0"))
|
urls := []string{fmt.Sprintf("http://%s:%s", host, port)}
|
||||||
|
if host == "0.0.0.0" {
|
||||||
|
urls, _ = setup.URLs(config.Conf)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(color.WhiteString(L("XGen")), color.GreenString(" 1.0"))
|
||||||
fmt.Println(color.WhiteString(L("Data")), color.GreenString(" %s", dataRoot))
|
fmt.Println(color.WhiteString(L("Data")), color.GreenString(" %s", dataRoot))
|
||||||
fmt.Println(color.WhiteString(L("Frontend")), color.GreenString(" http://%s%s/", host, port))
|
for _, url := range urls {
|
||||||
fmt.Println(color.WhiteString(L("Dashboard")), color.GreenString(" http://%s%s%slogin/admin", host, port, root))
|
fmt.Println(color.WhiteString(L("Frontend ")), color.GreenString(" %s", url))
|
||||||
fmt.Println(color.WhiteString(L("API")), color.GreenString(" http://%s%s/api", host, port))
|
fmt.Println(color.WhiteString(L("Dashboard")), color.GreenString(" %s/%s/login/admin", url, strings.Trim(root, "/")))
|
||||||
|
fmt.Println(color.WhiteString(L("API ")), color.GreenString(" %s/api", url))
|
||||||
|
}
|
||||||
|
|
||||||
fmt.Println(color.WhiteString(L("Listening")), color.GreenString(" %s:%d", config.Conf.Host, config.Conf.Port))
|
fmt.Println(color.WhiteString(L("Listening")), color.GreenString(" %s:%d", config.Conf.Host, config.Conf.Port))
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
if host == "0.0.0.0" {
|
||||||
|
host = "127.0.0.1"
|
||||||
|
}
|
||||||
|
|
||||||
fmt.Println(color.WhiteString(L("Data")), color.GreenString(" %s", dataRoot))
|
fmt.Println(color.WhiteString(L("Data")), color.GreenString(" %s", dataRoot))
|
||||||
fmt.Println(color.WhiteString(L("Frontend")), color.GreenString(" http://%s%s/", host, port))
|
fmt.Println(color.WhiteString(L("Frontend")), color.GreenString(" http://%s%s/", host, port))
|
||||||
fmt.Println(color.WhiteString(L("Dashboard")), color.GreenString(" http://%s%s/xiang/login/admin", host, port))
|
fmt.Println(color.WhiteString(L("Dashboard")), color.GreenString(" http://%s%s/xiang/login/admin", host, port))
|
||||||
|
|
|
||||||
|
|
@ -40,13 +40,15 @@ func LoadFrom(envfile string) Config {
|
||||||
|
|
||||||
file, err := filepath.Abs(envfile)
|
file, err := filepath.Abs(envfile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("Can't load env file. %s", err.Error())
|
// log.Warn("Can't load env file. %s", err.Error())
|
||||||
}
|
return Load()
|
||||||
err = godotenv.Overload(file)
|
|
||||||
if err != nil {
|
|
||||||
log.Warn("Can't load env file. %s", err.Error())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
godotenv.Overload(file)
|
||||||
|
// if err != nil {
|
||||||
|
// // log.Warn("Can't load env file. %s", err.Error())
|
||||||
|
// }
|
||||||
|
|
||||||
return Load()
|
return Load()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
101
data/bindata.go
101
data/bindata.go
|
|
@ -1,6 +1,7 @@
|
||||||
// Code generated for package data by go-bindata DO NOT EDIT. (@generated)
|
// Code generated for package data by go-bindata DO NOT EDIT. (@generated)
|
||||||
// sources:
|
// sources:
|
||||||
// .tmp/data/ui/index.html
|
// .tmp/data/ui/index.html
|
||||||
|
// .tmp/data/xgen/setup/index.html
|
||||||
// .tmp/data/xgen/v0.9/index.html
|
// .tmp/data/xgen/v0.9/index.html
|
||||||
// .tmp/data/xgen/v1.0/index.html
|
// .tmp/data/xgen/v1.0/index.html
|
||||||
// .tmp/data/xgen/v1.0/layouts__index.async.js
|
// .tmp/data/xgen/v1.0/layouts__index.async.js
|
||||||
|
|
@ -216,7 +217,27 @@ func uiIndexHtml() (*asset, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "ui/index.html", size: 11, mode: os.FileMode(420), modTime: time.Unix(1666415327, 0)}
|
info := bindataFileInfo{name: "ui/index.html", size: 11, mode: os.FileMode(420), modTime: time.Unix(1666927855, 0)}
|
||||||
|
a := &asset{bytes: bytes, info: info}
|
||||||
|
return a, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var _xgenSetupIndexHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8a\x70\x77\xf5\x53\x08\x76\x0d\x09\x0d\xe0\x02\x04\x00\x00\xff\xff\xdb\x53\x4c\xdc\x0b\x00\x00\x00")
|
||||||
|
|
||||||
|
func xgenSetupIndexHtmlBytes() ([]byte, error) {
|
||||||
|
return bindataRead(
|
||||||
|
_xgenSetupIndexHtml,
|
||||||
|
"xgen/setup/index.html",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func xgenSetupIndexHtml() (*asset, error) {
|
||||||
|
bytes, err := xgenSetupIndexHtmlBytes()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
info := bindataFileInfo{name: "xgen/setup/index.html", size: 11, mode: os.FileMode(420), modTime: time.Unix(1666927855, 0)}
|
||||||
a := &asset{bytes: bytes, info: info}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
@ -236,7 +257,7 @@ func xgenV09IndexHtml() (*asset, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "xgen/v0.9/index.html", size: 14, mode: os.FileMode(420), modTime: time.Unix(1666415327, 0)}
|
info := bindataFileInfo{name: "xgen/v0.9/index.html", size: 14, mode: os.FileMode(420), modTime: time.Unix(1666927855, 0)}
|
||||||
a := &asset{bytes: bytes, info: info}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
@ -256,7 +277,7 @@ func xgenV10IndexHtml() (*asset, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "xgen/v1.0/index.html", size: 50, mode: os.FileMode(420), modTime: time.Unix(1666415327, 0)}
|
info := bindataFileInfo{name: "xgen/v1.0/index.html", size: 50, mode: os.FileMode(420), modTime: time.Unix(1666927855, 0)}
|
||||||
a := &asset{bytes: bytes, info: info}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
@ -276,7 +297,7 @@ func xgenV10Layouts__indexAsyncJs() (*asset, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "xgen/v1.0/layouts__index.async.js", size: 71, mode: os.FileMode(420), modTime: time.Unix(1666415327, 0)}
|
info := bindataFileInfo{name: "xgen/v1.0/layouts__index.async.js", size: 71, mode: os.FileMode(420), modTime: time.Unix(1666927855, 0)}
|
||||||
a := &asset{bytes: bytes, info: info}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
@ -296,7 +317,7 @@ func xgenV10UmiJs() (*asset, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "xgen/v1.0/umi.js", size: 71, mode: os.FileMode(420), modTime: time.Unix(1666415327, 0)}
|
info := bindataFileInfo{name: "xgen/v1.0/umi.js", size: 71, mode: os.FileMode(420), modTime: time.Unix(1666927855, 0)}
|
||||||
a := &asset{bytes: bytes, info: info}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
@ -316,7 +337,7 @@ func yaoApisReadmeMd() (*asset, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "yao/apis/README.md", size: 13, mode: os.FileMode(420), modTime: time.Unix(1666415327, 0)}
|
info := bindataFileInfo{name: "yao/apis/README.md", size: 13, mode: os.FileMode(420), modTime: time.Unix(1666927855, 0)}
|
||||||
a := &asset{bytes: bytes, info: info}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
@ -336,7 +357,7 @@ func yaoApisChartHttpJson() (*asset, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "yao/apis/chart.http.json", size: 624, mode: os.FileMode(420), modTime: time.Unix(1666415327, 0)}
|
info := bindataFileInfo{name: "yao/apis/chart.http.json", size: 624, mode: os.FileMode(420), modTime: time.Unix(1666927855, 0)}
|
||||||
a := &asset{bytes: bytes, info: info}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
@ -356,7 +377,7 @@ func yaoApisImportHttpJson() (*asset, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "yao/apis/import.http.json", size: 1676, mode: os.FileMode(420), modTime: time.Unix(1666415327, 0)}
|
info := bindataFileInfo{name: "yao/apis/import.http.json", size: 1676, mode: os.FileMode(420), modTime: time.Unix(1666927855, 0)}
|
||||||
a := &asset{bytes: bytes, info: info}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
@ -376,7 +397,7 @@ func yaoApisPageHttpJson() (*asset, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "yao/apis/page.http.json", size: 609, mode: os.FileMode(420), modTime: time.Unix(1666415327, 0)}
|
info := bindataFileInfo{name: "yao/apis/page.http.json", size: 609, mode: os.FileMode(420), modTime: time.Unix(1666927855, 0)}
|
||||||
a := &asset{bytes: bytes, info: info}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
@ -396,7 +417,7 @@ func yaoApisStorageHttpJson() (*asset, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "yao/apis/storage.http.json", size: 1026, mode: os.FileMode(420), modTime: time.Unix(1666415327, 0)}
|
info := bindataFileInfo{name: "yao/apis/storage.http.json", size: 1026, mode: os.FileMode(420), modTime: time.Unix(1666927855, 0)}
|
||||||
a := &asset{bytes: bytes, info: info}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
@ -416,7 +437,7 @@ func yaoApisTableHttpJson() (*asset, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "yao/apis/table.http.json", size: 3213, mode: os.FileMode(420), modTime: time.Unix(1666415327, 0)}
|
info := bindataFileInfo{name: "yao/apis/table.http.json", size: 3213, mode: os.FileMode(420), modTime: time.Unix(1666927855, 0)}
|
||||||
a := &asset{bytes: bytes, info: info}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
@ -436,7 +457,7 @@ func yaoApisUserHttpJson() (*asset, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "yao/apis/user.http.json", size: 1453, mode: os.FileMode(420), modTime: time.Unix(1666415327, 0)}
|
info := bindataFileInfo{name: "yao/apis/user.http.json", size: 1453, mode: os.FileMode(420), modTime: time.Unix(1666927855, 0)}
|
||||||
a := &asset{bytes: bytes, info: info}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
@ -456,7 +477,7 @@ func yaoApisXiangHttpJson() (*asset, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "yao/apis/xiang.http.json", size: 1239, mode: os.FileMode(420), modTime: time.Unix(1666415327, 0)}
|
info := bindataFileInfo{name: "yao/apis/xiang.http.json", size: 1239, mode: os.FileMode(420), modTime: time.Unix(1666927855, 0)}
|
||||||
a := &asset{bytes: bytes, info: info}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
@ -476,7 +497,7 @@ func yaoDataAppJson() (*asset, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "yao/data/app.json", size: 277, mode: os.FileMode(420), modTime: time.Unix(1666415327, 0)}
|
info := bindataFileInfo{name: "yao/data/app.json", size: 277, mode: os.FileMode(420), modTime: time.Unix(1666927855, 0)}
|
||||||
a := &asset{bytes: bytes, info: info}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
@ -496,7 +517,7 @@ func yaoDataIcons404Png() (*asset, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "yao/data/icons/404.png", size: 9342, mode: os.FileMode(420), modTime: time.Unix(1666415327, 0)}
|
info := bindataFileInfo{name: "yao/data/icons/404.png", size: 9342, mode: os.FileMode(420), modTime: time.Unix(1666927855, 0)}
|
||||||
a := &asset{bytes: bytes, info: info}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
@ -516,7 +537,7 @@ func yaoDataIconsIconIcns() (*asset, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "yao/data/icons/icon.icns", size: 67465, mode: os.FileMode(420), modTime: time.Unix(1666415327, 0)}
|
info := bindataFileInfo{name: "yao/data/icons/icon.icns", size: 67465, mode: os.FileMode(420), modTime: time.Unix(1666927855, 0)}
|
||||||
a := &asset{bytes: bytes, info: info}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
@ -536,7 +557,7 @@ func yaoDataIconsIconIco() (*asset, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "yao/data/icons/icon.ico", size: 54993, mode: os.FileMode(420), modTime: time.Unix(1666415327, 0)}
|
info := bindataFileInfo{name: "yao/data/icons/icon.ico", size: 54993, mode: os.FileMode(420), modTime: time.Unix(1666927855, 0)}
|
||||||
a := &asset{bytes: bytes, info: info}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
@ -556,7 +577,7 @@ func yaoDataIconsIconPng() (*asset, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "yao/data/icons/icon.png", size: 34558, mode: os.FileMode(420), modTime: time.Unix(1666415327, 0)}
|
info := bindataFileInfo{name: "yao/data/icons/icon.png", size: 34558, mode: os.FileMode(420), modTime: time.Unix(1666927855, 0)}
|
||||||
a := &asset{bytes: bytes, info: info}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
@ -576,7 +597,7 @@ func yaoDataIndexHtml() (*asset, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "yao/data/index.html", size: 282, mode: os.FileMode(420), modTime: time.Unix(1666415327, 0)}
|
info := bindataFileInfo{name: "yao/data/index.html", size: 282, mode: os.FileMode(420), modTime: time.Unix(1666927855, 0)}
|
||||||
a := &asset{bytes: bytes, info: info}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
@ -596,7 +617,7 @@ func yaoFieldsModelTransJson() (*asset, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "yao/fields/model.trans.json", size: 14777, mode: os.FileMode(420), modTime: time.Unix(1666415327, 0)}
|
info := bindataFileInfo{name: "yao/fields/model.trans.json", size: 14777, mode: os.FileMode(420), modTime: time.Unix(1666927855, 0)}
|
||||||
a := &asset{bytes: bytes, info: info}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
@ -616,7 +637,7 @@ func yaoFlowsReadmeMd() (*asset, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "yao/flows/README.md", size: 12, mode: os.FileMode(420), modTime: time.Unix(1666415327, 0)}
|
info := bindataFileInfo{name: "yao/flows/README.md", size: 12, mode: os.FileMode(420), modTime: time.Unix(1666927855, 0)}
|
||||||
a := &asset{bytes: bytes, info: info}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
@ -636,7 +657,7 @@ func yaoFlowsAdminGuardFlowJson() (*asset, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "yao/flows/admin/guard.flow.json", size: 559, mode: os.FileMode(420), modTime: time.Unix(1666415327, 0)}
|
info := bindataFileInfo{name: "yao/flows/admin/guard.flow.json", size: 559, mode: os.FileMode(420), modTime: time.Unix(1666927855, 0)}
|
||||||
a := &asset{bytes: bytes, info: info}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
@ -656,7 +677,7 @@ func yaoFlowsMenuFlowJson() (*asset, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "yao/flows/menu.flow.json", size: 1045, mode: os.FileMode(420), modTime: time.Unix(1666415327, 0)}
|
info := bindataFileInfo{name: "yao/flows/menu.flow.json", size: 1045, mode: os.FileMode(420), modTime: time.Unix(1666927855, 0)}
|
||||||
a := &asset{bytes: bytes, info: info}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
@ -676,7 +697,7 @@ func yaoFlowsUserFindFlowJson() (*asset, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "yao/flows/user/find.flow.json", size: 328, mode: os.FileMode(420), modTime: time.Unix(1666415327, 0)}
|
info := bindataFileInfo{name: "yao/flows/user/find.flow.json", size: 328, mode: os.FileMode(420), modTime: time.Unix(1666927855, 0)}
|
||||||
a := &asset{bytes: bytes, info: info}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
@ -696,7 +717,7 @@ func yaoLangsEnUsJson() (*asset, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "yao/langs/en-US.json", size: 66, mode: os.FileMode(420), modTime: time.Unix(1666415327, 0)}
|
info := bindataFileInfo{name: "yao/langs/en-US.json", size: 66, mode: os.FileMode(420), modTime: time.Unix(1666927855, 0)}
|
||||||
a := &asset{bytes: bytes, info: info}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
@ -716,7 +737,7 @@ func yaoLangsZhCnGlobalYml() (*asset, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "yao/langs/zh-cn/global.yml", size: 1629, mode: os.FileMode(420), modTime: time.Unix(1666415327, 0)}
|
info := bindataFileInfo{name: "yao/langs/zh-cn/global.yml", size: 1629, mode: os.FileMode(420), modTime: time.Unix(1666927855, 0)}
|
||||||
a := &asset{bytes: bytes, info: info}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
@ -736,7 +757,7 @@ func yaoLangsZhCnLoginsAdminLoginYml() (*asset, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "yao/langs/zh-cn/logins/admin.login.yml", size: 94, mode: os.FileMode(420), modTime: time.Unix(1666415327, 0)}
|
info := bindataFileInfo{name: "yao/langs/zh-cn/logins/admin.login.yml", size: 94, mode: os.FileMode(420), modTime: time.Unix(1666927855, 0)}
|
||||||
a := &asset{bytes: bytes, info: info}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
@ -756,7 +777,7 @@ func yaoLangsZhCnLoginsUserLoginYml() (*asset, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "yao/langs/zh-cn/logins/user.login.yml", size: 90, mode: os.FileMode(420), modTime: time.Unix(1666415327, 0)}
|
info := bindataFileInfo{name: "yao/langs/zh-cn/logins/user.login.yml", size: 90, mode: os.FileMode(420), modTime: time.Unix(1666927855, 0)}
|
||||||
a := &asset{bytes: bytes, info: info}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
@ -776,7 +797,7 @@ func yaoLangsZhHkGlobalYml() (*asset, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "yao/langs/zh-hk/global.yml", size: 1629, mode: os.FileMode(420), modTime: time.Unix(1666415327, 0)}
|
info := bindataFileInfo{name: "yao/langs/zh-hk/global.yml", size: 1629, mode: os.FileMode(420), modTime: time.Unix(1666927855, 0)}
|
||||||
a := &asset{bytes: bytes, info: info}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
@ -796,7 +817,7 @@ func yaoLangsZhHkLoginsAdminLoginYml() (*asset, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "yao/langs/zh-hk/logins/admin.login.yml", size: 94, mode: os.FileMode(420), modTime: time.Unix(1666415327, 0)}
|
info := bindataFileInfo{name: "yao/langs/zh-hk/logins/admin.login.yml", size: 94, mode: os.FileMode(420), modTime: time.Unix(1666927855, 0)}
|
||||||
a := &asset{bytes: bytes, info: info}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
@ -816,7 +837,7 @@ func yaoLangsZhHkLoginsUserLoginYml() (*asset, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "yao/langs/zh-hk/logins/user.login.yml", size: 90, mode: os.FileMode(420), modTime: time.Unix(1666415327, 0)}
|
info := bindataFileInfo{name: "yao/langs/zh-hk/logins/user.login.yml", size: 90, mode: os.FileMode(420), modTime: time.Unix(1666927855, 0)}
|
||||||
a := &asset{bytes: bytes, info: info}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
@ -836,7 +857,7 @@ func yaoModelsReadmeMd() (*asset, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "yao/models/README.md", size: 15, mode: os.FileMode(420), modTime: time.Unix(1666415327, 0)}
|
info := bindataFileInfo{name: "yao/models/README.md", size: 15, mode: os.FileMode(420), modTime: time.Unix(1666927855, 0)}
|
||||||
a := &asset{bytes: bytes, info: info}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
@ -856,7 +877,7 @@ func yaoModelsMenuModJson() (*asset, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "yao/models/menu.mod.json", size: 2378, mode: os.FileMode(420), modTime: time.Unix(1666415327, 0)}
|
info := bindataFileInfo{name: "yao/models/menu.mod.json", size: 2378, mode: os.FileMode(420), modTime: time.Unix(1666927855, 0)}
|
||||||
a := &asset{bytes: bytes, info: info}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
@ -876,7 +897,7 @@ func yaoModelsUserModJson() (*asset, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "yao/models/user.mod.json", size: 8826, mode: os.FileMode(420), modTime: time.Unix(1666415327, 0)}
|
info := bindataFileInfo{name: "yao/models/user.mod.json", size: 8826, mode: os.FileMode(420), modTime: time.Unix(1666927855, 0)}
|
||||||
a := &asset{bytes: bytes, info: info}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
@ -896,7 +917,7 @@ func yaoModelsWorkflowModJson() (*asset, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "yao/models/workflow.mod.json", size: 3333, mode: os.FileMode(420), modTime: time.Unix(1666415327, 0)}
|
info := bindataFileInfo{name: "yao/models/workflow.mod.json", size: 3333, mode: os.FileMode(420), modTime: time.Unix(1666927855, 0)}
|
||||||
a := &asset{bytes: bytes, info: info}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
@ -916,7 +937,7 @@ func yaoTablesReadmeMd() (*asset, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "yao/tables/README.md", size: 15, mode: os.FileMode(420), modTime: time.Unix(1666415327, 0)}
|
info := bindataFileInfo{name: "yao/tables/README.md", size: 15, mode: os.FileMode(420), modTime: time.Unix(1666927855, 0)}
|
||||||
a := &asset{bytes: bytes, info: info}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
@ -936,7 +957,7 @@ func yaoTablesMenuTabJson() (*asset, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "yao/tables/menu.tab.json", size: 10471, mode: os.FileMode(420), modTime: time.Unix(1666415327, 0)}
|
info := bindataFileInfo{name: "yao/tables/menu.tab.json", size: 10471, mode: os.FileMode(420), modTime: time.Unix(1666927855, 0)}
|
||||||
a := &asset{bytes: bytes, info: info}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
@ -956,7 +977,7 @@ func yaoTablesUserTabJson() (*asset, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := bindataFileInfo{name: "yao/tables/user.tab.json", size: 2357, mode: os.FileMode(420), modTime: time.Unix(1666415327, 0)}
|
info := bindataFileInfo{name: "yao/tables/user.tab.json", size: 2357, mode: os.FileMode(420), modTime: time.Unix(1666927855, 0)}
|
||||||
a := &asset{bytes: bytes, info: info}
|
a := &asset{bytes: bytes, info: info}
|
||||||
return a, nil
|
return a, nil
|
||||||
}
|
}
|
||||||
|
|
@ -1014,6 +1035,7 @@ func AssetNames() []string {
|
||||||
// _bindata is a table, holding each asset generator, mapped to its name.
|
// _bindata is a table, holding each asset generator, mapped to its name.
|
||||||
var _bindata = map[string]func() (*asset, error){
|
var _bindata = map[string]func() (*asset, error){
|
||||||
"ui/index.html": uiIndexHtml,
|
"ui/index.html": uiIndexHtml,
|
||||||
|
"xgen/setup/index.html": xgenSetupIndexHtml,
|
||||||
"xgen/v0.9/index.html": xgenV09IndexHtml,
|
"xgen/v0.9/index.html": xgenV09IndexHtml,
|
||||||
"xgen/v1.0/index.html": xgenV10IndexHtml,
|
"xgen/v1.0/index.html": xgenV10IndexHtml,
|
||||||
"xgen/v1.0/layouts__index.async.js": xgenV10Layouts__indexAsyncJs,
|
"xgen/v1.0/layouts__index.async.js": xgenV10Layouts__indexAsyncJs,
|
||||||
|
|
@ -1100,6 +1122,9 @@ var _bintree = &bintree{nil, map[string]*bintree{
|
||||||
"index.html": {uiIndexHtml, map[string]*bintree{}},
|
"index.html": {uiIndexHtml, map[string]*bintree{}},
|
||||||
}},
|
}},
|
||||||
"xgen": {nil, map[string]*bintree{
|
"xgen": {nil, map[string]*bintree{
|
||||||
|
"setup": {nil, map[string]*bintree{
|
||||||
|
"index.html": {xgenSetupIndexHtml, map[string]*bintree{}},
|
||||||
|
}},
|
||||||
"v0.9": {nil, map[string]*bintree{
|
"v0.9": {nil, map[string]*bintree{
|
||||||
"index.html": {xgenV09IndexHtml, map[string]*bintree{}},
|
"index.html": {xgenV09IndexHtml, map[string]*bintree{}},
|
||||||
}},
|
}},
|
||||||
|
|
|
||||||
12
data/data.go
12
data/data.go
|
|
@ -33,6 +33,18 @@ func XgenV1() *assetfs.AssetFS {
|
||||||
panic("unreachable")
|
panic("unreachable")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Setup Setup ui
|
||||||
|
func Setup() *assetfs.AssetFS {
|
||||||
|
assetInfo := func(path string) (os.FileInfo, error) {
|
||||||
|
return os.Stat(path)
|
||||||
|
}
|
||||||
|
for k := range _bintree.Children {
|
||||||
|
k = "xgen/setup"
|
||||||
|
return &assetfs.AssetFS{Asset: Asset, AssetDir: AssetDir, AssetInfo: assetInfo, Prefix: k, Fallback: "index.html"}
|
||||||
|
}
|
||||||
|
panic("unreachable")
|
||||||
|
}
|
||||||
|
|
||||||
// ReplaceXGen bindata file
|
// ReplaceXGen bindata file
|
||||||
func ReplaceXGen(search, replace string) error {
|
func ReplaceXGen(search, replace string) error {
|
||||||
err := replaceXGenIndex(search, replace)
|
err := replaceXGenIndex(search, replace)
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,6 @@ func TestCommandStart(t *testing.T) {
|
||||||
request := func() (maps.MapStr, error) {
|
request := func() (maps.MapStr, error) {
|
||||||
time.Sleep(time.Microsecond * 2000)
|
time.Sleep(time.Microsecond * 2000)
|
||||||
url := fmt.Sprintf("http://%s:%d/api/user/find/1?select=id,name", "127.0.0.1", config.Conf.Port)
|
url := fmt.Sprintf("http://%s:%d/api/user/find/1?select=id,name", "127.0.0.1", config.Conf.Port)
|
||||||
// utils.Dump(url)
|
|
||||||
resp, err := http.Get(url)
|
resp, err := http.Get(url)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
||||||
|
|
@ -1,38 +1,17 @@
|
||||||
package service
|
package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/yaoapp/yao/config"
|
|
||||||
"github.com/yaoapp/yao/data"
|
|
||||||
"github.com/yaoapp/yao/share"
|
"github.com/yaoapp/yao/share"
|
||||||
)
|
)
|
||||||
|
|
||||||
// XGenFileServerV0 XGen v0.9
|
|
||||||
var XGenFileServerV0 http.Handler = http.FileServer(data.XgenV0())
|
|
||||||
|
|
||||||
// XGenFileServerV1 XGen v1.0
|
|
||||||
var XGenFileServerV1 http.Handler = http.FileServer(data.XgenV1())
|
|
||||||
|
|
||||||
// AppFileServer 应用静态文件
|
|
||||||
var AppFileServer http.Handler = http.FileServer(http.Dir(filepath.Join(config.Conf.Root, "ui")))
|
|
||||||
|
|
||||||
// Middlewares 服务中间件
|
// Middlewares 服务中间件
|
||||||
var Middlewares = []gin.HandlerFunc{
|
var Middlewares = []gin.HandlerFunc{
|
||||||
// BindDomain,
|
|
||||||
BinStatic,
|
BinStatic,
|
||||||
}
|
}
|
||||||
|
|
||||||
// AdminRoot cache
|
|
||||||
var AdminRoot = ""
|
|
||||||
|
|
||||||
// AdminRootLen cache
|
|
||||||
var AdminRootLen = 0
|
|
||||||
|
|
||||||
// BinStatic 静态文件服务
|
// BinStatic 静态文件服务
|
||||||
func BinStatic(c *gin.Context) {
|
func BinStatic(c *gin.Context) {
|
||||||
|
|
||||||
|
|
@ -44,10 +23,10 @@ func BinStatic(c *gin.Context) {
|
||||||
return
|
return
|
||||||
|
|
||||||
} else if share.App.XGen == "1.0" {
|
} else if share.App.XGen == "1.0" {
|
||||||
|
|
||||||
// Xgen 1.0
|
// Xgen 1.0
|
||||||
adminRoot, adminRootLen := adminRoot()
|
if length >= AdminRootLen && c.Request.URL.Path[0:AdminRootLen] == AdminRoot {
|
||||||
if length >= adminRootLen && c.Request.URL.Path[0:adminRootLen] == adminRoot {
|
c.Request.URL.Path = strings.TrimPrefix(c.Request.URL.Path, c.Request.URL.Path[0:AdminRootLen-1])
|
||||||
c.Request.URL.Path = strings.TrimPrefix(c.Request.URL.Path, c.Request.URL.Path[0:adminRootLen-1])
|
|
||||||
XGenFileServerV1.ServeHTTP(c.Writer, c.Request)
|
XGenFileServerV1.ServeHTTP(c.Writer, c.Request)
|
||||||
c.Abort()
|
c.Abort()
|
||||||
return
|
return
|
||||||
|
|
@ -69,24 +48,7 @@ func BinStatic(c *gin.Context) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 应用内静态文件目录(/ui)
|
// 应用内静态文件目录(/ui or public)
|
||||||
AppFileServer.ServeHTTP(c.Writer, c.Request)
|
AppFileServer.ServeHTTP(c.Writer, c.Request)
|
||||||
c.Abort()
|
c.Abort()
|
||||||
}
|
}
|
||||||
|
|
||||||
func adminRoot() (string, int) {
|
|
||||||
if AdminRoot != "" {
|
|
||||||
return AdminRoot, AdminRootLen
|
|
||||||
}
|
|
||||||
|
|
||||||
adminRoot := "/yao/"
|
|
||||||
if share.App.AdminRoot != "" {
|
|
||||||
root := strings.TrimPrefix(share.App.AdminRoot, "/")
|
|
||||||
root = strings.TrimSuffix(root, "/")
|
|
||||||
adminRoot = fmt.Sprintf("/%s/", root)
|
|
||||||
}
|
|
||||||
adminRootLen := len(adminRoot)
|
|
||||||
AdminRoot = adminRoot
|
|
||||||
AdminRootLen = adminRootLen
|
|
||||||
return AdminRoot, AdminRootLen
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -10,12 +10,13 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var shutdown = make(chan bool, 1)
|
var shutdown = make(chan bool, 1)
|
||||||
|
|
||||||
var shutdownComplete = make(chan bool, 1)
|
var shutdownComplete = make(chan bool, 1)
|
||||||
|
|
||||||
// Start 启动服务
|
// Start 启动服务
|
||||||
func Start() error {
|
func Start() error {
|
||||||
|
|
||||||
err := share.SessionStart()
|
err := prepare()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -84,3 +85,19 @@ func StopWithContext(ctx context.Context, onComplete func()) {
|
||||||
onComplete()
|
onComplete()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func prepare() error {
|
||||||
|
|
||||||
|
// Session server
|
||||||
|
err := share.SessionStart()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = SetupStatic()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
||||||
126
service/static.go
Normal file
126
service/static.go
Normal file
|
|
@ -0,0 +1,126 @@
|
||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io/fs"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/yaoapp/yao/config"
|
||||||
|
"github.com/yaoapp/yao/data"
|
||||||
|
"github.com/yaoapp/yao/share"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AppFileServer static file server
|
||||||
|
var AppFileServer http.Handler
|
||||||
|
|
||||||
|
// XGenFileServerV0 XGen v0.9
|
||||||
|
var XGenFileServerV0 http.Handler = http.FileServer(data.XgenV0())
|
||||||
|
|
||||||
|
// XGenFileServerV1 XGen v1.0
|
||||||
|
var XGenFileServerV1 http.Handler = http.FileServer(data.XgenV1())
|
||||||
|
|
||||||
|
// AdminRoot cache
|
||||||
|
var AdminRoot = ""
|
||||||
|
|
||||||
|
// AdminRootLen cache
|
||||||
|
var AdminRootLen = 0
|
||||||
|
|
||||||
|
// Dir files
|
||||||
|
type Dir string
|
||||||
|
|
||||||
|
// SetupStatic setup static file server
|
||||||
|
func SetupStatic() error {
|
||||||
|
|
||||||
|
// SetAdmin Root
|
||||||
|
adminRoot()
|
||||||
|
|
||||||
|
// Static file server
|
||||||
|
AppFileServer = http.FileServer(Dir(filepath.Join(config.Conf.Root, "public")))
|
||||||
|
if share.App.XGen == "" || share.App.XGen == "0.9" {
|
||||||
|
AppFileServer = http.FileServer(Dir(filepath.Join(config.Conf.Root, "ui")))
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open implements FileSystem using os.Open, opening files for reading rooted
|
||||||
|
// and relative to the directory d.
|
||||||
|
func (d Dir) Open(name string) (http.File, error) {
|
||||||
|
if filepath.Separator != '/' && strings.ContainsRune(name, filepath.Separator) {
|
||||||
|
return nil, errors.New("http: invalid character in file path")
|
||||||
|
}
|
||||||
|
|
||||||
|
dir := string(d)
|
||||||
|
if dir == "" {
|
||||||
|
dir = "."
|
||||||
|
}
|
||||||
|
|
||||||
|
fullName := filepath.Join(dir, filepath.FromSlash(path.Clean("/"+name)))
|
||||||
|
|
||||||
|
// Close dir views Disable directory listing
|
||||||
|
stat, err := os.Stat(fullName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, mapOpenError(err, fullName, filepath.Separator, os.Stat)
|
||||||
|
}
|
||||||
|
|
||||||
|
if stat.IsDir() {
|
||||||
|
indexFile := filepath.Join(fullName, "index.html")
|
||||||
|
if _, err := os.Stat(indexFile); os.IsNotExist(err) {
|
||||||
|
return nil, mapOpenError(fs.ErrNotExist, fullName, filepath.Separator, os.Stat)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
f, err := os.Open(fullName)
|
||||||
|
if err != nil {
|
||||||
|
return nil, mapOpenError(err, fullName, filepath.Separator, os.Stat)
|
||||||
|
}
|
||||||
|
|
||||||
|
return f, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// mapOpenError maps the provided non-nil error from opening name
|
||||||
|
// to a possibly better non-nil error. In particular, it turns OS-specific errors
|
||||||
|
// about opening files in non-directories into fs.ErrNotExist. See Issues 18984 and 49552.
|
||||||
|
func mapOpenError(originalErr error, name string, sep rune, stat func(string) (fs.FileInfo, error)) error {
|
||||||
|
if errors.Is(originalErr, fs.ErrNotExist) || errors.Is(originalErr, fs.ErrPermission) {
|
||||||
|
return originalErr
|
||||||
|
}
|
||||||
|
|
||||||
|
parts := strings.Split(name, string(sep))
|
||||||
|
for i := range parts {
|
||||||
|
if parts[i] == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fi, err := stat(strings.Join(parts[:i+1], string(sep)))
|
||||||
|
if err != nil {
|
||||||
|
return originalErr
|
||||||
|
}
|
||||||
|
if !fi.IsDir() {
|
||||||
|
return fs.ErrNotExist
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return originalErr
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetupAdmin setup admin static root
|
||||||
|
func adminRoot() (string, int) {
|
||||||
|
if AdminRoot != "" {
|
||||||
|
return AdminRoot, AdminRootLen
|
||||||
|
}
|
||||||
|
|
||||||
|
adminRoot := "/yao/"
|
||||||
|
if share.App.AdminRoot != "" {
|
||||||
|
root := strings.TrimPrefix(share.App.AdminRoot, "/")
|
||||||
|
root = strings.TrimSuffix(root, "/")
|
||||||
|
adminRoot = fmt.Sprintf("/%s/", root)
|
||||||
|
}
|
||||||
|
adminRootLen := len(adminRoot)
|
||||||
|
AdminRoot = adminRoot
|
||||||
|
AdminRootLen = adminRootLen
|
||||||
|
return AdminRoot, AdminRootLen
|
||||||
|
}
|
||||||
|
|
@ -215,14 +215,14 @@ func watchModel(root string, file string, event string, cfg config.Config) {
|
||||||
fmt.Println(color.RedString("[Watch] Model: %s %s", name, err.Error()))
|
fmt.Println(color.RedString("[Watch] Model: %s %s", name, err.Error()))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mod, err := gou.LoadModelReturn(string(content), name)
|
_, err = gou.LoadModelReturn(string(content), name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(color.RedString("[Watch] Model: %s %s", name, err.Error()))
|
fmt.Println(color.RedString("[Watch] Model: %s %s", name, err.Error()))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
mod.Migrate(true)
|
// mod.Migrate(true)
|
||||||
fmt.Println(color.GreenString("[Watch] Model: %s Created", name))
|
fmt.Println(color.GreenString("[Watch] Model: %s Created (Please run yao migrate manually)", name))
|
||||||
break
|
break
|
||||||
|
|
||||||
case "WRITE":
|
case "WRITE":
|
||||||
|
|
@ -231,13 +231,13 @@ func watchModel(root string, file string, event string, cfg config.Config) {
|
||||||
fmt.Println(color.RedString("[Watch] Model: %s %s", name, err.Error()))
|
fmt.Println(color.RedString("[Watch] Model: %s %s", name, err.Error()))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mod, err := gou.LoadModelReturn(string(content), name)
|
_, err = gou.LoadModelReturn(string(content), name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(color.RedString("[Watch] Model: %s %s", name, err.Error()))
|
fmt.Println(color.RedString("[Watch] Model: %s %s", name, err.Error()))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mod.Migrate(false)
|
// mod.Migrate(false)
|
||||||
fmt.Println(color.GreenString("[Watch] Model: %s Reloaded", name))
|
fmt.Println(color.GreenString("[Watch] Model: %s Reloaded (Please run yao migrate manually)", name))
|
||||||
break
|
break
|
||||||
|
|
||||||
case "REMOVE", "RENAME":
|
case "REMOVE", "RENAME":
|
||||||
|
|
|
||||||
105
setup/check.go
Normal file
105
setup/check.go
Normal file
|
|
@ -0,0 +1,105 @@
|
||||||
|
package setup
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/yaoapp/gou/connector"
|
||||||
|
"github.com/yaoapp/yao/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Check setup programe
|
||||||
|
func Check() bool {
|
||||||
|
|
||||||
|
root := appRoot()
|
||||||
|
|
||||||
|
appfile := filepath.Join(root, "app.json")
|
||||||
|
if _, err := os.Stat(appfile); err != nil && os.IsNotExist(err) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
envfile := filepath.Join(root, ".env")
|
||||||
|
if _, err := os.Stat(envfile); err != nil && os.IsNotExist(err) {
|
||||||
|
cfg, err := getConfig()
|
||||||
|
if err != nil || !hasInstalled(cfg) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate db link
|
||||||
|
func Validate() (err error) {
|
||||||
|
|
||||||
|
root := appRoot()
|
||||||
|
path := filepath.Join(root, "db", "yao.db")
|
||||||
|
|
||||||
|
data := []byte(fmt.Sprintf(`{
|
||||||
|
"type": "sqlite3",
|
||||||
|
"options": {
|
||||||
|
"file": "%s"
|
||||||
|
}
|
||||||
|
}`, path))
|
||||||
|
|
||||||
|
data = []byte(`{
|
||||||
|
"type": "mysql",
|
||||||
|
"options": {
|
||||||
|
"db": "test",
|
||||||
|
"hosts": [{ "host": "127.0.0.1", "user":"root", "pass":"123456" }]
|
||||||
|
}
|
||||||
|
}`)
|
||||||
|
|
||||||
|
_, err = connector.Load(string(data), "test")
|
||||||
|
return err
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func appRoot() string {
|
||||||
|
|
||||||
|
root := os.Getenv("YAO_ROOT")
|
||||||
|
if root == "" {
|
||||||
|
path, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
printError("无法获取应用目录: %s", err)
|
||||||
|
Stop()
|
||||||
|
}
|
||||||
|
root = path
|
||||||
|
}
|
||||||
|
|
||||||
|
root, err := filepath.Abs(root)
|
||||||
|
if err != nil {
|
||||||
|
printError("无法获取应用目录: %s", err)
|
||||||
|
Stop()
|
||||||
|
}
|
||||||
|
|
||||||
|
return root
|
||||||
|
}
|
||||||
|
|
||||||
|
func getConfig() (config.Config, error) {
|
||||||
|
root := appRoot()
|
||||||
|
envfile := filepath.Join(root, ".env")
|
||||||
|
cfg := config.LoadFrom(envfile)
|
||||||
|
return cfg, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func hasInstalled(cfg config.Config) bool {
|
||||||
|
|
||||||
|
switch cfg.DB.Driver {
|
||||||
|
|
||||||
|
case "sqlite3":
|
||||||
|
if cfg.DB.Primary != nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
break
|
||||||
|
|
||||||
|
case "mysql":
|
||||||
|
if cfg.DB.Primary != nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
14
setup/check_test.go
Normal file
14
setup/check_test.go
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
package setup
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestValidate(t *testing.T) {
|
||||||
|
// err := Validate()
|
||||||
|
// fmt.Println(err)
|
||||||
|
|
||||||
|
// if err != nil {
|
||||||
|
// t.Fatal(err)
|
||||||
|
// }
|
||||||
|
}
|
||||||
65
setup/env.go
Normal file
65
setup/env.go
Normal file
|
|
@ -0,0 +1,65 @@
|
||||||
|
package setup
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/joho/godotenv"
|
||||||
|
)
|
||||||
|
|
||||||
|
func envSet(file, name, value string) error {
|
||||||
|
|
||||||
|
file, err := filepath.Abs(file)
|
||||||
|
if err != nil {
|
||||||
|
dir := filepath.Dir(file)
|
||||||
|
err := os.MkdirAll(dir, os.ModePerm)
|
||||||
|
if err != nil && !os.IsExist(err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := os.Stat(file); err != nil && os.IsNotExist(err) {
|
||||||
|
err = os.WriteFile(file, []byte{}, 0644)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = godotenv.Write(map[string]string{"YAO_ENV": "development"}, file)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vars, err := godotenv.Read(file)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
vars[name] = value
|
||||||
|
return godotenv.Write(vars, file)
|
||||||
|
}
|
||||||
|
|
||||||
|
func envGet(file, name string) (string, error) {
|
||||||
|
|
||||||
|
v := os.Getenv(name)
|
||||||
|
if v != "" {
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
vars, err := godotenv.Read(file)
|
||||||
|
if err == nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return vars[name], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func envHas(file, name string) (bool, error) {
|
||||||
|
|
||||||
|
v, err := envGet(file, name)
|
||||||
|
if err != nil {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return v != "", nil
|
||||||
|
}
|
||||||
115
setup/handler.go
Normal file
115
setup/handler.go
Normal file
|
|
@ -0,0 +1,115 @@
|
||||||
|
package setup
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/yaoapp/kun/exception"
|
||||||
|
"github.com/yaoapp/xun"
|
||||||
|
)
|
||||||
|
|
||||||
|
// recovered custom recovered
|
||||||
|
func recovered(c *gin.Context, recovered interface{}) {
|
||||||
|
|
||||||
|
var code = http.StatusInternalServerError
|
||||||
|
|
||||||
|
if err, ok := recovered.(string); ok {
|
||||||
|
c.JSON(code, xun.R{
|
||||||
|
"code": code,
|
||||||
|
"message": fmt.Sprintf("%s", err),
|
||||||
|
})
|
||||||
|
} else if err, ok := recovered.(exception.Exception); ok {
|
||||||
|
code = err.Code
|
||||||
|
c.JSON(code, xun.R{
|
||||||
|
"code": code,
|
||||||
|
"message": err.Message,
|
||||||
|
})
|
||||||
|
} else if err, ok := recovered.(*exception.Exception); ok {
|
||||||
|
code = err.Code
|
||||||
|
c.JSON(code, xun.R{
|
||||||
|
"code": code,
|
||||||
|
"message": err.Message,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
c.JSON(code, xun.R{
|
||||||
|
"code": code,
|
||||||
|
"message": fmt.Sprintf("%v", recovered),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
c.AbortWithStatus(code)
|
||||||
|
}
|
||||||
|
|
||||||
|
// {
|
||||||
|
// "env": {
|
||||||
|
// "YAO_LANG": "中文",
|
||||||
|
// "YAO_ENV": "开发模式(推荐)",
|
||||||
|
// "YAO_PORT": "5099",
|
||||||
|
// "YAO_STUDIO_PORT": "5077"
|
||||||
|
// },
|
||||||
|
// "db": {
|
||||||
|
// "type": "sqlite",
|
||||||
|
// "option.file": "db/yao.db"
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
func runSetup(c *gin.Context) {
|
||||||
|
|
||||||
|
payload := getPayload(c)
|
||||||
|
|
||||||
|
cfg, err := getConfig()
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(500, gin.H{"code": 500, "message": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if hasInstalled(cfg) {
|
||||||
|
c.JSON(403, gin.H{"code": 400, "message": "应用已安装, 删除 .env 文件后重试"})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = Install(payload)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(500, gin.H{"code": 500, "message": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reload Config
|
||||||
|
cfg, err = getConfig()
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(500, gin.H{"code": 500, "message": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return
|
||||||
|
urls, err := AdminURL(cfg)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(500, gin.H{"code": 500, "message": err.Error()})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(200, gin.H{
|
||||||
|
"code": 200,
|
||||||
|
"message": "安装成功",
|
||||||
|
"urls": urls,
|
||||||
|
})
|
||||||
|
|
||||||
|
Complete()
|
||||||
|
}
|
||||||
|
|
||||||
|
func runCheck(c *gin.Context) {
|
||||||
|
time.Sleep(2 * time.Second)
|
||||||
|
c.JSON(200, gin.H{"code": 200})
|
||||||
|
}
|
||||||
|
|
||||||
|
func getPayload(c *gin.Context) map[string]map[string]string {
|
||||||
|
var payload map[string]map[string]string
|
||||||
|
err := c.ShouldBindJSON(&payload)
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(500, gin.H{"code": 400, "message": err.Error()})
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return payload
|
||||||
|
}
|
||||||
1254
setup/install.go
Normal file
1254
setup/install.go
Normal file
File diff suppressed because it is too large
Load diff
12
setup/install_test.go
Normal file
12
setup/install_test.go
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
package setup
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestInstall(t *testing.T) {
|
||||||
|
// err := Install()
|
||||||
|
// if err != nil {
|
||||||
|
// t.Fatal(err)
|
||||||
|
// }
|
||||||
|
}
|
||||||
230
setup/setup.go
Normal file
230
setup/setup.go
Normal file
|
|
@ -0,0 +1,230 @@
|
||||||
|
package setup
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"os/signal"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/fatih/color"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/yaoapp/yao/config"
|
||||||
|
"github.com/yaoapp/yao/data"
|
||||||
|
"github.com/yaoapp/yao/engine"
|
||||||
|
"github.com/yaoapp/yao/share"
|
||||||
|
"github.com/yaoapp/yao/widgets/app"
|
||||||
|
)
|
||||||
|
|
||||||
|
// XGenSetupServer XGen Setup
|
||||||
|
var XGenSetupServer http.Handler = http.FileServer(data.Setup())
|
||||||
|
|
||||||
|
// Done check done
|
||||||
|
var Done = make(chan bool, 1)
|
||||||
|
|
||||||
|
// shutdown check done
|
||||||
|
var shutdown = make(chan bool, 1)
|
||||||
|
|
||||||
|
// Canceled check if setup is canceld
|
||||||
|
var Canceled = make(chan bool, 1)
|
||||||
|
|
||||||
|
// Start start the studio api server
|
||||||
|
func Start() (err error) {
|
||||||
|
|
||||||
|
// recive interrupt signal
|
||||||
|
interrupt := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(interrupt, os.Interrupt, syscall.SIGTERM, syscall.SIGQUIT)
|
||||||
|
|
||||||
|
errCh := make(chan error, 1)
|
||||||
|
|
||||||
|
// Set router
|
||||||
|
gin.SetMode(gin.ReleaseMode)
|
||||||
|
router := gin.New()
|
||||||
|
|
||||||
|
if os.Getenv("YAO_SETUP_DEV") != "" {
|
||||||
|
fmt.Println(color.WhiteString("\nSETUP DEV: %s\n", os.Getenv("YAO_SETUP_DEV")))
|
||||||
|
}
|
||||||
|
|
||||||
|
router.Use(func(c *gin.Context) {
|
||||||
|
length := len(c.Request.URL.Path)
|
||||||
|
if length >= 5 && c.Request.URL.Path[0:5] == "/api/" {
|
||||||
|
c.Next()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if os.Getenv("YAO_SETUP_DEV") != "" {
|
||||||
|
root, err := filepath.Abs(os.Getenv("YAO_SETUP_DEV"))
|
||||||
|
if err != nil {
|
||||||
|
printError("%s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
static := http.FileServer(http.Dir(root))
|
||||||
|
static.ServeHTTP(c.Writer, c.Request)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup Pages
|
||||||
|
XGenSetupServer.ServeHTTP(c.Writer, c.Request)
|
||||||
|
return
|
||||||
|
}, gin.CustomRecovery(recovered))
|
||||||
|
|
||||||
|
router.POST("/api/__yao/app/check", runCheck)
|
||||||
|
router.POST("/api/__yao/app/setup", runSetup)
|
||||||
|
|
||||||
|
// Server setting
|
||||||
|
addr := ":5099"
|
||||||
|
|
||||||
|
// Listen
|
||||||
|
l, err := net.Listen("tcp4", addr)
|
||||||
|
if err != nil {
|
||||||
|
addr = ":0"
|
||||||
|
l, err = net.Listen("tcp4", addr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
srv := &http.Server{
|
||||||
|
Addr: addr,
|
||||||
|
Handler: router,
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
// printInfo("[Setup] %s Close Serve", addr)
|
||||||
|
err = srv.Close()
|
||||||
|
if err != nil {
|
||||||
|
printError("[Setup] Error (%v)", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// start serve
|
||||||
|
go func() {
|
||||||
|
// printInfo("[Setup] Starting: %s", addr)
|
||||||
|
if err := srv.Serve(l); err != nil && err != http.ErrServerClosed {
|
||||||
|
errCh <- err
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
welcome(l)
|
||||||
|
|
||||||
|
select {
|
||||||
|
|
||||||
|
case <-shutdown:
|
||||||
|
printInfo("Setup Shutdown")
|
||||||
|
return err
|
||||||
|
|
||||||
|
case <-interrupt:
|
||||||
|
printInfo("Setup Interrupt")
|
||||||
|
Canceled <- true
|
||||||
|
return err
|
||||||
|
|
||||||
|
case err := <-errCh:
|
||||||
|
printError("Setup Error: ", err)
|
||||||
|
Canceled <- true
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Complete stop the studio api server
|
||||||
|
func Complete() {
|
||||||
|
Done <- true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop stop the studio api server
|
||||||
|
func Stop() {
|
||||||
|
shutdown <- true
|
||||||
|
}
|
||||||
|
|
||||||
|
// AdminURL get admin url
|
||||||
|
func AdminURL(cfg config.Config) ([]string, error) {
|
||||||
|
err := engine.Load(cfg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
urls, err := URLs(cfg)
|
||||||
|
|
||||||
|
adminRoot := "yao"
|
||||||
|
if app.Setting.AdminRoot != "" {
|
||||||
|
adminRoot = app.Setting.AdminRoot
|
||||||
|
}
|
||||||
|
adminRoot = strings.Trim(adminRoot, "/")
|
||||||
|
|
||||||
|
for i := range urls {
|
||||||
|
urls[i] = fmt.Sprintf("%s/%s/", urls[i], adminRoot)
|
||||||
|
}
|
||||||
|
return urls, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// URLs get admin url
|
||||||
|
func URLs(cfg config.Config) ([]string, error) {
|
||||||
|
err := engine.Load(cfg)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ips, err := Ips()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range ips {
|
||||||
|
ips[i] = fmt.Sprintf("http://%s:%d", ips[i], cfg.Port)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ips, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func welcome(l net.Listener) {
|
||||||
|
fmt.Println(color.WhiteString("---------------------------------"))
|
||||||
|
fmt.Println(color.WhiteString("Yao Application Setup v%s", share.VERSION))
|
||||||
|
fmt.Println(color.WhiteString("---------------------------------"))
|
||||||
|
|
||||||
|
ips, err := Ips()
|
||||||
|
if err != nil {
|
||||||
|
printError("Error: ", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
addr := strings.Split(l.Addr().String(), ":")
|
||||||
|
if len(addr) != 2 {
|
||||||
|
printError("Error: can't get port")
|
||||||
|
}
|
||||||
|
|
||||||
|
port := addr[1]
|
||||||
|
for _, ip := range ips {
|
||||||
|
fmt.Println(color.WhiteString("\nOpen URL in the browser to continue:\n"))
|
||||||
|
printInfo("http://%s:%s", ip, port)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println()
|
||||||
|
}
|
||||||
|
|
||||||
|
func printError(message string, args ...interface{}) {
|
||||||
|
fmt.Println(color.RedString(message, args...))
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func printInfo(message string, args ...interface{}) {
|
||||||
|
fmt.Println(color.GreenString(message, args...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ips get the local ip list
|
||||||
|
func Ips() ([]string, error) {
|
||||||
|
addrs, err := net.InterfaceAddrs()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
iplist := []string{}
|
||||||
|
for _, address := range addrs {
|
||||||
|
// check the address type and if it is not a loopback the display it
|
||||||
|
if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
|
||||||
|
if ipnet.IP.To4() != nil {
|
||||||
|
iplist = append(iplist, ipnet.IP.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return iplist, nil
|
||||||
|
}
|
||||||
|
|
@ -51,6 +51,26 @@ func (c *Computable) ComputeEdit(name string, process *gou.Process, args []inter
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if columns, ok := args[0].([]interface{}); ok {
|
||||||
|
new := []string{}
|
||||||
|
for _, col := range columns {
|
||||||
|
new = append(new, fmt.Sprintf("%v", col))
|
||||||
|
}
|
||||||
|
args[0] = new
|
||||||
|
}
|
||||||
|
|
||||||
|
if values, ok := args[1].([]interface{}); ok {
|
||||||
|
new := [][]interface{}{}
|
||||||
|
for _, value := range values {
|
||||||
|
arr, ok := value.([]interface{})
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("args[1] is not a [][] %s", reflect.ValueOf(args[1]).Type().Name())
|
||||||
|
}
|
||||||
|
new = append(new, arr)
|
||||||
|
}
|
||||||
|
args[1] = new
|
||||||
|
}
|
||||||
|
|
||||||
if _, ok := args[0].([]string); !ok {
|
if _, ok := args[0].([]string); !ok {
|
||||||
return fmt.Errorf("args[0] is not a []string %s", reflect.ValueOf(args[0]).Type().Name())
|
return fmt.Errorf("args[0] is not a []string %s", reflect.ValueOf(args[0]).Type().Name())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
1
xgen/setup/index.html
Normal file
1
xgen/setup/index.html
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
XGEN SETUP
|
||||||
Loading…
Add table
Reference in a new issue