459 lines
12 KiB
Go
459 lines
12 KiB
Go
package service
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/fatih/color"
|
|
"github.com/yaoapp/gou"
|
|
"github.com/yaoapp/yao/chart"
|
|
"github.com/yaoapp/yao/config"
|
|
"github.com/yaoapp/yao/engine"
|
|
"github.com/yaoapp/yao/page"
|
|
"github.com/yaoapp/yao/share"
|
|
"github.com/yaoapp/yao/table"
|
|
"github.com/yaoapp/yao/workflow"
|
|
)
|
|
|
|
// Watch 监听应用目录文件变更
|
|
func Watch(cfg config.Config) {
|
|
if os.Getenv("YAO_DEV") != "" {
|
|
WatchEngine(filepath.Join(os.Getenv("YAO_DEV"), "/yao"))
|
|
}
|
|
WatchModel(filepath.Join(cfg.Root, "models"), "")
|
|
WatchAPI(filepath.Join(cfg.Root, "apis"), "")
|
|
WatchFlow(filepath.Join(cfg.Root, "flows"), "")
|
|
WatchPlugin(filepath.Join(cfg.Root, "plugins"))
|
|
WatchTable(filepath.Join(cfg.Root, "tables"), "")
|
|
WatchChart(filepath.Join(cfg.Root, "charts"), "")
|
|
WatchPage(filepath.Join(cfg.Root, "pages"), "")
|
|
WatchWorkFlow(filepath.Join(cfg.Root, "workflows"), "")
|
|
|
|
// 看板大屏
|
|
WatchPage(filepath.Join(cfg.Root, "kanban"), "")
|
|
WatchPage(filepath.Join(cfg.Root, "screen"), "")
|
|
|
|
// 监听脚本 & libs更新
|
|
WatchGlobal(filepath.Join(cfg.Root, "libs"))
|
|
WatchGlobal(filepath.Join(cfg.Root, "scripts"))
|
|
}
|
|
|
|
// WatchEngine 监听监听引擎内建数据变更
|
|
func WatchEngine(root string) {
|
|
root = share.DirAbs(root)
|
|
WatchModel(filepath.Join(root, "models"), "xiang.")
|
|
WatchAPI(filepath.Join(root, "apis"), "xiang.")
|
|
WatchFlow(filepath.Join(root, "flows"), "xiang.")
|
|
WatchTable(filepath.Join(root, "tables"), "xiang.")
|
|
}
|
|
|
|
// WatchGlobal 监听通用程序更新
|
|
func WatchGlobal(root string) {
|
|
if share.DirNotExists(root) {
|
|
return
|
|
}
|
|
root = share.DirAbs(root)
|
|
go share.Watch(root, func(op string, filename string) {
|
|
if !strings.HasSuffix(filename, ".json") && !strings.HasSuffix(filename, ".js") {
|
|
return
|
|
}
|
|
|
|
// 重启服务器
|
|
if op == "write" || op == "create" || op == "remove" || op == "rename" {
|
|
err := engine.Load(config.Conf)
|
|
if err != nil {
|
|
fmt.Println(color.RedString("Fatal: %s", err.Error()))
|
|
return
|
|
}
|
|
StopWithouttSession(func() {
|
|
fmt.Println(color.GreenString("Service Restarted"))
|
|
go StartWithouttSession()
|
|
})
|
|
}
|
|
})
|
|
}
|
|
|
|
// WatchModel 监听业务接口更新
|
|
func WatchModel(root string, prefix string) {
|
|
if share.DirNotExists(root) {
|
|
return
|
|
}
|
|
root = share.DirAbs(root)
|
|
go share.Watch(root, func(op string, filename string) {
|
|
|
|
if !strings.HasSuffix(filename, ".json") {
|
|
return
|
|
}
|
|
if op == "write" || op == "create" {
|
|
name := prefix + share.SpecName(root, filename)
|
|
content := share.ReadFile(filename)
|
|
_, err := gou.LoadModelReturn(string(content), name) // Reload
|
|
if err != nil {
|
|
fmt.Println(color.RedString("Fatal: %s", err.Error()))
|
|
return
|
|
}
|
|
fmt.Println(color.GreenString("Model %s Reloaded", name))
|
|
} else if op == "remove" || op == "rename" {
|
|
name := prefix + share.SpecName(root, filename)
|
|
if _, has := gou.Models[name]; has {
|
|
delete(gou.Models, name)
|
|
fmt.Println(color.RedString("Model %s Removed", name))
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
// WatchAPI 监听业务接口更新
|
|
func WatchAPI(root string, prefix string) {
|
|
if share.DirNotExists(root) {
|
|
return
|
|
}
|
|
root = share.DirAbs(root)
|
|
go share.Watch(root, func(op string, filename string) {
|
|
|
|
if !strings.HasSuffix(filename, ".json") {
|
|
return
|
|
}
|
|
|
|
if op == "write" || op == "create" {
|
|
name := prefix + share.SpecName(root, filename)
|
|
content := share.ReadFile(filename)
|
|
_, err := gou.LoadAPIReturn(string(content), name) // Reload
|
|
if err != nil {
|
|
fmt.Println(color.RedString("Fatal: %s", err.Error()))
|
|
return
|
|
}
|
|
fmt.Println(color.GreenString("API %s Reloaded", name))
|
|
|
|
} else if op == "remove" || op == "rename" {
|
|
name := prefix + share.SpecName(root, filename)
|
|
if _, has := gou.APIs[name]; has {
|
|
delete(gou.APIs, name)
|
|
fmt.Println(color.RedString("API %s Removed", name))
|
|
}
|
|
}
|
|
|
|
// 重启服务器
|
|
if op == "write" || op == "create" || op == "remove" || op == "rename" {
|
|
StopWithouttSession(func() {
|
|
fmt.Println(color.GreenString("Service Restarted"))
|
|
go StartWithouttSession()
|
|
})
|
|
}
|
|
})
|
|
}
|
|
|
|
// WatchFlow 监听业务逻辑变更
|
|
func WatchFlow(root string, prefix string) {
|
|
if share.DirNotExists(root) {
|
|
return
|
|
}
|
|
root = share.DirAbs(root)
|
|
go share.Watch(root, func(op string, filename string) {
|
|
if !strings.HasSuffix(filename, ".json") && !strings.HasSuffix(filename, ".js") {
|
|
return
|
|
}
|
|
|
|
if strings.HasSuffix(filename, ".js") {
|
|
name := prefix + share.SpecName(root, filename)
|
|
name = strings.ReplaceAll(name, ".", "/")
|
|
filename = filepath.Join(root, name+".flow.json")
|
|
}
|
|
|
|
if op == "write" || op == "create" {
|
|
name := prefix + share.SpecName(root, filename)
|
|
content := share.ReadFile(filename)
|
|
flow, err := gou.LoadFlowReturn(string(content), name) // Reload
|
|
if err != nil {
|
|
fmt.Println(color.RedString("Fatal: %s", err.Error()))
|
|
return
|
|
}
|
|
|
|
if flow != nil { // Reload Script
|
|
dir := filepath.Dir(filename)
|
|
share.Walk(dir, ".js", func(root, filename string) {
|
|
script := share.ScriptName(filename)
|
|
content := share.ReadFile(filename)
|
|
_, err := flow.LoadScriptReturn(string(content), script)
|
|
if err != nil {
|
|
fmt.Println(color.RedString("Fatal: %s", err.Error()))
|
|
return
|
|
}
|
|
})
|
|
}
|
|
|
|
fmt.Println(color.GreenString("Flow %s Reloaded", name))
|
|
|
|
} else if op == "remove" || op == "rename" {
|
|
name := prefix + share.SpecName(root, filename)
|
|
if _, has := gou.Flows[name]; has {
|
|
delete(gou.Flows, name)
|
|
fmt.Println(color.RedString("Flow %s Removed", name))
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
// WatchPlugin 监听业务插件变更
|
|
func WatchPlugin(root string) {
|
|
if share.DirNotExists(root) {
|
|
return
|
|
}
|
|
root = share.DirAbs(root)
|
|
go share.Watch(root, func(op string, filename string) {
|
|
|
|
if !strings.HasSuffix(filename, ".so") {
|
|
return
|
|
}
|
|
|
|
if op == "write" || op == "create" {
|
|
name := share.SpecName(root, filename)
|
|
_, err := gou.LoadPluginReturn(filename, name) // Reload
|
|
if err != nil {
|
|
fmt.Println(color.RedString("Fatal: %s", err.Error()))
|
|
return
|
|
}
|
|
fmt.Println(color.GreenString("Plugin %s Reloaded", name))
|
|
|
|
} else if op == "remove" || op == "rename" {
|
|
name := share.SpecName(root, filename)
|
|
if _, has := gou.Plugins[name]; has {
|
|
delete(gou.Plugins, name)
|
|
fmt.Println(color.RedString("Plugin %s Removed", name))
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
// WatchTable 监听数据表格更新
|
|
func WatchTable(root string, prefix string) {
|
|
if share.DirNotExists(root) {
|
|
return
|
|
}
|
|
root = share.DirAbs(root)
|
|
go share.Watch(root, func(op string, filename string) {
|
|
|
|
if !strings.HasSuffix(filename, ".json") {
|
|
return
|
|
}
|
|
|
|
if op == "write" || op == "create" {
|
|
name := prefix + share.SpecName(root, filename)
|
|
content := share.ReadFile(filename)
|
|
_, err := table.LoadTable(string(content), name) // Reload Table
|
|
if err != nil {
|
|
fmt.Println(color.RedString("Fatal: %s", err.Error()))
|
|
return
|
|
}
|
|
|
|
api, has := gou.APIs["xiang.table"]
|
|
if has {
|
|
_, err := gou.LoadAPIReturn(api.Source, api.Name)
|
|
if err != nil {
|
|
fmt.Println(color.RedString("Fatal: %s", err.Error()))
|
|
return
|
|
}
|
|
}
|
|
fmt.Println(color.GreenString("Table %s Reloaded", name))
|
|
|
|
} else if op == "remove" || op == "rename" {
|
|
name := prefix + share.SpecName(root, filename)
|
|
if _, has := table.Tables[name]; has {
|
|
delete(table.Tables, name)
|
|
fmt.Println(color.RedString("Table %s Removed", name))
|
|
}
|
|
}
|
|
|
|
// 重启服务器
|
|
if op == "write" || op == "create" || op == "remove" || op == "rename" {
|
|
StopWithouttSession(func() {
|
|
fmt.Println(color.GreenString("Service Restarted"))
|
|
go StartWithouttSession()
|
|
})
|
|
}
|
|
})
|
|
}
|
|
|
|
// WatchChart 监听分析图表更新
|
|
func WatchChart(root string, prefix string) {
|
|
if share.DirNotExists(root) {
|
|
return
|
|
}
|
|
root = share.DirAbs(root)
|
|
go share.Watch(root, func(op string, filename string) {
|
|
if !strings.HasSuffix(filename, ".json") && !strings.HasSuffix(filename, ".js") {
|
|
return
|
|
}
|
|
|
|
if strings.HasSuffix(filename, ".js") {
|
|
name := prefix + share.SpecName(root, filename)
|
|
name = strings.ReplaceAll(name, ".", "/")
|
|
filename = filepath.Join(root, name+".chart.json")
|
|
}
|
|
|
|
if op == "write" || op == "create" {
|
|
name := prefix + share.SpecName(root, filename)
|
|
content := share.ReadFile(filename)
|
|
chart, err := chart.LoadChart(content, name) // Relaod
|
|
if err != nil {
|
|
fmt.Println(color.RedString("Fatal: %s", err.Error()))
|
|
return
|
|
}
|
|
|
|
if chart != nil { // Reload Script
|
|
dir := filepath.Dir(filename)
|
|
share.Walk(dir, ".js", func(root, filename string) {
|
|
script := share.ScriptName(filename)
|
|
content := share.ReadFile(filename)
|
|
_, err := chart.LoadScriptReturn(string(content), script)
|
|
if err != nil {
|
|
fmt.Println(color.RedString("Fatal: %s", err.Error()))
|
|
return
|
|
}
|
|
})
|
|
}
|
|
|
|
api, has := gou.APIs["xiang.chart"]
|
|
if has {
|
|
_, err := gou.LoadAPIReturn(api.Source, api.Name)
|
|
if err != nil {
|
|
fmt.Println(color.RedString("Fatal: %s", err.Error()))
|
|
return
|
|
}
|
|
}
|
|
fmt.Println(color.GreenString("Chart %s Reloaded", name))
|
|
|
|
} else if op == "remove" || op == "rename" {
|
|
name := prefix + share.SpecName(root, filename)
|
|
if _, has := chart.Charts[name]; has {
|
|
delete(chart.Charts, name)
|
|
fmt.Println(color.RedString("Chart %s Removed", name))
|
|
}
|
|
}
|
|
|
|
// 重启服务器
|
|
if op == "write" || op == "create" || op == "remove" || op == "rename" {
|
|
StopWithouttSession(func() {
|
|
fmt.Println(color.GreenString("Service Restarted"))
|
|
go StartWithouttSession()
|
|
})
|
|
}
|
|
})
|
|
}
|
|
|
|
// WatchPage 监听页面更新
|
|
func WatchPage(root string, prefix string) {
|
|
if share.DirNotExists(root) {
|
|
return
|
|
}
|
|
root = share.DirAbs(root)
|
|
go share.Watch(root, func(op string, filename string) {
|
|
if !strings.HasSuffix(filename, ".json") && !strings.HasSuffix(filename, ".js") {
|
|
return
|
|
}
|
|
|
|
if strings.HasSuffix(filename, ".js") {
|
|
name := prefix + share.SpecName(root, filename)
|
|
name = strings.ReplaceAll(name, ".", "/")
|
|
filename = filepath.Join(root, name+".page.json")
|
|
}
|
|
|
|
if op == "write" || op == "create" {
|
|
name := prefix + share.SpecName(root, filename)
|
|
content := share.ReadFile(filename)
|
|
page, err := page.LoadPage(content, name) // Relaod
|
|
if err != nil {
|
|
fmt.Println(color.RedString("Fatal: %s", err.Error()))
|
|
return
|
|
}
|
|
|
|
if page != nil { // Reload Script
|
|
dir := filepath.Dir(filename)
|
|
share.Walk(dir, ".js", func(root, filename string) {
|
|
script := share.ScriptName(filename)
|
|
content := share.ReadFile(filename)
|
|
_, err := page.LoadScriptReturn(string(content), script)
|
|
if err != nil {
|
|
fmt.Println(color.RedString("Fatal: %s", err.Error()))
|
|
return
|
|
}
|
|
})
|
|
}
|
|
|
|
api, has := gou.APIs["xiang.page"]
|
|
if has {
|
|
_, err := gou.LoadAPIReturn(api.Source, api.Name)
|
|
if err != nil {
|
|
fmt.Println(color.RedString("Fatal: %s", err.Error()))
|
|
return
|
|
}
|
|
}
|
|
fmt.Println(color.GreenString("Page %s Reloaded", name))
|
|
|
|
} else if op == "remove" || op == "rename" {
|
|
name := prefix + share.SpecName(root, filename)
|
|
if _, has := page.Pages[name]; has {
|
|
delete(page.Pages, name)
|
|
fmt.Println(color.RedString("Page %s Removed", name))
|
|
}
|
|
}
|
|
|
|
// 重启服务器
|
|
if op == "write" || op == "create" || op == "remove" || op == "rename" {
|
|
StopWithouttSession(func() {
|
|
fmt.Println(color.GreenString("Service Restarted"))
|
|
go StartWithouttSession()
|
|
})
|
|
}
|
|
})
|
|
}
|
|
|
|
// WatchWorkFlow 监听工作流更新
|
|
func WatchWorkFlow(root string, prefix string) {
|
|
if share.DirNotExists(root) {
|
|
return
|
|
}
|
|
root = share.DirAbs(root)
|
|
go share.Watch(root, func(op string, filename string) {
|
|
if !strings.HasSuffix(filename, ".json") {
|
|
return
|
|
}
|
|
|
|
if op == "write" || op == "create" {
|
|
name := prefix + share.SpecName(root, filename)
|
|
content := share.ReadFile(filename)
|
|
_, err := workflow.LoadWorkFlow(content, name) // Relaod
|
|
if err != nil {
|
|
fmt.Println(color.RedString("Fatal: %s", err.Error()))
|
|
return
|
|
}
|
|
|
|
api, has := gou.APIs["xiang.workflow."+name]
|
|
if has {
|
|
_, err := gou.LoadAPIReturn(api.Source, api.Name)
|
|
if err != nil {
|
|
fmt.Println(color.RedString("Fatal: %s", err.Error()))
|
|
return
|
|
}
|
|
}
|
|
fmt.Println(color.GreenString("Workflow %s Reloaded", name))
|
|
|
|
} else if op == "remove" || op == "rename" {
|
|
name := prefix + share.SpecName(root, filename)
|
|
if _, has := workflow.WorkFlows[name]; has {
|
|
delete(workflow.WorkFlows, name)
|
|
fmt.Println(color.RedString("Workflow %s Removed", name))
|
|
}
|
|
}
|
|
|
|
// 重启服务器
|
|
if op == "write" || op == "create" || op == "remove" || op == "rename" {
|
|
StopWithouttSession(func() {
|
|
fmt.Println(color.GreenString("Service Restarted"))
|
|
go StartWithouttSession()
|
|
})
|
|
}
|
|
})
|
|
}
|