升级到 Gou 支持 SQLite
This commit is contained in:
parent
9fa1fa815f
commit
a342cd50b0
12 changed files with 265 additions and 72 deletions
|
|
@ -4,18 +4,20 @@ import (
|
|||
"github.com/spf13/cobra"
|
||||
"github.com/yaoapp/kun/maps"
|
||||
"github.com/yaoapp/kun/utils"
|
||||
"github.com/yaoapp/xiang/config"
|
||||
"github.com/yaoapp/xiang/global"
|
||||
)
|
||||
|
||||
var infoCmd = &cobra.Command{
|
||||
Use: "info",
|
||||
var inspectCmd = &cobra.Command{
|
||||
Use: "inspect",
|
||||
Short: "显示当前配置信息",
|
||||
Long: `显示当前配置信息`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
Boot()
|
||||
res := maps.Map{
|
||||
"version": global.VERSION,
|
||||
"domain": global.DOMAIN,
|
||||
"config": global.Conf,
|
||||
"config": config.Conf,
|
||||
}
|
||||
utils.Dump(res)
|
||||
},
|
||||
|
|
@ -1,9 +1,13 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/yaoapp/gou"
|
||||
"github.com/yaoapp/kun/utils"
|
||||
"github.com/yaoapp/xiang/config"
|
||||
"github.com/yaoapp/xiang/global"
|
||||
)
|
||||
|
||||
var name string
|
||||
|
|
@ -12,6 +16,9 @@ var migrateCmd = &cobra.Command{
|
|||
Short: "更新数据结构",
|
||||
Long: `更新数据库结构`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
Boot()
|
||||
// 加载数据模型
|
||||
global.Load(config.Conf)
|
||||
|
||||
if name != "" {
|
||||
mod, has := gou.Models[name]
|
||||
|
|
@ -22,8 +29,8 @@ var migrateCmd = &cobra.Command{
|
|||
}
|
||||
|
||||
// Do Stuff Here
|
||||
for name, mod := range gou.Models {
|
||||
utils.Dump(name)
|
||||
for _, mod := range gou.Models {
|
||||
fmt.Println(color.GreenString("更新数据模型 %s 绑定数据表: %s", mod.Name, mod.MetaData.Table.Name))
|
||||
mod.Migrate(true)
|
||||
}
|
||||
},
|
||||
|
|
|
|||
28
cmd/root.go
28
cmd/root.go
|
|
@ -3,10 +3,15 @@ package cmd
|
|||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/yaoapp/xiang/config"
|
||||
)
|
||||
|
||||
var appPath string
|
||||
var envFile string
|
||||
|
||||
var rootCmd = &cobra.Command{
|
||||
Use: "xiang",
|
||||
Short: "象传应用引擎命令行工具",
|
||||
|
|
@ -27,12 +32,12 @@ func init() {
|
|||
versionCmd,
|
||||
domainCmd,
|
||||
migrateCmd,
|
||||
infoCmd,
|
||||
inspectCmd,
|
||||
startCmd,
|
||||
)
|
||||
|
||||
rootCmd.SetHelpCommand(helpCmd)
|
||||
|
||||
rootCmd.PersistentFlags().StringVarP(&appPath, "app", "a", "", "指定应用目录")
|
||||
rootCmd.PersistentFlags().StringVarP(&envFile, "env", "e", "", "指定环境变量文件")
|
||||
}
|
||||
|
||||
// Execute 运行Root
|
||||
|
|
@ -42,3 +47,20 @@ func Execute() {
|
|||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
// Boot 设定配置
|
||||
func Boot() {
|
||||
|
||||
if envFile == "" && appPath != "" {
|
||||
config.SetAppPath(appPath, filepath.Join(appPath, ".env"))
|
||||
return
|
||||
}
|
||||
|
||||
if envFile != "" { // 指定环境变量文件
|
||||
config.SetEnvFile(envFile)
|
||||
}
|
||||
|
||||
if appPath != "" {
|
||||
config.SetAppPath(appPath)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
78
cmd/start.go
78
cmd/start.go
|
|
@ -1,50 +1,68 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"log"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/yaoapp/gou"
|
||||
"github.com/yaoapp/xiang/config"
|
||||
"github.com/yaoapp/xiang/global"
|
||||
)
|
||||
|
||||
var startAppPath string
|
||||
var startCmd = &cobra.Command{
|
||||
Use: "start",
|
||||
Short: "启动象传应用引擎",
|
||||
Long: `启动象传应用引擎`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
defer global.ServiceStop(func() { log.Println("服务已关闭") })
|
||||
log.Printf("启动象传应用引擎 v%s mode=%s", global.VERSION, global.Conf.Mode)
|
||||
log.Printf("应用根目录: %s", global.Conf.Root)
|
||||
defer global.ServiceStop(func() { fmt.Println("服务已关闭") })
|
||||
|
||||
// 应用目录
|
||||
if startAppPath != "" {
|
||||
global.Conf.Root = startAppPath
|
||||
global.Conf.RootAPI = filepath.Join(startAppPath, "/apis")
|
||||
global.Conf.RootFLow = filepath.Join(startAppPath, "/flows")
|
||||
global.Conf.RootModel = filepath.Join(startAppPath, "/models")
|
||||
global.Conf.RootPlugin = filepath.Join(startAppPath, "/plugins")
|
||||
global.Conf.RootTable = filepath.Join(startAppPath, "/tables")
|
||||
global.Conf.RootChart = filepath.Join(startAppPath, "/charts")
|
||||
global.Conf.RootScreen = filepath.Join(startAppPath, "/screens")
|
||||
global.Conf.RootData = filepath.Join(startAppPath, "/data")
|
||||
|
||||
// 重新加载应用
|
||||
global.Reload(global.Conf)
|
||||
Boot()
|
||||
mode := config.Conf.Mode
|
||||
if mode == "debug" {
|
||||
mode = color.RedString("调试模式")
|
||||
} else {
|
||||
mode = ""
|
||||
}
|
||||
|
||||
// 启动服务
|
||||
for _, api := range gou.APIs {
|
||||
log.Printf("%s(%d)", api.Name, len(api.HTTP.Paths))
|
||||
fmt.Printf(color.GreenString("\n象传应用引擎 v%s %s", global.VERSION, mode))
|
||||
|
||||
// 加载数据模型 API 等
|
||||
global.Load(config.Conf)
|
||||
|
||||
// 打印应用目录信息
|
||||
fmt.Printf(color.GreenString("\n应用根目录: %s\n", config.Conf.Root))
|
||||
for _, api := range gou.APIs { // API信息
|
||||
fmt.Printf(color.CyanString("\n%s(%d)\n", api.Name, len(api.HTTP.Paths)))
|
||||
for _, p := range api.HTTP.Paths {
|
||||
log.Println(p.Method, filepath.Join("/api", api.HTTP.Group, p.Path), "\tprocess:", p.Process)
|
||||
|
||||
fmt.Println(
|
||||
colorMehtod(p.Method),
|
||||
color.WhiteString(filepath.Join("/api", api.HTTP.Group, p.Path)),
|
||||
"\tprocess:", p.Process)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
domain := global.DOMAIN
|
||||
if domain == "*.iqka.com" {
|
||||
domain = "local.iqka.com"
|
||||
}
|
||||
|
||||
port := fmt.Sprintf(":%d", config.Conf.Service.Port)
|
||||
if port == ":80" {
|
||||
port = ""
|
||||
}
|
||||
|
||||
fmt.Printf(color.GreenString("\n前台界面: http://%s%s/\n", domain, port))
|
||||
fmt.Printf(color.GreenString("管理后台: http://%s%s/xiang/login\n", domain, port))
|
||||
fmt.Printf(color.GreenString("API 接口: http://%s%s/api\n", domain, port))
|
||||
fmt.Printf(color.GreenString("跨域访问: %s\n\n", strings.Join(config.Conf.Service.Allow, ",")))
|
||||
|
||||
// 调试模式
|
||||
if global.Conf.Mode == "debug" {
|
||||
if config.Conf.Mode == "debug" {
|
||||
global.WatchChanges()
|
||||
}
|
||||
|
||||
|
|
@ -52,6 +70,14 @@ var startCmd = &cobra.Command{
|
|||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
startCmd.PersistentFlags().StringVarP(&startAppPath, "app", "a", "", "指定应用目录")
|
||||
func colorMehtod(method string) string {
|
||||
method = strings.ToUpper(method)
|
||||
switch method {
|
||||
case "GET":
|
||||
return color.GreenString("GET")
|
||||
case "POST":
|
||||
return color.YellowString("POST")
|
||||
default:
|
||||
return color.WhiteString(method)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ import (
|
|||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/caarlos0/env/v6"
|
||||
"github.com/joho/godotenv"
|
||||
|
|
@ -30,6 +32,8 @@ type XiangConfig struct {
|
|||
Source string `json:"source,omitempty" env:"XIANG_SOURCE" envDefault:"fs://."` // 源码路径(用于单元测试载入数据)
|
||||
Path string `json:"path,omitempty" env:"XIANG_PATH" envDefault:"bin://xiang"` // 引擎文件目录
|
||||
Root string `json:"root,omitempty" env:"XIANG_ROOT" envDefault:"fs://."` // 应用文件目录
|
||||
RootUI string `json:"root_ui,omitempty" env:"XIANG_ROOT_UI"` // 应用界面静态文件目录
|
||||
RootDB string `json:"root_db,omitempty" env:"XIANG_ROOT_DB"` // 应用SQLite数据库目录
|
||||
RootData string `json:"root_data,omitempty" env:"XIANG_ROOT_DATA"` // 应用数据文件目录
|
||||
RootAPI string `json:"root_api,omitempty" env:"XIANG_ROOT_API"` // 应用API文件目录
|
||||
RootModel string `json:"root_model,omitempty" env:"XIANG_ROOT_MODEL"` // 应用模型文件目录
|
||||
|
|
@ -54,10 +58,11 @@ type ServiceConfig struct {
|
|||
|
||||
// DatabaseConfig 数据库配置
|
||||
type DatabaseConfig struct {
|
||||
Debug bool `json:"debug,omitempty" env:"XIANG_DB_DEBUG" envDefault:"false"` // DEBUG 开关
|
||||
Primary []string `json:"primary,omitempty" env:"XIANG_DB_PRIMARY" envSeparator:"|"` // 主库连接DSN
|
||||
Secondary []string `json:"secondary,omitempty" env:"XIANG_DB_SECONDARY" envSeparator:"|"` // 从库连接DSN
|
||||
AESKey string `json:"aeskey,omitempty" env:"XIANG_DB_AESKEY"` // 加密存储KEY
|
||||
Debug bool `json:"debug,omitempty" env:"XIANG_DB_DEBUG" envDefault:"false"` // DEBUG 开关
|
||||
Driver string `json:"driver,omitempty" env:"XIANG_DB_DRIVER" envDefault:"sqlite3"` // 数据库驱动 ( sqlite3, mysql, postgres)
|
||||
Primary []string `json:"primary,omitempty" env:"XIANG_DB_PRIMARY" envSeparator:"|" envDefault:"file:xiang.db?cache=shared&mode=memory"` // 主库连接DSN
|
||||
Secondary []string `json:"secondary,omitempty" env:"XIANG_DB_SECONDARY" envSeparator:"|"` // 从库连接DSN
|
||||
AESKey string `json:"aeskey,omitempty" env:"XIANG_DB_AESKEY"` // 加密存储KEY
|
||||
}
|
||||
|
||||
// StorageConfig 存储配置
|
||||
|
|
@ -81,15 +86,25 @@ type LogConfig struct {
|
|||
}
|
||||
|
||||
// NewConfig 创建配置文件
|
||||
func NewConfig() Config {
|
||||
func NewConfig(envfile ...string) Config {
|
||||
|
||||
filename := os.Getenv("XIANG_ENV_FILE")
|
||||
if filename == "" {
|
||||
filename = ".env"
|
||||
}
|
||||
|
||||
err := godotenv.Load(filename)
|
||||
if len(envfile) > 0 {
|
||||
file, err := filepath.Abs(envfile[0])
|
||||
if err != nil {
|
||||
log.Printf("加载环境配置文件%s出错 %s\n", envfile[0], err.Error())
|
||||
} else {
|
||||
filename = file
|
||||
}
|
||||
}
|
||||
|
||||
err := godotenv.Overload(filename)
|
||||
if err != nil {
|
||||
log.Printf("读取环境配置文件%s出错 %s\n", filename, err.Error())
|
||||
log.Printf("加载环境配置文件%s出错 %s\n", filename, err.Error())
|
||||
}
|
||||
|
||||
cfg := Config{}
|
||||
|
|
@ -126,6 +141,7 @@ func (cfg *Config) SetDefaults() {
|
|||
if cfg.RootPlugin == "" {
|
||||
cfg.RootPlugin = cfg.Root + "/plugins"
|
||||
}
|
||||
|
||||
if cfg.RootTable == "" {
|
||||
cfg.RootTable = cfg.Root + "/tables"
|
||||
}
|
||||
|
|
@ -135,10 +151,72 @@ func (cfg *Config) SetDefaults() {
|
|||
if cfg.RootScreen == "" {
|
||||
cfg.RootScreen = cfg.Root + "/screens"
|
||||
}
|
||||
|
||||
if cfg.RootData == "" {
|
||||
cfg.RootData = cfg.Root + "/data"
|
||||
}
|
||||
|
||||
if cfg.RootDB == "" {
|
||||
cfg.RootDB = cfg.Root + "/db"
|
||||
cfg.RootDB = strings.TrimPrefix(cfg.RootDB, "fs://")
|
||||
cfg.RootDB = strings.TrimPrefix(cfg.RootDB, "file://")
|
||||
}
|
||||
if cfg.RootUI == "" {
|
||||
cfg.RootUI = cfg.Root + "/ui"
|
||||
cfg.RootUI = strings.TrimPrefix(cfg.RootUI, "fs://")
|
||||
cfg.RootUI = strings.TrimPrefix(cfg.RootUI, "file://")
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// SetEnvFile 指定ENV文件
|
||||
func SetEnvFile(filename string) {
|
||||
Conf = NewConfig(filename)
|
||||
}
|
||||
|
||||
// SetAppPath 设定应用目录
|
||||
func SetAppPath(root string, envfile ...string) {
|
||||
|
||||
fullpath, err := filepath.Abs(root)
|
||||
if err != nil {
|
||||
log.Panicf("设定应用目录%s出错 %s\n", root, err.Error())
|
||||
}
|
||||
|
||||
// 创建应用目录
|
||||
pathinfo, err := os.Stat(fullpath)
|
||||
if os.IsNotExist(err) {
|
||||
err := os.MkdirAll(fullpath, os.ModePerm)
|
||||
if err != nil {
|
||||
log.Panicf("创建目录失败(%s) %s", root, err)
|
||||
}
|
||||
}
|
||||
pathinfo, err = os.Stat(fullpath)
|
||||
if !pathinfo.IsDir() {
|
||||
log.Panicf("检查应用目录失败(%s) ", err)
|
||||
}
|
||||
|
||||
if !pathinfo.IsDir() {
|
||||
log.Panicf("应用目录不是文件夹(%s) ", root)
|
||||
}
|
||||
|
||||
// Set ENV
|
||||
if len(envfile) > 0 {
|
||||
Conf = NewConfig(envfile[0])
|
||||
}
|
||||
|
||||
// 从加载配置文件
|
||||
Conf.Root = fullpath
|
||||
Conf.RootAPI = filepath.Join(fullpath, "/apis")
|
||||
Conf.RootFLow = filepath.Join(fullpath, "/flows")
|
||||
Conf.RootModel = filepath.Join(fullpath, "/models")
|
||||
Conf.RootPlugin = filepath.Join(fullpath, "/plugins")
|
||||
Conf.RootTable = filepath.Join(fullpath, "/tables")
|
||||
Conf.RootChart = filepath.Join(fullpath, "/charts")
|
||||
Conf.RootScreen = filepath.Join(root, "/screens")
|
||||
Conf.RootData = filepath.Join(fullpath, "/data")
|
||||
Conf.RootUI = filepath.Join(fullpath, "/ui")
|
||||
Conf.RootDB = filepath.Join(fullpath, "/db")
|
||||
}
|
||||
|
||||
// IsDebug 是否为调试模式
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ var cfg config.Config
|
|||
func TestMain(m *testing.M) {
|
||||
|
||||
// 加载模型等
|
||||
Load(Conf)
|
||||
Load(config.Conf)
|
||||
|
||||
// 加载表格(临时)
|
||||
root := "fs://" + path.Join(Conf.Source, "/app/tables/service.json")
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package global
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
|
|
@ -15,6 +16,7 @@ import (
|
|||
"github.com/yaoapp/xiang/data"
|
||||
"github.com/yaoapp/xiang/table"
|
||||
"github.com/yaoapp/xiang/xfs"
|
||||
"github.com/yaoapp/xun/capsule"
|
||||
)
|
||||
|
||||
// Script 脚本文件类型
|
||||
|
|
@ -51,6 +53,9 @@ var App AppInfo
|
|||
|
||||
// Load 根据配置加载 API, FLow, Model, Plugin
|
||||
func Load(cfg config.Config) {
|
||||
|
||||
AppInit(cfg)
|
||||
DBConnect(cfg.Database)
|
||||
LoadAppInfo(cfg.Root)
|
||||
LoadEngine(cfg.Path)
|
||||
LoadApp(AppRoot{
|
||||
|
|
@ -63,6 +68,13 @@ func Load(cfg config.Config) {
|
|||
Screens: cfg.RootScreen,
|
||||
Data: cfg.RootData,
|
||||
})
|
||||
|
||||
// 加密密钥函数
|
||||
gou.LoadCrypt(fmt.Sprintf(`{"key":"%s"}`, cfg.Database.AESKey), "AES")
|
||||
gou.LoadCrypt(`{}`, "PASSWORD")
|
||||
|
||||
// 设定已加载配置
|
||||
Conf = cfg
|
||||
}
|
||||
|
||||
// Reload 根据配置重新加载 API, FLow, Model, Plugin
|
||||
|
|
@ -74,6 +86,41 @@ func Reload(cfg config.Config) {
|
|||
Load(cfg)
|
||||
}
|
||||
|
||||
// DBConnect 建立数据库连接
|
||||
func DBConnect(dbconfig config.DatabaseConfig) {
|
||||
|
||||
// 连接主库
|
||||
for i, dsn := range dbconfig.Primary {
|
||||
db := capsule.AddConn("primary", dbconfig.Driver, dsn)
|
||||
if i == 0 {
|
||||
db.SetAsGlobal()
|
||||
}
|
||||
}
|
||||
|
||||
// 连接从库
|
||||
for _, dsn := range dbconfig.Secondary {
|
||||
capsule.AddReadConn("secondary", dbconfig.Driver, dsn)
|
||||
}
|
||||
}
|
||||
|
||||
// AppInit 应用初始化
|
||||
func AppInit(cfg config.Config) {
|
||||
|
||||
if _, err := os.Stat(cfg.RootUI); os.IsNotExist(err) {
|
||||
err := os.MkdirAll(cfg.RootUI, os.ModePerm)
|
||||
if err != nil {
|
||||
log.Panicf("创建目录失败(%s) %s", cfg.RootUI, err)
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := os.Stat(cfg.RootDB); os.IsNotExist(err) {
|
||||
err := os.MkdirAll(cfg.RootDB, os.ModePerm)
|
||||
if err != nil {
|
||||
log.Panicf("创建目录失败(%s) %s", cfg.RootDB, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// LoadAppInfo 读取应用信息
|
||||
func LoadAppInfo(root string) {
|
||||
info := defaultAppInfo()
|
||||
|
|
|
|||
|
|
@ -1,14 +1,11 @@
|
|||
package global
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/yaoapp/gou"
|
||||
"github.com/yaoapp/xiang/config"
|
||||
"github.com/yaoapp/xiang/data"
|
||||
"github.com/yaoapp/xun/capsule"
|
||||
)
|
||||
|
||||
// VERSION 版本号
|
||||
|
|
@ -42,18 +39,4 @@ func init() {
|
|||
}
|
||||
AllowHosts = append(AllowHosts, domain)
|
||||
}
|
||||
|
||||
Conf = config.Conf
|
||||
|
||||
// 数据库连接
|
||||
if len(Conf.Database.Primary) > 0 {
|
||||
capsule.AddConn("primary", "mysql", Conf.Database.Primary[0]).SetAsGlobal()
|
||||
}
|
||||
|
||||
// 加密密钥
|
||||
gou.LoadCrypt(fmt.Sprintf(`{"key":"%s"}`, Conf.Database.AESKey), "AES")
|
||||
gou.LoadCrypt(`{}`, "PASSWORD")
|
||||
|
||||
// 加载数据
|
||||
Load(Conf)
|
||||
}
|
||||
|
|
|
|||
13
go.mod
13
go.mod
|
|
@ -11,6 +11,7 @@ require (
|
|||
github.com/gin-gonic/gin v1.7.4 // indirect
|
||||
github.com/go-sql-driver/mysql v1.6.0 // indirect
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
|
||||
github.com/hashicorp/go-hclog v1.0.0 // indirect
|
||||
github.com/hashicorp/go-plugin v1.4.3 // indirect
|
||||
github.com/hashicorp/yamux v0.0.0-20210826001029-26ff87cf9493 // indirect
|
||||
github.com/jmoiron/sqlx v1.3.4 // indirect
|
||||
|
|
@ -21,18 +22,18 @@ require (
|
|||
github.com/mattn/go-isatty v0.0.14 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.8 // indirect
|
||||
github.com/mojocn/base64Captcha v1.3.5 // indirect
|
||||
github.com/robertkrimen/otto v0.0.0-20210927222213-f9375a256948 // indirect
|
||||
github.com/robertkrimen/otto v0.0.0-20211004134430-12a632260352 // indirect
|
||||
github.com/spf13/afero v1.6.0 // indirect
|
||||
github.com/spf13/cobra v1.2.1 // indirect
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/yaoapp/gou v0.0.0-20211003110813-8a100940e019 // indirect
|
||||
github.com/yaoapp/gou v0.0.0-20211007044811-e0834e575aa0 // indirect
|
||||
github.com/yaoapp/kun v0.6.7
|
||||
github.com/yaoapp/xun v0.5.2 // indirect
|
||||
github.com/yaoapp/xun v0.6.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect
|
||||
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d // indirect
|
||||
golang.org/x/net v0.0.0-20210929193557-e81a3d93ecf6 // indirect
|
||||
golang.org/x/sys v0.0.0-20211002104244-808efd93c36d // indirect
|
||||
google.golang.org/genproto v0.0.0-20211001223012-bfb93cce50d9 // indirect
|
||||
golang.org/x/net v0.0.0-20211006190231-62292e806868 // indirect
|
||||
golang.org/x/sys v0.0.0-20211006225509-1a26e0398eed // indirect
|
||||
google.golang.org/genproto v0.0.0-20211005153810-c76a74d43a8e // indirect
|
||||
google.golang.org/grpc v1.41.0 // indirect
|
||||
)
|
||||
|
||||
|
|
|
|||
19
go.sum
19
go.sum
|
|
@ -192,6 +192,8 @@ github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtng
|
|||
github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
|
||||
github.com/hashicorp/go-hclog v0.16.2 h1:K4ev2ib4LdQETX5cSZBG0DVLk1jwGqSPXBjdah3veNs=
|
||||
github.com/hashicorp/go-hclog v0.16.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
|
||||
github.com/hashicorp/go-hclog v1.0.0 h1:bkKf0BeBXcSYa7f5Fyi9gMuQ8gNsxeiNpZjR6VxNZeo=
|
||||
github.com/hashicorp/go-hclog v1.0.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
|
||||
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
|
||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||
|
|
@ -318,6 +320,8 @@ github.com/robertkrimen/otto v0.0.0-20210614181706-373ff5438452 h1:ewTtJ72GFy2e0
|
|||
github.com/robertkrimen/otto v0.0.0-20210614181706-373ff5438452/go.mod h1:xvqspoSXJTIpemEonrMDFq6XzwHYYgToXWj5eRX1OtY=
|
||||
github.com/robertkrimen/otto v0.0.0-20210927222213-f9375a256948 h1:JgBmCxzPLP5ldSfEsVYhMUlJ7gQsOeBIPZOOeUdTTU8=
|
||||
github.com/robertkrimen/otto v0.0.0-20210927222213-f9375a256948/go.mod h1:/mK7FZ3mFYEn9zvNPhpngTyatyehSwte5bJZ4ehL5Xw=
|
||||
github.com/robertkrimen/otto v0.0.0-20211004134430-12a632260352 h1:hqx3srlCjXphJgUFQqfo41HrWvZuYvMM9WEkb3oBgi0=
|
||||
github.com/robertkrimen/otto v0.0.0-20211004134430-12a632260352/go.mod h1:/mK7FZ3mFYEn9zvNPhpngTyatyehSwte5bJZ4ehL5Xw=
|
||||
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
|
|
@ -388,6 +392,8 @@ github.com/yaoapp/gou v0.0.0-20211001101736-7de3f97a840a h1:E4eybsoNhNrfKzmnjH5z
|
|||
github.com/yaoapp/gou v0.0.0-20211001101736-7de3f97a840a/go.mod h1:vcNZXFRgGuZWzjtYH65ck1o6nzWYDpToQ09zHC9xNDE=
|
||||
github.com/yaoapp/gou v0.0.0-20211003110813-8a100940e019 h1:ufa7z9jiqvD+t8yYN1oj8xz+YNiLzxGhhRkIu9aoWeE=
|
||||
github.com/yaoapp/gou v0.0.0-20211003110813-8a100940e019/go.mod h1:vcNZXFRgGuZWzjtYH65ck1o6nzWYDpToQ09zHC9xNDE=
|
||||
github.com/yaoapp/gou v0.0.0-20211007044811-e0834e575aa0 h1:LyMs1aDbBAShEqHT7HrR+0gVqJjq2vxaqB7W/aNujPM=
|
||||
github.com/yaoapp/gou v0.0.0-20211007044811-e0834e575aa0/go.mod h1:rLXQyNCz8z8fGCyr4NDZ2OFn9/CYdUVvM0RFMdKRSYo=
|
||||
github.com/yaoapp/kun v0.6.1 h1:gbjP5wmAuJLe1RGZ2evH4rPCVWykf0iqbksaHikF/GI=
|
||||
github.com/yaoapp/kun v0.6.1/go.mod h1:igsTcWDnzpp0HtRN7sBP+XOEN2tzoC5hk2MyoPFs3xA=
|
||||
github.com/yaoapp/kun v0.6.2 h1:QbtdZpVIklRDGEvL5YYRf/eR05YFZVFk/8rX2vy2K0Q=
|
||||
|
|
@ -404,11 +410,14 @@ github.com/yaoapp/kun v0.6.7 h1:OgdArT+RLC6KI4LV1mpPFZLQijIQ/PdMP7S76NCn+BY=
|
|||
github.com/yaoapp/kun v0.6.7/go.mod h1:igsTcWDnzpp0HtRN7sBP+XOEN2tzoC5hk2MyoPFs3xA=
|
||||
github.com/yaoapp/xun v0.5.2 h1:DedZ26FpcXfkLnPKXzJsrbVmpWDRx9adUo8AvOcNT+g=
|
||||
github.com/yaoapp/xun v0.5.2/go.mod h1:y107NMHO635nhqJxMt582i1iqLjnNxAoeYr5/500UBw=
|
||||
github.com/yaoapp/xun v0.6.0 h1:U8SBDv0OVkPWsJ2A7Y1TurTZQpxSeB1slR6ryaFKgdo=
|
||||
github.com/yaoapp/xun v0.6.0/go.mod h1:SCJhBxU8AN4EIBZY5AkQI02JqtCe+HAOxHMl6BVhNQQ=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
|
||||
go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
|
||||
|
|
@ -511,6 +520,7 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v
|
|||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d h1:LO7XpTYMwTqxjLcGWPijK3vRXg1aWdlNOVOHRq45d7c=
|
||||
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210913180222-943fd674d43e h1:+b/22bPvDYt4NPDcy4xAGCmON713ONAWFeY3Z7I3tR8=
|
||||
|
|
@ -521,6 +531,8 @@ golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b h1:eB48h3HiRycXNy8E0Gf5e0hv7
|
|||
golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210929193557-e81a3d93ecf6 h1:Z04ewVs7JhXaYkmDhBERPi41gnltfQpMWDnTnQbaCqk=
|
||||
golang.org/x/net v0.0.0-20210929193557-e81a3d93ecf6/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211006190231-62292e806868 h1:KlOXYy8wQWTUJYFgkUI40Lzr06ofg5IRXUK5C7qZt1k=
|
||||
golang.org/x/net v0.0.0-20211006190231-62292e806868/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
|
|
@ -593,6 +605,7 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210903071746-97244b99971b h1:3Dq0eVHn0uaQJmPO+/aYPI/fRMqdrVDbu7MQcku54gg=
|
||||
golang.org/x/sys v0.0.0-20210903071746-97244b99971b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
|
|
@ -608,6 +621,9 @@ golang.org/x/sys v0.0.0-20211001092434-39dca1131b70 h1:pGleJoyD1yA5HfvuaksHxD040
|
|||
golang.org/x/sys v0.0.0-20211001092434-39dca1131b70/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211002104244-808efd93c36d h1:SABT8Vei3iTiu+Gy8KOzpSNz+W1EQ5YBCRtiEETxF+0=
|
||||
golang.org/x/sys v0.0.0-20211002104244-808efd93c36d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211004093028-2c5d950f24ef/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211006225509-1a26e0398eed h1:E159xujlywdAeN3FqsTBPzRKGUq/pDHolXbuttkC36E=
|
||||
golang.org/x/sys v0.0.0-20211006225509-1a26e0398eed/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
|
@ -674,6 +690,7 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f
|
|||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
|
@ -761,6 +778,8 @@ google.golang.org/genproto v0.0.0-20210930144712-2e2e1008e8a3 h1:+F3FcO6LTrzNq5w
|
|||
google.golang.org/genproto v0.0.0-20210930144712-2e2e1008e8a3/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20211001223012-bfb93cce50d9 h1:eF1wcrhdz56Vugf8qNX5dD93ItkrhothojQyHXqloe0=
|
||||
google.golang.org/genproto v0.0.0-20211001223012-bfb93cce50d9/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20211005153810-c76a74d43a8e h1:Im71rbA1N3CbIag/PumYhQcNR8bLNmuOtRIyOnnLsT8=
|
||||
google.golang.org/genproto v0.0.0-20211005153810-c76a74d43a8e/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
|
|
|
|||
15
main_test.go
15
main_test.go
|
|
@ -13,6 +13,8 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
"github.com/yaoapp/kun/any"
|
||||
"github.com/yaoapp/kun/maps"
|
||||
"github.com/yaoapp/kun/utils"
|
||||
"github.com/yaoapp/xiang/config"
|
||||
"github.com/yaoapp/xiang/global"
|
||||
)
|
||||
|
||||
|
|
@ -41,6 +43,7 @@ func TestCommandStart(t *testing.T) {
|
|||
defer func() {
|
||||
os.Args = oldArgs
|
||||
global.ServiceStop(func() {})
|
||||
log.Println("服务已关闭")
|
||||
}()
|
||||
go func() {
|
||||
os.Args = append(os.Args, "start")
|
||||
|
|
@ -49,8 +52,8 @@ func TestCommandStart(t *testing.T) {
|
|||
|
||||
// 发送请求
|
||||
request := func() (maps.MapStr, error) {
|
||||
time.Sleep(time.Microsecond * 1000)
|
||||
url := fmt.Sprintf("http://%s:%d/api/user/find/1?select=id,name", "local.iqka.com", global.Conf.Service.Port)
|
||||
time.Sleep(time.Microsecond * 2000)
|
||||
url := fmt.Sprintf("http://%s:%d/api/user/find/1?select=id,name", "local.iqka.com", config.Conf.Service.Port)
|
||||
// utils.Dump(url)
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
|
|
@ -94,9 +97,9 @@ func TestCommandStop(t *testing.T) {
|
|||
|
||||
// 发送请求
|
||||
request := func() (maps.MapStr, error) {
|
||||
time.Sleep(time.Microsecond * 1000)
|
||||
url := fmt.Sprintf("http://%s:%d/api/user/find/1?select=id,name", "local.iqka.com", global.Conf.Service.Port)
|
||||
// utils.Dump(url)
|
||||
time.Sleep(time.Microsecond * 2000)
|
||||
url := fmt.Sprintf("http://%s:%d/api/user/find/1?select=id,name", "local.iqka.com", config.Conf.Service.Port)
|
||||
utils.Dump(url)
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -124,7 +127,7 @@ func TestCommandStop(t *testing.T) {
|
|||
|
||||
// 测试关闭
|
||||
global.ServiceStop(func() { log.Println("服务已关闭") })
|
||||
time.Sleep(time.Second * 1)
|
||||
time.Sleep(time.Second * 2)
|
||||
_, err = request()
|
||||
assert.NotNil(t, err)
|
||||
return
|
||||
|
|
|
|||
|
|
@ -27,3 +27,8 @@ func Printf(format string, v ...interface{}) {
|
|||
func Println(v ...interface{}) {
|
||||
log.Output(2, fmt.Sprintln(v...))
|
||||
}
|
||||
|
||||
// Fatalf is equivalent to Printf() followed by a call to os.Exit(1).
|
||||
func Fatalf(format string, v ...interface{}) {
|
||||
log.Fatalf(format, v...)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue