1
0
mirror of https://shylinux.com/x/icebergs synced 2025-05-06 13:17:03 +08:00
This commit is contained in:
shaoying 2020-10-10 22:12:06 +08:00
parent 15a24e892f
commit 39b0821512
19 changed files with 270 additions and 493 deletions

View File

@ -46,9 +46,12 @@ func (f *Frame) Close(m *ice.Message, arg ...string) bool {
const ( const (
RESTART = "restart" RESTART = "restart"
BUILD = "build"
SPAWN = "spawn"
START = "start" START = "start"
STOP = "stop" STOP = "stop"
BENCH = "bench"
BEGIN = "begin" BEGIN = "begin"
END = "end" END = "end"
) )

View File

@ -19,7 +19,7 @@ func init() {
ROUTINE: {Name: ROUTINE, Help: "协程池", Value: kit.Data()}, ROUTINE: {Name: ROUTINE, Help: "协程池", Value: kit.Data()},
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
ROUTINE: {Name: "routine hash auto 清理", Help: "协程池", Action: map[string]*ice.Action{ ROUTINE: {Name: "routine hash auto prunes", Help: "协程池", Action: map[string]*ice.Action{
mdb.CREATE: {Name: "create fileline status", Help: "创建", Hand: func(m *ice.Message, arg ...string) { mdb.CREATE: {Name: "create fileline status", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.INSERT, ROUTINE, "", mdb.HASH, arg) m.Cmdy(mdb.INSERT, ROUTINE, "", mdb.HASH, arg)
}}, }},

View File

@ -305,6 +305,7 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool {
} }
if f.count = 1; f.source == STDIO { if f.count = 1; f.source == STDIO {
m.Option("_disable_log", "true")
f.count = kit.Int(m.Conf(SOURCE, "hash.stdio.meta.count")) + 1 f.count = kit.Int(m.Conf(SOURCE, "hash.stdio.meta.count")) + 1
f.scan(m, STDIO, "", r) f.scan(m, STDIO, "", r)
} else { } else {

View File

@ -88,7 +88,7 @@ func _cache_download(m *ice.Message, r *http.Response) (file, size string) {
for { for {
if n, _ := r.Body.Read(buf); n > 0 { if n, _ := r.Body.Read(buf); n > 0 {
f.Write(buf[0:n]) f.Write(buf[0:n])
switch size += n; cb := m.Optionv("progress").(type) { switch size += n; cb := m.Optionv(DOWNLOAD_CB).(type) {
case []string: case []string:
m.Richs(cb[0], cb[1], cb[2], func(key string, value map[string]interface{}) { m.Richs(cb[0], cb[1], cb[2], func(key string, value map[string]interface{}) {
value = value[kit.MDB_META].(map[string]interface{}) value = value[kit.MDB_META].(map[string]interface{})
@ -126,8 +126,9 @@ const (
CATCH = "catch" CATCH = "catch"
WRITE = "write" WRITE = "write"
UPLOAD = "upload" UPLOAD = "upload"
DOWNLOAD = "download" DOWNLOAD = "download"
DOWNLOAD_CB = "download.cb"
) )
const CACHE = "cache" const CACHE = "cache"

View File

@ -30,9 +30,7 @@ func _space_list(m *ice.Message, space string) {
m.Sort(kit.MDB_NAME) m.Sort(kit.MDB_NAME)
} }
func _space_dial(m *ice.Message, dev, name string, arg ...string) { func _space_dial(m *ice.Message, dev, name string, arg ...string) {
m.Debug("what %v %v %v", dev, name, arg)
m.Richs(SPIDE, nil, dev, func(key string, value map[string]interface{}) { m.Richs(SPIDE, nil, dev, func(key string, value map[string]interface{}) {
m.Debug("what")
client := kit.Value(value, "client").(map[string]interface{}) client := kit.Value(value, "client").(map[string]interface{})
redial := m.Confm(SPACE, "meta.redial") redial := m.Confm(SPACE, "meta.redial")
web := m.Target().Server().(*Frame) web := m.Target().Server().(*Frame)
@ -41,10 +39,8 @@ func _space_dial(m *ice.Message, dev, name string, arg ...string) {
proto := kit.Select("ws", "wss", client["protocol"] == "https") proto := kit.Select("ws", "wss", client["protocol"] == "https")
uri := kit.MergeURL(proto+"://"+host+"/space/", "name", name, "type", ice.Info.NodeType, "share", os.Getenv("ctx_share"), "river", os.Getenv("ctx_river")) uri := kit.MergeURL(proto+"://"+host+"/space/", "name", name, "type", ice.Info.NodeType, "share", os.Getenv("ctx_share"), "river", os.Getenv("ctx_river"))
if u, e := url.Parse(uri); m.Assert(e) { if u, e := url.Parse(uri); m.Assert(e) {
m.Debug("what")
m.Go(func() { m.Go(func() {
m.Debug("what")
for i := 0; i >= 0 && i < kit.Int(redial["c"]); i++ { for i := 0; i >= 0 && i < kit.Int(redial["c"]); i++ {
m.Option(tcp.DIAL_CB, func(s net.Conn, e error) { m.Option(tcp.DIAL_CB, func(s net.Conn, e error) {
if m.Warn(e != nil, e) { if m.Warn(e != nil, e) {
@ -132,14 +128,13 @@ func _space_exec(msg *ice.Message, source, target []string, c *websocket.Conn, n
} }
func _space_handle(m *ice.Message, safe bool, send map[string]*ice.Message, c *websocket.Conn, name string) bool { func _space_handle(m *ice.Message, safe bool, send map[string]*ice.Message, c *websocket.Conn, name string) bool {
for running := true; running; { for running := true; running; {
if t, b, e := c.ReadMessage(); m.Warn(e != nil, "space recv %d msg %v", t, e) { if _, b, e := c.ReadMessage(); m.Warn(e != nil, e) {
// 解析失败
break break
} else { } else {
socket, msg := c, m.Spawn(b) socket, msg := c, m.Spawn(b)
target := kit.Simple(msg.Optionv(ice.MSG_TARGET)) target := kit.Simple(msg.Optionv(ice.MSG_TARGET))
source := kit.Simple(msg.Optionv(ice.MSG_SOURCE), name) source := kit.Simple(msg.Optionv(ice.MSG_SOURCE), name)
msg.Log("recv", "%v<-%v %s %v", target, source, msg.Detailv(), msg.Format("meta")) msg.Log("recv", "%v->%v %s %v", source, target, msg.Detailv(), msg.Format("meta"))
if len(target) == 0 { if len(target) == 0 {
if msg.Option(ice.MSG_USERROLE, aaa.UserRole(msg, msg.Option(ice.MSG_USERNAME))) == aaa.VOID { if msg.Option(ice.MSG_USERROLE, aaa.UserRole(msg, msg.Option(ice.MSG_USERNAME))) == aaa.VOID {
@ -152,35 +147,31 @@ func _space_handle(m *ice.Message, safe bool, send map[string]*ice.Message, c *w
// 本地执行 // 本地执行
msg.Option("_dev", name) msg.Option("_dev", name)
msg.Go(func() { _space_exec(msg, source, target, c, name) }) msg.Go(func() { _space_exec(msg, source, target, c, name) })
continue
} }
} else if msg.Richs(SPACE, nil, target[0], func(key string, value map[string]interface{}) { } else if msg.Richs(SPACE, nil, target[0], func(key string, value map[string]interface{}) {
// 查询节点 // 查询节点
name := target[0]
if s, ok := value["socket"].(*websocket.Conn); ok { if s, ok := value["socket"].(*websocket.Conn); ok {
socket, source, target = s, source, target[1:] socket, source, target = s, source, target[1:]
} else { } else {
socket, source, target = s, source, target[1:] socket, source, target = s, source, target[1:]
} }
_space_echo(msg, source, target, socket, name)
}) != nil { }) != nil {
// 转发报文 // 转发报文
} else if res, ok := send[msg.Option(ice.MSG_TARGET)]; len(target) == 1 && ok { } else if res, ok := send[msg.Option(ice.MSG_TARGET)]; len(target) == 1 && ok {
// 接收响应 // 接收响应
res.Back(msg) res.Back(msg)
continue
} else if msg.Warn(msg.Option("_handle") == "true", "space miss") { } else if msg.Warn(msg.Option("_handle") == "true", "space miss") {
// 回复失败 // 回复失败
continue
} else { } else {
// 下发失败 // 下发失败
msg.Warn(true, "space error") msg.Warn(true, "space error")
source, target = []string{}, kit.Revert(source)[1:] source, target = []string{}, kit.Revert(source)[1:]
continue
} }
_space_echo(msg, source, target, socket, name)
} }
} }
return false return false

View File

@ -15,12 +15,12 @@ const AUTOGEN = "autogen"
func init() { func init() {
Index.Merge(&ice.Context{ Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{ Configs: map[string]*ice.Config{
AUTOGEN: {Name: AUTOGEN, Help: "生成", Value: kit.Data( AUTOGEN: {Name: AUTOGEN, Help: "生成", Value: kit.Data(
kit.MDB_FIELD, "time,id,name,from", kit.MDB_FIELD, "time,id,name,from",
)}, )},
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
AUTOGEN: {Name: "autogen auto 创建", Help: "生成", Action: map[string]*ice.Action{ AUTOGEN: {Name: "autogen path auto create", Help: "生成", Action: map[string]*ice.Action{
mdb.CREATE: {Name: "create name=hi@key from=usr/icebergs/misc/zsh/zsh.go@key", Help: "创建", Hand: func(m *ice.Message, arg ...string) { mdb.CREATE: {Name: "create name=hi@key from=usr/icebergs/misc/zsh/zsh.go@key", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
if p := path.Join("src", m.Option("name"), m.Option("name")+".shy"); !kit.FileExists(p) { if p := path.Join("src", m.Option("name"), m.Option("name")+".shy"); !kit.FileExists(p) {
m.Cmd(nfs.SAVE, p, `chapter "`+m.Option("name")+`"`, "\n", `field "`+m.Option("name")+`" web.code.`+m.Option("name")+"."+m.Option("name")) m.Cmd(nfs.SAVE, p, `chapter "`+m.Option("name")+`"`, "\n", `field "`+m.Option("name")+`" web.code.`+m.Option("name")+"."+m.Option("name"))
@ -89,8 +89,13 @@ func init() {
} }
}}, }},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Option(mdb.FIELDS, kit.Select(m.Conf(m.Prefix(AUTOGEN), kit.META_FIELD), mdb.DETAIL, len(arg) > 0)) if len(arg) > 0 && !strings.HasSuffix(arg[0], "/") {
m.Cmdy(mdb.SELECT, m.Prefix(AUTOGEN), "", mdb.LIST, kit.MDB_ID, arg) m.Option(nfs.DIR_ROOT, "src")
m.Cmdy(nfs.CAT, kit.Select("./", arg, 0))
return
}
m.Option(nfs.DIR_ROOT, "src")
m.Cmdy(nfs.DIR, kit.Select("./", arg, 0))
}}, }},
}, },
}, nil) }, nil)

6
core/code/code.shy Normal file
View File

@ -0,0 +1,6 @@
chapter "code"
field "安装" web.code.install
field "编译" web.code.compile
field "发布" web.code.publish
field "升级" web.code.upgrade
field "编程" web.code.autogen

View File

@ -1,6 +1,8 @@
package code package code
import ( import (
"strings"
ice "github.com/shylinux/icebergs" ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/cli" "github.com/shylinux/icebergs/base/cli"
"github.com/shylinux/icebergs/base/nfs" "github.com/shylinux/icebergs/base/nfs"
@ -15,8 +17,8 @@ const COMPILE = "compile"
func init() { func init() {
Index.Merge(&ice.Context{ Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{ Configs: map[string]*ice.Config{
COMPILE: {Name: "compile", Help: "编译", Value: kit.Data( COMPILE: {Name: COMPILE, Help: "编译", Value: kit.Data(
"path", "usr/publish", "env", kit.Dict( kit.MDB_PATH, "usr/publish", "env", kit.Dict(
"PATH", os.Getenv("PATH"), "PATH", os.Getenv("PATH"),
"HOME", os.Getenv("HOME"), "HOME", os.Getenv("HOME"),
"GOCACHE", os.Getenv("GOCACHE"), "GOCACHE", os.Getenv("GOCACHE"),
@ -27,32 +29,39 @@ func init() {
)}, )},
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
COMPILE: {Name: "compile [os [arch [main]]]", Help: "编译", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { COMPILE: {Name: "compile os=linux,darwin,windows arch=amd64,386,arm src=src/main.go 执行:button", Help: "编译", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 { if len(arg) == 0 {
// 目录列表 // 目录列表
m.Cmdy(nfs.DIR, m.Conf(cmd, "meta.path"), "time size path") m.Cmdy(nfs.DIR, m.Conf(COMPILE, kit.META_PATH), "time size path")
return return
} }
// 编译目标 main := "src/main.go"
main := kit.Select("src/main.go", arg, 2) goos := m.Conf(cli.RUNTIME, "host.GOOS")
arch := kit.Select(m.Conf(cli.RUNTIME, "host.GOARCH"), arg, 1) arch := m.Conf(cli.RUNTIME, "host.GOARCH")
goos := kit.Select(m.Conf(cli.RUNTIME, "host.GOOS"), arg, 0) for _, k := range arg {
file := path.Join(m.Conf(cmd, "meta.path"), kit.Keys(kit.Select("ice"), goos, arch)) switch k {
if goos == "windows" { case "linux", "darwin", "windows":
// file += ".exe" goos = k
case "amd64", "386", "arm":
arch = k
default:
main = k
}
} }
// 编译目标
file := path.Join(m.Conf(cmd, "meta.path"), kit.Keys(kit.Select("ice", path.Base(strings.TrimSuffix(main, ".go")), main != "src/main.go"), goos, arch))
// 编译参数 // 编译参数
m.Optionv(cli.CMD_ENV, kit.Simple(m.Confv(COMPILE, "meta.env"), "GOARCH", arch, "GOOS", goos)) m.Optionv(cli.CMD_ENV, kit.Simple(m.Confv(COMPILE, "meta.env"), "GOARCH", arch, "GOOS", goos))
if msg := m.Cmd(cli.SYSTEM, m.Confv(COMPILE, "meta.go"), file, main); msg.Append(cli.CMD_CODE) != "0" { if msg := m.Cmd(cli.SYSTEM, m.Confv(COMPILE, "meta.go"), file, main); msg.Append(cli.CMD_CODE) != "0" {
m.Copy(msg) m.Copy(msg)
return } else {
m.Log_EXPORT("source", main, "target", file)
m.PushRender(kit.MDB_LINK, "download", kit.MergeURL2(m.Option(ice.MSG_USERWEB), "/publish/"+path.Base(file)))
m.Echo(file)
} }
// 编译记录
// m.Cmdy(web.STORY, web.CATCH, "bin", file)
m.Log_EXPORT("source", main, "target", file)
}}, }},
}, },
}, nil) }, nil)

View File

@ -4,6 +4,7 @@ import (
ice "github.com/shylinux/icebergs" ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/aaa" "github.com/shylinux/icebergs/base/aaa"
"github.com/shylinux/icebergs/base/cli" "github.com/shylinux/icebergs/base/cli"
"github.com/shylinux/icebergs/base/gdb"
"github.com/shylinux/icebergs/base/mdb" "github.com/shylinux/icebergs/base/mdb"
"github.com/shylinux/icebergs/base/nfs" "github.com/shylinux/icebergs/base/nfs"
"github.com/shylinux/icebergs/base/tcp" "github.com/shylinux/icebergs/base/tcp"
@ -27,14 +28,15 @@ func init() {
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
INSTALL: {Name: "install name port path auto", Help: "安装", Meta: kit.Dict(), Action: map[string]*ice.Action{ INSTALL: {Name: "install name port path auto", Help: "安装", Meta: kit.Dict(), Action: map[string]*ice.Action{
"download": {Name: "download link", Help: "下载", Hand: func(m *ice.Message, arg ...string) { web.DOWNLOAD: {Name: "download link", Help: "下载", Hand: func(m *ice.Message, arg ...string) {
name := path.Base(arg[0]) name := path.Base(m.Option(kit.MDB_LINK))
p := path.Join(m.Conf(INSTALL, kit.META_PATH), name) p := path.Join(m.Conf(INSTALL, kit.META_PATH), name)
m.Option("_process", "_progress") m.Option(ice.MSG_PROCESS, "_progress")
m.Option(mdb.FIELDS, m.Conf(INSTALL, kit.META_FIELD)) m.Option(mdb.FIELDS, m.Conf(INSTALL, kit.META_FIELD))
if m.Cmd(mdb.SELECT, m.Prefix(INSTALL), "", mdb.HASH, kit.MDB_NAME, name).Table(func(index int, value map[string]string, head []string) { if m.Cmd(mdb.SELECT, INSTALL, "", mdb.HASH, kit.MDB_NAME, name).Table(func(index int, value map[string]string, head []string) {
if _, e := os.Stat(p); e == nil { if _, e := os.Stat(p); e == nil {
m.Set(kit.MDB_LINK)
m.Push("", value, kit.Split(m.Option(mdb.FIELDS))) m.Push("", value, kit.Split(m.Option(mdb.FIELDS)))
} }
}); len(m.Appendv(kit.MDB_NAME)) > 0 { }); len(m.Appendv(kit.MDB_NAME)) > 0 {
@ -45,10 +47,10 @@ func init() {
m.Cmd(nfs.SAVE, p, "") m.Cmd(nfs.SAVE, p, "")
// 进度 // 进度
m.Cmd(mdb.INSERT, m.Prefix(INSTALL), "", mdb.HASH, kit.MDB_NAME, name, kit.MDB_LINK, arg[0]) m.Cmd(mdb.INSERT, INSTALL, "", mdb.HASH, kit.MDB_NAME, name, kit.MDB_LINK, m.Option(kit.MDB_LINK))
m.Richs(INSTALL, "", name, func(key string, value map[string]interface{}) { m.Richs(INSTALL, "", name, func(key string, value map[string]interface{}) {
value = value[kit.MDB_META].(map[string]interface{}) value = value[kit.MDB_META].(map[string]interface{})
m.Optionv("progress", func(size int, total int) { m.Optionv(web.DOWNLOAD_CB, func(size int, total int) {
s := size * 100 / total s := size * 100 / total
if s != kit.Int(value[kit.SSH_STEP]) && s%10 == 0 { if s != kit.Int(value[kit.SSH_STEP]) && s%10 == 0 {
m.Log_IMPORT(kit.MDB_FILE, name, kit.SSH_STEP, s, kit.MDB_SIZE, kit.FmtSize(int64(size)), kit.MDB_TOTAL, kit.FmtSize(int64(total))) m.Log_IMPORT(kit.MDB_FILE, name, kit.SSH_STEP, s, kit.MDB_SIZE, kit.FmtSize(int64(size)), kit.MDB_TOTAL, kit.FmtSize(int64(total)))
@ -57,23 +59,21 @@ func init() {
}) })
}) })
m.Gos(m, func(m *ice.Message) { // 下载
// 下载 m.Go(func() {
m.Option(cli.CMD_DIR, m.Conf(INSTALL, kit.META_PATH)) m.Option(cli.CMD_DIR, m.Conf(INSTALL, kit.META_PATH))
msg := m.Cmd(web.SPIDE, web.SPIDE_DEV, web.SPIDE_CACHE, web.SPIDE_GET, arg[0]) msg := m.Cmd(web.SPIDE, web.SPIDE_DEV, web.SPIDE_CACHE, web.SPIDE_GET, m.Option(kit.MDB_LINK))
m.Cmdy(nfs.LINK, p, msg.Append(kit.MDB_FILE))
// 解压 m.Cmdy(nfs.LINK, p, msg.Append(kit.MDB_FILE))
m.Cmd(cli.SYSTEM, "tar", "xvf", name) m.Cmd(cli.SYSTEM, "tar", "xvf", name)
}) })
}}, }},
"build": {Name: "build link", Help: "构建", Hand: func(m *ice.Message, arg ...string) { gdb.BUILD: {Name: "build link", Help: "构建", Hand: func(m *ice.Message, arg ...string) {
m.Option("cache.button", "构建") m.Option("cache.action", "build")
m.Option("_process", "_follow") m.Option(ice.MSG_PROCESS, "_follow")
if m.Option("cache.hash") != "" { if m.Option("cache.hash") != "" {
m.Cmdy(cli.OUTPUT, m.Option("cache.hash")) m.Cmdy(cli.OUTPUT, m.Option("cache.hash"))
m.Sort(kit.MDB_ID) m.Sort(kit.MDB_ID).Table(func(index int, value map[string]string, head []string) {
m.Table(func(index int, value map[string]string, head []string) {
m.Option("cache.begin", value[kit.MDB_ID]) m.Option("cache.begin", value[kit.MDB_ID])
m.Echo(value[kit.SSH_RES]) m.Echo(value[kit.SSH_RES])
}) })
@ -81,25 +81,27 @@ func init() {
return return
} }
if m.Conf(cli.OUTPUT, kit.Keys(kit.MDB_HASH, m.Option("cache.hash"), kit.MDB_META, kit.MDB_STATUS)) == "stop" { if m.Conf(cli.OUTPUT, kit.Keys(kit.MDB_HASH, m.Option("cache.hash"), kit.MDB_META, kit.MDB_STATUS)) == gdb.STOP {
m.Echo("stop") m.Echo(gdb.STOP)
} }
return return
} }
m.Cmdy(cli.OUTPUT, mdb.CREATE, kit.MDB_NAME, arg[0]) m.Cmdy(cli.OUTPUT, mdb.CREATE, kit.MDB_NAME, m.Option(kit.MDB_LINK))
m.Option("cache.hash", m.Result()) m.Option("cache.hash", m.Result())
m.Option("cache.begin", 1) m.Option("cache.begin", 1)
m.Set(ice.MSG_RESULT)
m.Go(func() { m.Go(func() {
defer m.Cmdy(cli.OUTPUT, mdb.MODIFY, kit.MDB_STATUS, cli.Status.Stop) defer m.Cmdy(cli.OUTPUT, mdb.MODIFY, kit.MDB_STATUS, cli.Status.Stop)
defer m.Option(kit.MDB_HASH, m.Option("cache.hash")) defer m.Option(kit.MDB_HASH, m.Option("cache.hash"))
p := m.Option(cli.CMD_DIR, path.Join(m.Conf(INSTALL, kit.META_PATH), kit.TrimExt(arg[0]))) p := m.Option(cli.CMD_DIR, path.Join(m.Conf(INSTALL, kit.META_PATH), kit.TrimExt(m.Option(kit.MDB_LINK))))
pp := kit.Path(path.Join(p, kit.Select("_install", m.Option("install"))))
switch cb := m.Optionv("prepare").(type) { switch cb := m.Optionv("prepare").(type) {
case func(string): case func(string):
cb(p) cb(p)
default: default:
if m.Cmdy(cli.SYSTEM, "./configure", "--prefix="+kit.Path(path.Join(p, kit.Select("_install", m.Option("install")))), arg[1:]); m.Append(cli.CMD_CODE) != "0" { if m.Cmdy(cli.SYSTEM, "./configure", "--prefix="+pp, arg[1:]); m.Append(cli.CMD_CODE) != "0" {
return return
} }
} }
@ -108,21 +110,21 @@ func init() {
return return
} }
m.Cmdy(cli.SYSTEM, "make", "PREFIX="+kit.Path(path.Join(p, kit.Select("_install", m.Option("install")))), "install") m.Cmdy(cli.SYSTEM, "make", "PREFIX="+pp, "install")
}) })
}}, }},
"spawn": {Name: "spawn link", Help: "新建", Hand: func(m *ice.Message, arg ...string) { gdb.SPAWN: {Name: "spawn link", Help: "新建", Hand: func(m *ice.Message, arg ...string) {
port := m.Cmdx(tcp.PORT, aaa.Right) port := m.Cmdx(tcp.PORT, aaa.Right)
target := path.Join(m.Conf(cli.DAEMON, kit.META_PATH), port) target := path.Join(m.Conf(cli.DAEMON, kit.META_PATH), port)
source := path.Join(m.Conf(INSTALL, kit.META_PATH), kit.TrimExt(arg[0])) source := path.Join(m.Conf(INSTALL, kit.META_PATH), kit.TrimExt(m.Option(kit.MDB_LINK)))
m.Cmd(nfs.DIR, path.Join(source, kit.Select("_install", m.Option("install")))).Table(func(index int, value map[string]string, head []string) { m.Cmd(nfs.DIR, path.Join(source, kit.Select("_install", m.Option("install")))).Table(func(index int, value map[string]string, head []string) {
m.Cmd(cli.SYSTEM, "cp", "-r", strings.TrimSuffix(value[kit.MDB_PATH], "/"), target) m.Cmd(cli.SYSTEM, "cp", "-r", strings.TrimSuffix(value[kit.MDB_PATH], "/"), target)
}) })
m.Echo(target) m.Echo(target)
}}, }},
"start": {Name: "start link cmd...", Help: "启动", Hand: func(m *ice.Message, arg ...string) { gdb.START: {Name: "start link cmd", Help: "启动", Hand: func(m *ice.Message, arg ...string) {
p := m.Option(cli.CMD_DIR, m.Cmdx(INSTALL, "spawn", arg[0])) p := m.Option(cli.CMD_DIR, m.Cmdx(INSTALL, gdb.SPAWN))
args := []string{} args := []string{}
switch cb := m.Optionv("prepare").(type) { switch cb := m.Optionv("prepare").(type) {
@ -132,43 +134,30 @@ func init() {
m.Cmdy(cli.DAEMON, arg[1:], args) m.Cmdy(cli.DAEMON, arg[1:], args)
}}, }},
"bench": {Name: "bench port cmd...", Help: "压测", Hand: func(m *ice.Message, arg ...string) {
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) == 0 { if len(arg) == 0 {
// 源码列表 // 源码列表
m.Option(mdb.FIELDS, m.Conf(INSTALL, kit.META_FIELD)) m.Option(mdb.FIELDS, m.Conf(INSTALL, kit.META_FIELD))
m.Cmdy(mdb.SELECT, m.Prefix(INSTALL), "", mdb.HASH) m.Cmdy(mdb.SELECT, INSTALL, "", mdb.HASH)
return return
} }
if len(arg) == 1 { if len(arg) == 1 {
// 服务列表 // 服务列表
arg = kit.Split(arg[0], "-.")
m.Option(mdb.FIELDS, "time,port,status,pid,cmd,dir") m.Option(mdb.FIELDS, "time,port,status,pid,cmd,dir")
m.Cmdy(mdb.SELECT, cli.DAEMON, "", mdb.HASH) m.Cmd(mdb.SELECT, cli.DAEMON, "", mdb.HASH).Table(func(index int, value map[string]string, head []string) {
m.Appendv("port", []string{}) if strings.Contains(value["cmd"], "bin/"+arg[0]) {
m.Push("", value, kit.Split(m.Option(mdb.FIELDS)))
}
})
m.Appendv(kit.SSH_PORT, []string{})
m.Table(func(index int, value map[string]string, head []string) { m.Table(func(index int, value map[string]string, head []string) {
m.Push(kit.SSH_PORT, path.Base(value[kit.SSH_DIR])) m.Push(kit.SSH_PORT, path.Base(value[kit.SSH_DIR]))
}) })
return return
} }
arg[0] = path.Base(arg[0])
if key := strings.Split(strings.Split(arg[0], "-")[0], ".")[0]; len(arg) == 1 {
u := kit.ParseURL(m.Option(ice.MSG_USERWEB))
m.Cmd(cli.DAEMON).Table(func(index int, value map[string]string, head []string) {
// 服务列表
if strings.Contains(value[kit.MDB_NAME], key) {
m.Push(kit.MDB_TIME, value[kit.MDB_TIME])
m.Push(kit.SSH_PORT, path.Base(value[kit.SSH_DIR]))
m.Push(kit.MDB_STATUS, value[kit.MDB_STATUS])
m.Push(kit.MDB_NAME, value[kit.MDB_NAME])
m.PushRender(kit.MDB_LINK, "a", kit.Format("http://%s:%s", u.Hostname(), path.Base(value[kit.SSH_DIR])))
}
})
return
}
// 目录列表 // 目录列表
m.Option(nfs.DIR_ROOT, path.Join(m.Conf(cli.DAEMON, kit.META_PATH), arg[1])) m.Option(nfs.DIR_ROOT, path.Join(m.Conf(cli.DAEMON, kit.META_PATH), arg[1]))
m.Cmdy(nfs.DIR, kit.Select("./", arg, 2)) m.Cmdy(nfs.DIR, kit.Select("./", arg, 2))

View File

@ -42,7 +42,7 @@ func init() {
)}, )},
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
PUBLISH: {Name: "publish path=auto auto 火山架 冰山架 神农架", Help: "发布", Action: map[string]*ice.Action{ PUBLISH: {Name: "publish path auto can ice ish", Help: "发布", Action: map[string]*ice.Action{
"contexts": {Name: "contexts", Help: "环境", Hand: func(m *ice.Message, arg ...string) { "contexts": {Name: "contexts", Help: "环境", Hand: func(m *ice.Message, arg ...string) {
u := kit.ParseURL(m.Option(ice.MSG_USERWEB)) u := kit.ParseURL(m.Option(ice.MSG_USERWEB))
m.Option("httphost", fmt.Sprintf("%s://%s:%s", u.Scheme, strings.Split(u.Host, ":")[0], kit.Select(kit.Select("80", "443", u.Scheme == "https"), strings.Split(u.Host, ":"), 1))) m.Option("httphost", fmt.Sprintf("%s://%s:%s", u.Scheme, strings.Split(u.Host, ":")[0], kit.Select(kit.Select("80", "443", u.Scheme == "https"), strings.Split(u.Host, ":"), 1)))
@ -57,7 +57,6 @@ func init() {
} }
}}, }},
"ish": {Name: "ish", Help: "神农架", Hand: func(m *ice.Message, arg ...string) { "ish": {Name: "ish", Help: "神农架", Hand: func(m *ice.Message, arg ...string) {
_publish_file(m, "etc/conf/tmux.conf")
m.Option(nfs.DIR_REG, ".*\\.(sh|vim|conf)") m.Option(nfs.DIR_REG, ".*\\.(sh|vim|conf)")
m.Cmdy(nfs.DIR, m.Conf(PUBLISH, kit.META_PATH), "time size line path link") m.Cmdy(nfs.DIR, m.Conf(PUBLISH, kit.META_PATH), "time size line path link")
}}, }},
@ -101,15 +100,3 @@ mkdir contexts; cd contexts
export ctx_dev={{.Option "httphost"}} ctx_river={{.Option "sess.river"}} ctx_share={{.Option "share"}} ctx_temp=$(mktemp); curl -sL $ctx_dev >$ctx_temp; source $ctx_temp ice export ctx_dev={{.Option "httphost"}} ctx_river={{.Option "sess.river"}} ctx_share={{.Option "share"}} ctx_temp=$(mktemp); curl -sL $ctx_dev >$ctx_temp; source $ctx_temp ice
`, `,
) )
/*
yum install -y make git vim go
mkdir ~/.ssh &>/dev/null; touch ~/.ssh/config; [ -z "$(cat ~/.ssh/config|grep 'HOST {{.Option "hostname"}}')" ] && echo -e "HOST {{.Option "hostname"}}\n Port 9030" >> ~/.ssh/config
export ISH_CONF_HUB_PROXY={{.Option "userhost"}}:.ish/pluged/
git clone $ISH_CONF_HUB_PROXY/github.com/shylinux/contexts && cd contexts
source etc/miss.sh
touch ~/.gitconfig; [ -z "$(cat ~/.gitconfig|grep '\[url \"{{.Option "userhost"}}')" ] && echo -e "[url \"{{.Option "userhost"}}:ish/pluged/\"]\n insteadOf=\"https://github.com/\"\n" >> ~/.gitconfig
git clone https://github.com/shylinux/contexts && cd contexts
source etc/miss.sh
*/

View File

@ -1,188 +0,0 @@
package code
import (
"net/http"
ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/cli"
"github.com/shylinux/icebergs/base/nfs"
"github.com/shylinux/icebergs/base/web"
kit "github.com/shylinux/toolkits"
"net/url"
"os"
"path"
"runtime"
"strings"
)
const ( // CODE
// INSTALL = "_install"
PREPARE = "_prepare"
PROJECT = "_project"
)
const TRASH = "trash"
func init() {
Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{
"_install": {Name: "install", Help: "安装", Value: kit.Data(
"path", "usr/install", "target", "usr/local",
"linux", "https://dl.google.com/go/go1.14.2.linux-amd64.tar.gz",
"darwin", "https://dl.google.com/go/go1.14.6.darwin-amd64.tar.gz",
"windows", "https://golang.google.cn/dl/go1.14.6.windows-amd64.zip",
)},
PREPARE: {Name: "prepare", Help: "配置", Value: kit.Data("path", "usr/prepare",
"script", ".ish/pluged/golang/init.sh", "export", kit.Dict(
"GOPROXY", "https://goproxy.cn,direct",
"GOPRIVATE", "https://github.com",
),
)},
PROJECT: {Name: "project", Help: "项目", Value: kit.Data("path", "usr/project")},
"login": {Name: "login", Help: "终端接入", Value: kit.Data()},
},
Commands: map[string]*ice.Command{
"_install": {Name: "install url 安装:button", Help: "安装", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
target := m.Conf("_install", kit.Keys("meta", runtime.GOOS))
p := path.Join(m.Conf("_install", "meta.path"), path.Base(target))
if _, e := os.Stat(p); e != nil {
// 下载
msg := m.Cmd(web.SPIDE, "dev", web.CACHE, http.MethodGet, target)
m.Cmd(web.CACHE, web.WATCH, msg.Append(web.DATA), p)
}
os.MkdirAll(m.Conf("_install", kit.Keys("meta.target")), ice.MOD_DIR)
m.Cmdy(cli.SYSTEM, "tar", "xvf", p, "-C", m.Conf("_install", kit.Keys("meta.target")))
}},
PREPARE: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
export := []string{}
kit.Fetch(m.Confv(PREPARE, "meta.export"), func(key string, val string) {
export = append(export, key+"="+val)
})
m.Cmd(nfs.SAVE, m.Conf(PREPARE, "meta.script"), kit.Format(`
export GOROOT=%s GOPATH=%s:$GOPATH GOBIN=%s
export PATH=$GOBIN:$GOROOT/bin:$PATH
export %s
`, kit.Path(m.Conf("_install", kit.Keys("meta.target")), "go"), kit.Path("src"), kit.Path("bin"), strings.Join(export, " ")))
}},
PROJECT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
}},
"login": {Name: "login key", Help: "登录", Meta: kit.Dict(
"detail", []string{"编辑", "删除", "清理", "清空"},
), Action: map[string]*ice.Action{}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if len(arg) > 0 && arg[0] == "action" {
switch arg[1] {
case "modify", "编辑":
m.Richs(cmd, nil, m.Option("key"), func(key string, value map[string]interface{}) {
m.Logs(ice.LOG_MODIFY, cmd, key, "field", arg[2], "value", kit.Value(value, arg[2]), "->", arg[3])
kit.Value(value, arg[2], arg[3])
})
case "delete", "删除":
m.Logs(ice.LOG_DELETE, cmd, m.Option("key"), "value", m.Conf(cmd, kit.Keys(kit.MDB_HASH, m.Option("key"))))
m.Conf(cmd, kit.Keys(kit.MDB_HASH, m.Option("key")), "")
case "prune", "清理":
m.Cmdy(cmd, "prune")
case "clear", "清空":
m.Cmdy(cmd, "prune", "all")
}
return
}
switch kit.Select("list", arg, 0) {
case "init":
if m.Option("sid") != "" && m.Conf(cmd, []string{kit.MDB_HASH, m.Option("sid"), "status"}) != "" {
// 复用会话
m.Conf(cmd, []string{kit.MDB_HASH, m.Option("sid"), "status"}, "login")
m.Logs(ice.LOG_AUTH, "sid", m.Option("sid"))
m.Echo(m.Option("sid"))
return
}
you := m.Conf(web.SHARE, kit.Keys(kit.MDB_HASH, m.Option("share"), "name"))
// 添加会话
h := m.Rich(cmd, nil, kit.Dict(
"type", kit.Select("zsh", arg, 1),
"status", "login",
"you", you,
"pwd", m.Option("pwd"),
"pid", m.Option("pid"),
"pane", m.Option("pane"),
"hostname", m.Option("hostname"),
"username", m.Option("username"),
))
m.Logs(ice.LOG_AUTH, "sid", h, "you", you)
m.Echo(h)
case "exit":
// 退出会话
m.Richs(cmd, nil, m.Option("sid"), func(key string, value map[string]interface{}) {
m.Logs(ice.LOG_AUTH, "sid", m.Option("sid"))
value["status"] = "logout"
m.Echo(key)
})
case "prune":
list := []string{}
m.Richs(cmd, nil, "*", func(key string, value map[string]interface{}) {
if len(arg) > 1 && arg[1] == "all" || value["status"] == "logout" {
list = append(list, key)
}
})
// 清理会话
kit.Fetch(list, func(index int, value string) {
m.Logs(ice.LOG_DELETE, "login", value, "value", m.Conf(cmd, kit.Keys(kit.MDB_HASH, value)))
m.Conf(cmd, kit.Keys(kit.MDB_HASH, value), "")
})
m.Echo("%d", len(list))
case "list":
// 会话列表
m.Richs("login", nil, "*", func(key string, value map[string]interface{}) {
m.Push(key, value, []string{"time", "key", "type", "status", "you"})
pwd := strings.Split(kit.Format(value["pwd"]), "/")
if len(pwd) > 3 {
m.Push("pwd", strings.Join(pwd[len(pwd)-3:len(pwd)], "/"))
} else {
m.Push("pwd", value["pwd"])
}
m.Push(key, value, []string{"pid", "pane", "hostname", "username"})
})
default:
// 会话详情
m.Richs(cmd, nil, arg[0], func(key string, value map[string]interface{}) {
m.Push("detail", value)
})
}
}},
"/miss/": {Name: "/miss/", Help: "任务", Action: map[string]*ice.Action{
"pwd": {Name: "pwd", Help: "pwd", Hand: func(m *ice.Message, arg ...string) {
m.Render(ice.RENDER_RESULT)
m.Echo("hello world\n")
}},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
u, e := url.QueryUnescape(m.Option("arg"))
m.Assert(e)
args := kit.Split(u)
if len(arg) == 0 || arg[0] == "" {
return
}
m.Render(ice.RENDER_RESULT)
if m.Cmdy(arg, args); len(m.Resultv()) == 0 {
m.Table()
}
}},
},
}, nil)
}

View File

@ -6,7 +6,6 @@ import (
"github.com/shylinux/icebergs/base/web" "github.com/shylinux/icebergs/base/web"
kit "github.com/shylinux/toolkits" kit "github.com/shylinux/toolkits"
"net/http"
"os" "os"
) )
@ -15,8 +14,8 @@ const UPGRADE = "upgrade"
func init() { func init() {
Index.Merge(&ice.Context{ Index.Merge(&ice.Context{
Configs: map[string]*ice.Config{ Configs: map[string]*ice.Config{
UPGRADE: {Name: "upgrade", Help: "升级", Value: kit.Dict(kit.MDB_HASH, kit.Dict( UPGRADE: {Name: UPGRADE, Help: "升级", Value: kit.Dict(kit.MDB_HASH, kit.Dict(
"path", "usr/upgrade", "system", kit.Dict(kit.MDB_LIST, kit.List( kit.MDB_PATH, "usr/upgrade", "system", kit.Dict(kit.MDB_LIST, kit.List(
kit.MDB_INPUT, "bin", "file", "ice.bin", "path", "bin/ice.bin", kit.MDB_INPUT, "bin", "file", "ice.bin", "path", "bin/ice.bin",
kit.MDB_INPUT, "bin", "file", "ice.sh", "path", "bin/ice.sh", kit.MDB_INPUT, "bin", "file", "ice.sh", "path", "bin/ice.sh",
)), )),
@ -33,12 +32,12 @@ func init() {
} }
// 下载文件 // 下载文件
msg := m.Cmd(web.SPIDE, "dev", web.CACHE, http.MethodGet, "/publish/"+kit.Format(value[kit.MDB_FILE])) msg := m.Cmd(web.SPIDE, web.SPIDE_DEV, web.SPIDE_CACHE, web.SPIDE_GET, "/publish/"+kit.Format(value[kit.MDB_FILE]))
m.Cmd(web.STORY, web.WATCH, msg.Append(kit.MDB_FILE), value[kit.MDB_PATH]) m.Cmd(web.STORY, web.WATCH, msg.Append(kit.MDB_FILE), value[kit.MDB_PATH])
os.Chmod(kit.Format(value[kit.MDB_PATH]), 0770) os.Chmod(kit.Format(value[kit.MDB_PATH]), 0770)
}) })
if exit { if exit {
m.Sleep("1s").Gos(m, func(m *ice.Message) { m.Cmd("exit", 1) }) m.Sleep("1s").Go(func() { m.Cmd("exit", 1) })
} }
}}, }},
}, },

View File

@ -74,7 +74,7 @@ func (f *Frame) Close(m *Message, arg ...string) bool {
var Index = &Context{Name: "ice", Help: "冰山模块", var Index = &Context{Name: "ice", Help: "冰山模块",
Caches: map[string]*Cache{ Caches: map[string]*Cache{
CTX_FOLLOW: {Value: ""}, CTX_FOLLOW: {Value: "ice"},
CTX_STREAM: {Value: "shy"}, CTX_STREAM: {Value: "shy"},
CTX_STATUS: {Value: "begin"}, CTX_STATUS: {Value: "begin"},
}, },
@ -177,6 +177,7 @@ func Run(arg ...string) string {
return Pulse.Result() return Pulse.Result()
} }
var BinPack = map[string][]byte{}
var names = map[string]interface{}{} var names = map[string]interface{}{}
var ErrNameExists = "name already exists: " var ErrNameExists = "name already exists: "

View File

@ -25,6 +25,9 @@ func (m *Message) log(level string, str string, arg ...interface{}) *Message {
Log(m, m.Format("prefix"), level, str) Log(m, m.Format("prefix"), level, str)
// 日志分流 // 日志分流
} }
if m.Option("_disable_log") == "true" {
return m // 屏蔽日志
}
// 日志颜色 // 日志颜色
prefix, suffix := "", "" prefix, suffix := "", ""
@ -34,7 +37,7 @@ func (m *Message) log(level string, str string, arg ...interface{}) *Message {
case LOG_CMDS, LOG_START, LOG_SERVE: case LOG_CMDS, LOG_START, LOG_SERVE:
prefix, suffix = "\033[32m", "\033[0m" prefix, suffix = "\033[32m", "\033[0m"
case LOG_WARN, LOG_ERROR, LOG_CLOSE: case LOG_WARN, LOG_CLOSE, LOG_ERROR:
prefix, suffix = "\033[31m", "\033[0m" prefix, suffix = "\033[31m", "\033[0m"
case LOG_AUTH, LOG_COST: case LOG_AUTH, LOG_COST:
prefix, suffix = "\033[33m", "\033[0m" prefix, suffix = "\033[33m", "\033[0m"

10
misc.go
View File

@ -1,6 +1,8 @@
package ice package ice
import ( import (
"path"
kit "github.com/shylinux/toolkits" kit "github.com/shylinux/toolkits"
"fmt" "fmt"
@ -83,13 +85,15 @@ func (m *Message) PushRender(key, view, name string, arg ...string) *Message {
m.Push(key, fmt.Sprintf(`<img src="%s" height=%s>`, name, kit.Select("120", arg, 0))) m.Push(key, fmt.Sprintf(`<img src="%s" height=%s>`, name, kit.Select("120", arg, 0)))
case "a": case "a":
m.Push(key, fmt.Sprintf(`<a href="%s" target="_blank">%s</a>`, kit.Select(name, arg, 0), name)) m.Push(key, fmt.Sprintf(`<a href="%s" target="_blank">%s</a>`, kit.Select(name, arg, 0), name))
case "download":
m.Push(key, fmt.Sprintf(`<a href="%s" download="%s">%s</a>`, kit.Select(name, arg, 0), path.Base(kit.Select(name, arg, 0)), name))
default: default:
m.Push(key, name) m.Push(key, name)
} }
return m return m
} }
func (m *Message) PushButton(key string, arg ...string) { func (m *Message) PushButton(arg ...string) {
m.PushRender("action", "button", key, arg...) m.PushRender("action", "button", strings.Join(arg, ","))
} }
func (m *Message) PushAction(list ...interface{}) { func (m *Message) PushAction(list ...interface{}) {
if len(m.meta[MSG_APPEND]) > 0 && m.meta[MSG_APPEND][0] == kit.MDB_KEY { if len(m.meta[MSG_APPEND]) > 0 && m.meta[MSG_APPEND][0] == kit.MDB_KEY {
@ -109,5 +113,3 @@ func (m *Message) AddCmd(cmd *Command) string {
m.target.Commands[name] = cmd m.target.Commands[name] = cmd
return kit.Keys(m.target.Cap(CTX_FOLLOW), name) return kit.Keys(m.target.Cap(CTX_FOLLOW), name)
} }
var BinPack = map[string][]byte{}

View File

@ -165,13 +165,13 @@ func init() {
switch vs[0] { switch vs[0] {
case "##": case "##":
if strings.Contains(vs[1], "ahead") { if strings.Contains(vs[1], "ahead") {
list = append(list, "上传") list = append(list, "push")
} }
default: default:
if strings.Contains(vs[0], "??") { if strings.Contains(vs[0], "??") {
list = append(list, "添加") list = append(list, "add")
} else { } else {
list = append(list, "提交") list = append(list, "submit")
} }
} }
m.PushButton(strings.Join(list, ",")) m.PushButton(strings.Join(list, ","))

View File

@ -3,14 +3,15 @@ package tmux
import ( import (
ice "github.com/shylinux/icebergs" ice "github.com/shylinux/icebergs"
"github.com/shylinux/icebergs/base/cli" "github.com/shylinux/icebergs/base/cli"
"github.com/shylinux/icebergs/base/gdb"
"github.com/shylinux/icebergs/base/mdb" "github.com/shylinux/icebergs/base/mdb"
"github.com/shylinux/icebergs/base/web" "github.com/shylinux/icebergs/base/web"
"github.com/shylinux/icebergs/core/code" "github.com/shylinux/icebergs/core/code"
"github.com/shylinux/icebergs/core/wiki"
kit "github.com/shylinux/toolkits" kit "github.com/shylinux/toolkits"
"path" "path"
"strings" "strings"
"time"
) )
const ( const (
@ -48,24 +49,28 @@ var Index = &ice.Context{Name: TMUX, Help: "工作台",
)}, )},
}, },
Commands: map[string]*ice.Command{ Commands: map[string]*ice.Command{
TMUX: {Name: "tmux port=auto path=auto auto 启动:button 构建:button 下载:button", Help: "服务", Action: map[string]*ice.Action{ ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Load() }},
"download": {Name: "download", Help: "下载", Hand: func(m *ice.Message, arg ...string) { ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Save() }},
m.Cmdy(code.INSTALL, "download", m.Conf(TMUX, kit.META_SOURCE))
TMUX: {Name: "tmux port path auto start build download", Help: "服务", Action: map[string]*ice.Action{
web.DOWNLOAD: {Name: "download", Help: "下载", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(code.INSTALL, web.DOWNLOAD, m.Conf(TMUX, kit.META_SOURCE))
}}, }},
"build": {Name: "build", Help: "构建", Hand: func(m *ice.Message, arg ...string) { gdb.BUILD: {Name: "build", Help: "构建", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(code.INSTALL, "build", m.Conf(TMUX, kit.META_SOURCE)) m.Cmdy(code.INSTALL, gdb.BUILD, m.Conf(TMUX, kit.META_SOURCE))
}}, }},
"start": {Name: "start", Help: "启动", Hand: func(m *ice.Message, arg ...string) { gdb.START: {Name: "start", Help: "启动", Hand: func(m *ice.Message, arg ...string) {
m.Optionv("prepare", func(p string) []string { m.Optionv("prepare", func(p string) []string {
m.Option(cli.CMD_DIR, p) m.Option(cli.CMD_DIR, p)
return []string{"-S", kit.Path(p, "tmux.socket"), "new-session", "-dn", "miss"} return []string{"-S", kit.Path(p, "tmux.socket"), "new-session", "-dn", "miss"}
}) })
m.Cmdy(code.INSTALL, "start", m.Conf(TMUX, kit.META_SOURCE), "bin/tmux") m.Cmdy(code.INSTALL, gdb.START, m.Conf(TMUX, kit.META_SOURCE), "bin/tmux")
}}, }},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmdy(code.INSTALL, path.Base(m.Conf(TMUX, kit.META_SOURCE)), arg) m.Cmdy(code.INSTALL, path.Base(m.Conf(TMUX, kit.META_SOURCE)), arg)
}}, }},
TEXT: {Name: "text 查看:button 保存:button 清空:button text:textarea", Help: "文本", Action: map[string]*ice.Action{
TEXT: {Name: "text 查看:button save 清空 text:textarea", Help: "文本", Action: map[string]*ice.Action{
"save": {Name: "save", Help: "保存", Hand: func(m *ice.Message, arg ...string) { "save": {Name: "save", Help: "保存", Hand: func(m *ice.Message, arg ...string) {
if len(arg) > 0 && arg[0] != "" { if len(arg) > 0 && arg[0] != "" {
m.Cmd(cli.SYSTEM, TMUX, "set-buffer", arg[0]) m.Cmd(cli.SYSTEM, TMUX, "set-buffer", arg[0])
@ -74,35 +79,35 @@ var Index = &ice.Context{Name: TMUX, Help: "工作台",
}}, }},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
text := m.Cmdx(cli.SYSTEM, TMUX, "show-buffer") text := m.Cmdx(cli.SYSTEM, TMUX, "show-buffer")
m.Cmdy("web.wiki.spark", "inner", text) m.Cmdy(wiki.SPARK, "inner", text)
m.Cmdy("web.wiki.image", "qrcode", text) m.Cmdy(wiki.IMAGE, "qrcode", text)
m.Render("") m.Render("")
}}, }},
BUFFER: {Name: "buffer buffer=auto value auto 导出 导入", Help: "缓存", Action: map[string]*ice.Action{ BUFFER: {Name: "buffer name value auto export import", Help: "缓存", Action: map[string]*ice.Action{
mdb.MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) { mdb.MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) {
switch arg[0] { switch arg[0] {
case "text": case kit.MDB_TEXT:
m.Cmd(cli.SYSTEM, TMUX, "set-buffer", "-b", m.Option("buffer"), arg[1]) m.Cmd(cli.SYSTEM, TMUX, "set-buffer", "-b", m.Option(kit.MDB_NAME), arg[1])
} }
}}, }},
mdb.EXPORT: {Name: "export", Help: "导出", Hand: func(m *ice.Message, arg ...string) { mdb.EXPORT: {Name: "export", Help: "导出", Hand: func(m *ice.Message, arg ...string) {
m.Conf(m.Prefix(BUFFER), mdb.LIST, "") m.Conf(BUFFER, mdb.LIST, "")
m.Conf(m.Prefix(BUFFER), kit.Keys(mdb.META, "count"), "0") m.Conf(BUFFER, kit.Keys(mdb.META, kit.MDB_COUNT), "0")
m.Cmd(m.Prefix(BUFFER)).Table(func(index int, value map[string]string, head []string) { m.Cmd(BUFFER).Table(func(index int, value map[string]string, head []string) {
m.Grow(m.Prefix(BUFFER), "", kit.Dict( m.Grow(BUFFER, "", kit.Dict(
"name", value[head[0]], "text", m.Cmdx(cli.SYSTEM, TMUX, "show-buffer", "-b", value[head[0]]), kit.MDB_NAME, value[head[0]], kit.MDB_TEXT, m.Cmdx(cli.SYSTEM, TMUX, "show-buffer", "-b", value[head[0]]),
)) ))
}) })
m.Cmdy(mdb.EXPORT, m.Prefix(BUFFER), "", mdb.LIST) m.Cmdy(mdb.EXPORT, m.Prefix(BUFFER), "", mdb.LIST)
}}, }},
mdb.IMPORT: {Name: "import", Help: "导入", Hand: func(m *ice.Message, arg ...string) { mdb.IMPORT: {Name: "import", Help: "导入", Hand: func(m *ice.Message, arg ...string) {
m.Conf(m.Prefix(BUFFER), mdb.LIST, "") m.Conf(BUFFER, mdb.LIST, "")
m.Conf(m.Prefix(BUFFER), kit.Keys(mdb.META, "count"), "0") m.Conf(BUFFER, kit.Keys(mdb.META, kit.MDB_COUNT), "0")
m.Cmdy(mdb.IMPORT, m.Prefix(BUFFER), "", mdb.LIST) m.Cmdy(mdb.IMPORT, m.Prefix(BUFFER), "", mdb.LIST)
m.Grows(m.Prefix(BUFFER), "", "", "", func(index int, value map[string]interface{}) { m.Grows(BUFFER, "", "", "", func(index int, value map[string]interface{}) {
m.Cmd(cli.SYSTEM, TMUX, "set-buffer", "-b", value["name"], value["text"]) m.Cmd(cli.SYSTEM, TMUX, "set-buffer", "-b", value[kit.MDB_NAME], value[kit.MDB_TEXT])
}) })
}}, }},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
@ -119,23 +124,23 @@ var Index = &ice.Context{Name: TMUX, Help: "工作台",
// 缓存列表 // 缓存列表
for i, v := range kit.Split(m.Cmdx(cli.SYSTEM, TMUX, "list-buffers"), "\n", "\n", "\n") { for i, v := range kit.Split(m.Cmdx(cli.SYSTEM, TMUX, "list-buffers"), "\n", "\n", "\n") {
ls := strings.SplitN(v, ": ", 3) ls := strings.SplitN(v, ": ", 3)
m.Push("buffer", ls[0]) m.Push(kit.MDB_NAME, ls[0])
m.Push("size", ls[1]) m.Push(kit.MDB_SIZE, ls[1])
if i < 3 { if i < 3 {
m.Push("text", m.Cmdx(cli.SYSTEM, TMUX, "show-buffer", "-b", ls[0])) m.Push(kit.MDB_TEXT, m.Cmdx(cli.SYSTEM, TMUX, "show-buffer", "-b", ls[0]))
} else { } else {
m.Push("text", ls[2][1:len(ls[2])-1]) m.Push(kit.MDB_TEXT, ls[2][1:len(ls[2])-1])
} }
} }
}}, }},
SCRIPT: {Name: "script name=auto auto 添加 导出 导入", Help: "脚本", Action: map[string]*ice.Action{ SCRIPT: {Name: "script name auto create export import", Help: "脚本", Action: map[string]*ice.Action{
mdb.INSERT: {Name: "insert type=shell,tmux,vim name=hi text:textarea=pwd", Help: "添加", Hand: func(m *ice.Message, arg ...string) { mdb.CREATE: {Name: "create type=shell,tmux,vim name=hi text:textarea=pwd", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.INSERT, m.Prefix(SCRIPT), "", mdb.HASH, arg) m.Cmdy(mdb.INSERT, m.Prefix(SCRIPT), "", mdb.HASH, arg)
}}, }},
mdb.MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) { mdb.MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.MODIFY, m.Prefix(SCRIPT), "", mdb.HASH, kit.MDB_NAME, m.Option(kit.MDB_NAME), arg) m.Cmdy(mdb.MODIFY, m.Prefix(SCRIPT), "", mdb.HASH, kit.MDB_NAME, m.Option(kit.MDB_NAME), arg)
}}, }},
mdb.DELETE: {Name: "delete", Help: "删除", Hand: func(m *ice.Message, arg ...string) { mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(mdb.DELETE, m.Prefix(SCRIPT), "", mdb.HASH, kit.MDB_NAME, m.Option(kit.MDB_NAME)) m.Cmdy(mdb.DELETE, m.Prefix(SCRIPT), "", mdb.HASH, kit.MDB_NAME, m.Option(kit.MDB_NAME))
}}, }},
mdb.EXPORT: {Name: "export", Help: "导出", Hand: func(m *ice.Message, arg ...string) { mdb.EXPORT: {Name: "export", Help: "导出", Hand: func(m *ice.Message, arg ...string) {
@ -145,13 +150,12 @@ var Index = &ice.Context{Name: TMUX, Help: "工作台",
m.Cmdy(mdb.IMPORT, m.Prefix(SCRIPT), "", mdb.HASH) m.Cmdy(mdb.IMPORT, m.Prefix(SCRIPT), "", mdb.HASH)
}}, }},
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
if m.Option(mdb.FIELDS, m.Conf(m.Prefix(SCRIPT), kit.META_FIELD)); len(arg) > 0 { m.Option(mdb.FIELDS, kit.Select(m.Conf(SCRIPT, kit.META_FIELD), mdb.DETAIL, len(arg) > 0))
m.Option(mdb.FIELDS, mdb.DETAIL)
}
m.Cmdy(mdb.SELECT, m.Prefix(SCRIPT), "", mdb.HASH, kit.MDB_NAME, arg) m.Cmdy(mdb.SELECT, m.Prefix(SCRIPT), "", mdb.HASH, kit.MDB_NAME, arg)
m.PushAction(mdb.REMOVE)
}}, }},
SESSION: {Name: "session session=auto window=auto pane=auto cmd auto 脚本 创建 ", Help: "会话管理", Action: map[string]*ice.Action{ SESSION: {Name: "session session window pane cmd auto create script", Help: "会话管理", Action: map[string]*ice.Action{
mdb.CREATE: {Name: "create name", Help: "创建", Hand: func(m *ice.Message, arg ...string) { mdb.CREATE: {Name: "create name", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
m.Option(cli.CMD_ENV, "TMUX", "") m.Option(cli.CMD_ENV, "TMUX", "")
if m.Option(PANE) != "" { if m.Option(PANE) != "" {
m.Cmd(cli.SYSTEM, TMUX, "split-window", "-t", m.Option(SESSION)+":"+m.Option(WINDOW)+"."+m.Option(PANE)) m.Cmd(cli.SYSTEM, TMUX, "split-window", "-t", m.Option(SESSION)+":"+m.Option(WINDOW)+"."+m.Option(PANE))
@ -167,15 +171,6 @@ var Index = &ice.Context{Name: TMUX, Help: "工作台",
m.Cmd(cli.SYSTEM, TMUX, "new-session", "-ds", m.Option("name")) m.Cmd(cli.SYSTEM, TMUX, "new-session", "-ds", m.Option("name"))
} }
}}, }},
mdb.SELECT: {Name: "select", Help: "进入", Hand: func(m *ice.Message, arg ...string) {
m.Cmd(cli.SYSTEM, TMUX, "switch-client", "-t", m.Option(SESSION))
if m.Option(WINDOW) != "" {
m.Cmd(cli.SYSTEM, TMUX, "select-window", "-t", m.Option(SESSION)+":"+m.Option(WINDOW))
}
if m.Option(PANE) != "" {
m.Cmd(cli.SYSTEM, TMUX, "select-pane", "-t", m.Option(SESSION)+":"+m.Option(WINDOW)+"."+m.Option(PANE))
}
}},
mdb.MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) { mdb.MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) {
switch arg[0] { switch arg[0] {
case WINDOW: case WINDOW:
@ -186,7 +181,16 @@ var Index = &ice.Context{Name: TMUX, Help: "工作台",
m.Cmd(cli.SYSTEM, TMUX, "rename-session", "-t", m.Option(SESSION), arg[1]) m.Cmd(cli.SYSTEM, TMUX, "rename-session", "-t", m.Option(SESSION), arg[1])
} }
}}, }},
mdb.DELETE: {Name: "delete", Help: "删除", Hand: func(m *ice.Message, arg ...string) { mdb.SELECT: {Name: "select", Help: "进入", Hand: func(m *ice.Message, arg ...string) {
m.Cmd(cli.SYSTEM, TMUX, "switch-client", "-t", m.Option(SESSION))
if m.Option(WINDOW) != "" {
m.Cmd(cli.SYSTEM, TMUX, "select-window", "-t", m.Option(SESSION)+":"+m.Option(WINDOW))
}
if m.Option(PANE) != "" {
m.Cmd(cli.SYSTEM, TMUX, "select-pane", "-t", m.Option(SESSION)+":"+m.Option(WINDOW)+"."+m.Option(PANE))
}
}},
mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
if m.Option(PANE) != "" { if m.Option(PANE) != "" {
m.Cmd(cli.SYSTEM, TMUX, "kill-pane", "-t", m.Option(SESSION)+":"+m.Option(WINDOW)+"."+m.Option(PANE)) m.Cmd(cli.SYSTEM, TMUX, "kill-pane", "-t", m.Option(SESSION)+":"+m.Option(WINDOW)+"."+m.Option(PANE))
} else if m.Option(WINDOW) != "" { } else if m.Option(WINDOW) != "" {
@ -197,19 +201,19 @@ var Index = &ice.Context{Name: TMUX, Help: "工作台",
}}, }},
mdb.INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) { mdb.INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) {
m.Option(mdb.FIELDS, "time,type,name,text") m.Option(mdb.FIELDS, "name,type,text")
m.Cmdy(mdb.SELECT, SCRIPT, "", mdb.HASH) m.Cmdy(mdb.SELECT, SCRIPT, "", mdb.HASH)
}}, }},
"script": {Name: "script name", Help: "脚本", Hand: func(m *ice.Message, arg ...string) { SCRIPT: {Name: "script name", Help: "脚本", Hand: func(m *ice.Message, arg ...string) {
m.Cmd(mdb.SELECT, SCRIPT, "", mdb.HASH, kit.MDB_NAME, m.Option(kit.MDB_NAME)).Table(func(index int, value map[string]string, head []string) { m.Cmd(mdb.SELECT, SCRIPT, "", mdb.HASH, kit.MDB_NAME, m.Option(kit.MDB_NAME)).Table(func(index int, value map[string]string, head []string) {
switch value[kit.MDB_TYPE] { switch value[kit.MDB_TYPE] {
case "shell": case "shell":
for _, line := range kit.Split(value[kit.MDB_TEXT]) { for _, line := range kit.Split(value[kit.MDB_TEXT], "\n", "\n", "\n") {
m.Cmd(cli.SYSTEM, TMUX, "send-keys", "-t", m.Option(SESSION)+":"+m.Option(WINDOW)+"."+m.Option(PANE), line, "Enter") m.Cmd(cli.SYSTEM, TMUX, "send-keys", "-t", m.Option(SESSION)+":"+m.Option(WINDOW)+"."+m.Option(PANE), line, "Enter")
} }
case "tmux": case "tmux":
for _, line := range kit.Split(value[kit.MDB_TEXT]) { for _, line := range kit.Split(value[kit.MDB_TEXT], "\n", "\n", "\n") {
m.Cmd(cli.SYSTEM, TMUX, line) m.Cmd(cli.SYSTEM, TMUX, line)
} }
case "vim": case "vim":
@ -221,7 +225,7 @@ var Index = &ice.Context{Name: TMUX, Help: "工作台",
// 执行命令 // 执行命令
target := arg[0] + ":" + arg[1] + "." + arg[2] target := arg[0] + ":" + arg[1] + "." + arg[2]
m.Cmd(cli.SYSTEM, TMUX, "send-keys", "-t", target, strings.Join(arg[3:], " "), "Enter") m.Cmd(cli.SYSTEM, TMUX, "send-keys", "-t", target, strings.Join(arg[3:], " "), "Enter")
time.Sleep(1 * time.Second) m.Sleep("100ms")
} }
if len(arg) > 2 { if len(arg) > 2 {
// 终端内容 // 终端内容
@ -238,7 +242,7 @@ var Index = &ice.Context{Name: TMUX, Help: "工作台",
case "1": case "1":
m.PushButton("") m.PushButton("")
default: default:
m.PushButton("进入", "删除") m.PushButton(mdb.SELECT, mdb.REMOVE)
} }
}) })
return return
@ -247,14 +251,14 @@ var Index = &ice.Context{Name: TMUX, Help: "工作台",
if len(arg) == 1 { if len(arg) == 1 {
// 窗口列表 // 窗口列表
m.Cmdy(WINDOW, arg[0]) m.Cmdy(WINDOW, arg[0])
m.PushAction("进入", "删除") m.PushAction(mdb.SELECT, mdb.REMOVE)
return return
} }
if len(arg) == 2 { if len(arg) == 2 {
// 终端列表 // 终端列表
m.Cmdy(PANE, arg[0]+":"+arg[1]) m.Cmdy(PANE, arg[0]+":"+arg[1])
m.PushAction("进入", "删除") m.PushAction(mdb.SELECT, mdb.REMOVE)
return return
} }
}}, }},

View File

@ -12,24 +12,22 @@ field tmux web.code.inner args `[ usr/install/tmux-3.1b cmd-bind-key.c ]`
section "构建" section "构建"
spark shell ` spark shell `
yum install -y gcc make libevent-devel.x86_64 ncurses-devel.x86_64 yum install -y wget make gcc libevent-devel.x86_64 ncurses-devel.x86_64
wget https://github.com/tmux/tmux/releases/download/3.1b/tmux-3.1b.tar.gz wget https://github.com/tmux/tmux/releases/download/3.1b/tmux-3.1b.tar.gz
tar xvf tmux-3.1b.tar.gz && cd tmux-3.1b tar xvf tmux-3.1b.tar.gz && cd tmux-3.1b
./configure --prefix=$PWD/install ./configure --prefix=$PWD/_install
make -j8 && make install make -j8 && make install
` `
section "启动" section "启动"
spark shell ` spark shell `
cd ./install cd ./_install
./bin/tmux -S $PWD/tmux.socket ./bin/tmux -S $PWD/tmux.socket
` `
chapter "应用" chapter "应用"
field paste web.chat.paste.paste
field text web.code.tmux.text field text web.code.tmux.text
field buffer web.code.tmux.buffer field buffer web.code.tmux.buffer
field script web.code.tmux.script field script web.code.tmux.script
@ -37,21 +35,3 @@ field session web.code.tmux.session
chapter "项目" chapter "项目"
field icebergs web.code.inner args `[ usr/icebergs misc/tmux/tmux.go ]` field icebergs web.code.inner args `[ usr/icebergs misc/tmux/tmux.go ]`
return
section "libevent"
spark shell `
wget https://github.com/libevent/libevent/releases/download/release-2.1.12-stable/libevent-2.1.12-stable.tar.gz
tar xvf libevent-2.1.12-stable.tar.gz && cd libevent-2.1.12-stable
./configure --prefix=$PWD/install
make -j8 && make install
`
section "ncurses"
spark shell `
wget https://invisible-island.net/datafiles/release/ncurses.tar.gz
tar xvf ncurses.tar.gz && cd ncurses-6.2
./configure
make -j8
make install
`

218
type.go
View File

@ -95,7 +95,7 @@ func (c *Context) _hand(m *Message, cmd *Command, key string, k string, h *Actio
value = kit.Select(value, arg, i) value = kit.Select(value, arg, i)
} }
m.Option(name, kit.Select("", value, !strings.HasPrefix(value, "@"))) m.Option(name, kit.Select(m.Option(name), value, !strings.HasPrefix(value, "@")))
} }
if !order { if !order {
for i := 0; i < len(arg)-1; i += 2 { for i := 0; i < len(arg)-1; i += 2 {
@ -116,21 +116,11 @@ func (c *Context) cmd(m *Message, cmd *Command, key string, arg ...string) *Mess
if h, ok := cmd.Action[arg[1]]; ok { if h, ok := cmd.Action[arg[1]]; ok {
return c._hand(m, cmd, key, arg[1], h, arg[2:]...) return c._hand(m, cmd, key, arg[1], h, arg[2:]...)
} }
for k, h := range cmd.Action {
if h.Name == arg[1] || h.Help == arg[1] {
return c._hand(m, cmd, key, k, h, arg[2:]...)
}
}
} }
if len(arg) > 0 && cmd.Action != nil { if len(arg) > 0 && cmd.Action != nil {
if h, ok := cmd.Action[arg[0]]; ok { if h, ok := cmd.Action[arg[0]]; ok {
return c._hand(m, cmd, key, arg[0], h, arg[1:]...) return c._hand(m, cmd, key, arg[0], h, arg[1:]...)
} }
for k, h := range cmd.Action {
if h.Name == arg[0] || h.Help == arg[0] {
return c._hand(m, cmd, key, k, h, arg[1:]...)
}
}
} }
m.Log(LOG_CMDS, "%s.%s %d %v %s", c.Name, key, len(arg), arg, m.Log(LOG_CMDS, "%s.%s %d %v %s", c.Name, key, len(arg), arg,
@ -139,10 +129,7 @@ func (c *Context) cmd(m *Message, cmd *Command, key string, arg ...string) *Mess
return m return m
} }
func (c *Context) Cmd(m *Message, cmd string, key string, arg ...string) *Message { func (c *Context) Cmd(m *Message, cmd string, key string, arg ...string) *Message {
if s, ok := m.Target().Commands[cmd]; ok { return c.cmd(m, m.Target().Commands[cmd], cmd, arg...)
c.cmd(m, s, cmd, arg...)
}
return m
} }
func (c *Context) Server() Server { func (c *Context) Server() Server {
return c.server return c.server
@ -169,6 +156,7 @@ func (c *Context) Merge(s *Context, x Server) *Context {
} }
for k, v := range s.Commands { for k, v := range s.Commands {
c.Commands[k] = v c.Commands[k] = v
if v.List == nil { if v.List == nil {
v.List = c._split(v.Name) v.List = c._split(v.Name)
} }
@ -177,14 +165,13 @@ func (c *Context) Merge(s *Context, x Server) *Context {
} }
for k, a := range v.Action { for k, a := range v.Action {
kit.Value(v.Meta, kit.Keys("trans", k), a.Help)
if a.List == nil { if a.List == nil {
a.List = c._split(a.Name) a.List = c._split(a.Name)
} }
if len(a.List) > 0 { if len(a.List) > 0 {
v.Meta[a.Help] = a.List
v.Meta[k] = a.List v.Meta[k] = a.List
} }
kit.Value(v.Meta, kit.Keys("trans", k), a.Help)
} }
} }
@ -234,8 +221,10 @@ func (c *Context) _split(name string) []interface{} {
} }
case "=": case "=":
if value = kit.Select("", ls, i+1); len(ls) > i+1 && strings.Contains(ls[i+1], ",") { if value = kit.Select("", ls, i+1); len(ls) > i+1 && strings.Contains(ls[i+1], ",") {
vs := strings.Split(ls[i+1], ",")
kit.Value(item, "values", vs)
kit.Value(item, kit.MDB_VALUE, vs[0])
kit.Value(item, kit.MDB_INPUT, "select") kit.Value(item, kit.MDB_INPUT, "select")
kit.Value(item, "values", strings.Split(ls[i+1], ","))
if kit.Value(item, kit.MDB_NAME) == "scale" { if kit.Value(item, kit.MDB_NAME) == "scale" {
kit.Value(item, kit.MDB_VALUE, "week") kit.Value(item, kit.MDB_VALUE, "week")
} }
@ -255,7 +244,7 @@ func (c *Context) _split(name string) []interface{} {
func (c *Context) Spawn(m *Message, name string, help string, arg ...string) *Context { func (c *Context) Spawn(m *Message, name string, help string, arg ...string) *Context {
s := &Context{Name: name, Help: help, Caches: map[string]*Cache{}, Configs: map[string]*Config{}} s := &Context{Name: name, Help: help, Caches: map[string]*Cache{}, Configs: map[string]*Config{}}
if m.target.Server != nil { if m.target.server != nil {
c.Register(s, m.target.server.Spawn(m, s, arg...)) c.Register(s, m.target.server.Spawn(m, s, arg...))
} else { } else {
c.Register(s, nil) c.Register(s, nil)
@ -264,17 +253,10 @@ func (c *Context) Spawn(m *Message, name string, help string, arg ...string) *Co
return s return s
} }
func (c *Context) Begin(m *Message, arg ...string) *Context { func (c *Context) Begin(m *Message, arg ...string) *Context {
c.Caches[CTX_FOLLOW] = &Cache{Name: CTX_FOLLOW, Value: ""} c.Caches[CTX_FOLLOW] = &Cache{Name: CTX_FOLLOW, Value: kit.Keys(kit.Select("", c.context.Cap(CTX_FOLLOW), c.context != Index), c.Name)}
c.Caches[CTX_STATUS] = &Cache{Name: CTX_STATUS, Value: ""} c.Caches[CTX_STATUS] = &Cache{Name: CTX_STATUS, Value: CTX_BEGIN}
c.Caches[CTX_STREAM] = &Cache{Name: CTX_STREAM, Value: ""} c.Caches[CTX_STREAM] = &Cache{Name: CTX_STREAM, Value: ""}
if c.context == Index {
c.Cap(CTX_FOLLOW, c.Name)
} else if c.context != nil {
c.Cap(CTX_FOLLOW, kit.Keys(c.context.Cap(CTX_FOLLOW), c.Name))
}
m.Log(LOG_BEGIN, c.Cap(CTX_FOLLOW)) m.Log(LOG_BEGIN, c.Cap(CTX_FOLLOW))
c.Cap(CTX_STATUS, CTX_BEGIN)
if c.begin = m; c.server != nil { if c.begin = m; c.server != nil {
c.server.Begin(m, arg...) c.server.Begin(m, arg...)
@ -283,14 +265,14 @@ func (c *Context) Begin(m *Message, arg ...string) *Context {
} }
func (c *Context) Start(m *Message, arg ...string) bool { func (c *Context) Start(m *Message, arg ...string) bool {
wait := make(chan bool) wait := make(chan bool)
m.Hold(1)
m.Hold(1)
m.Go(func() { m.Go(func() {
m.Log(LOG_START, c.Cap(CTX_FOLLOW)) m.Log(LOG_START, c.Cap(CTX_FOLLOW))
c.Cap(CTX_STATUS, CTX_START) c.Cap(CTX_STATUS, CTX_START)
c.start = m wait <- true
if wait <- true; c.server != nil { if c.start = m; c.server != nil {
c.server.Start(m, arg...) c.server.Start(m, arg...)
} }
if m.Done(true); m.wait != nil { if m.Done(true); m.wait != nil {
@ -302,7 +284,7 @@ func (c *Context) Start(m *Message, arg ...string) bool {
return true return true
} }
func (c *Context) Close(m *Message, arg ...string) bool { func (c *Context) Close(m *Message, arg ...string) bool {
m.Log(LOG_CLOSE, "%s", c.Cap(CTX_FOLLOW)) m.Log(LOG_CLOSE, c.Cap(CTX_FOLLOW))
c.Cap(CTX_STATUS, CTX_CLOSE) c.Cap(CTX_STATUS, CTX_CLOSE)
if c.server != nil { if c.server != nil {
@ -319,9 +301,8 @@ type Message struct {
meta map[string][]string meta map[string][]string
data map[string]interface{} data map[string]interface{}
messages []*Message message *Message
message *Message root *Message
root *Message
source *Context source *Context
target *Context target *Context
@ -501,7 +482,7 @@ func (m *Message) Travel(cb interface{}) *Message {
for i := 0; i < len(list); i++ { for i := 0; i < len(list); i++ {
switch cb := cb.(type) { switch cb := cb.(type) {
case func(*Context, *Context): case func(*Context, *Context):
// 模块回调 // 遍历模块
cb(list[i].context, list[i]) cb(list[i].context, list[i])
case func(*Context, *Context, string, *Command): case func(*Context, *Context, string, *Command):
ls := []string{} ls := []string{}
@ -509,8 +490,9 @@ func (m *Message) Travel(cb interface{}) *Message {
ls = append(ls, k) ls = append(ls, k)
} }
sort.Strings(ls) sort.Strings(ls)
for _, k := range ls { for _, k := range ls {
// 命令回调 // 遍历命令
cb(list[i].context, list[i], k, list[i].Commands[k]) cb(list[i].context, list[i], k, list[i].Commands[k])
} }
case func(*Context, *Context, string, *Config): case func(*Context, *Context, string, *Config):
@ -519,114 +501,116 @@ func (m *Message) Travel(cb interface{}) *Message {
ls = append(ls, k) ls = append(ls, k)
} }
sort.Strings(ls) sort.Strings(ls)
for _, k := range ls { for _, k := range ls {
// 配置回调 // 遍历配置
cb(list[i].context, list[i], k, list[i].Configs[k]) cb(list[i].context, list[i], k, list[i].Configs[k])
} }
} }
// 下级模块
ls := []string{} ls := []string{}
for k := range list[i].contexts { for k := range list[i].contexts {
ls = append(ls, k) ls = append(ls, k)
} }
sort.Strings(ls) sort.Strings(ls)
// 遍历递进
for _, k := range ls { for _, k := range ls {
list = append(list, list[i].contexts[k]) list = append(list, list[i].contexts[k])
} }
} }
return m return m
} }
func (m *Message) Search(key interface{}, cb interface{}) *Message { func (m *Message) Search(key string, cb interface{}) *Message {
if key == "" { if key == "" {
return m return m
} }
switch key := key.(type) {
case string: // 查找模块
// 查找模块 p := m.target.root
p := m.target.root if ctx, ok := names[key].(*Context); ok {
if ctx, ok := names[key].(*Context); ok { p = ctx
p = ctx } else if key == "ice." {
} else if key == "ice." { p, key = m.target.root, ""
p, key = m.target.root, "" } else if key == "." {
} else if key == "." { p, key = m.target, ""
p, key = m.target, "" } else if key == ".." {
} else if key == ".." { if m.target.context != nil {
if m.target.context != nil { p, key = m.target.context, ""
p, key = m.target.context, "" }
} else if strings.Contains(key, ".") {
list := strings.Split(key, ".")
for _, p = range []*Context{m.target.root, m.target, m.source} {
if p == nil {
continue
} }
} else if strings.Contains(key, ".") { for _, v := range list[:len(list)-1] {
list := strings.Split(key, ".") if s, ok := p.contexts[v]; ok {
for _, p = range []*Context{m.target.root, m.target, m.source} { p = s
if p == nil { } else {
continue p = nil
}
for _, v := range list[:len(list)-1] {
if s, ok := p.contexts[v]; ok {
p = s
} else {
p = nil
break
}
}
if p != nil {
break break
} }
} }
if p == nil { if p != nil {
m.Log(LOG_WARN, "not found %s", key)
break break
} }
key = list[len(list)-1] }
} else { if m.Warn(p == nil, ErrNotFound, key) {
p = m.target return m
}
key = list[len(list)-1]
} else {
p = m.target
}
// 遍历命令
switch cb := cb.(type) {
case func(key string, cmd *Command):
if key == "" {
for k, v := range p.Commands {
cb(k, v)
}
} else if cmd, ok := p.Commands[key]; ok {
cb(key, cmd)
} }
// 遍历命令 case func(p *Context, s *Context, key string, cmd *Command):
switch cb := cb.(type) { if key == "" {
case func(key string, cmd *Command): for k, v := range p.Commands {
if key == "" { cb(p.context, p, k, v)
for k, v := range p.Commands {
cb(k, v)
}
break
} }
break
case func(p *Context, s *Context, key string, cmd *Command):
if key == "" {
for k, v := range p.Commands {
cb(p.context, p, k, v)
}
break
}
for _, p := range []*Context{p, m.target, m.source} {
for s := p; s != nil; s = s.context {
if cmd, ok := s.Commands[key]; ok {
cb(s.context, s, key, cmd)
return m
}
}
}
case func(p *Context, s *Context, key string, conf *Config):
for _, p := range []*Context{m.target, p, m.source} {
for s := p; s != nil; s = s.context {
if cmd, ok := s.Configs[key]; ok {
cb(s.context, s, key, cmd)
return m
}
}
}
case func(p *Context, s *Context, key string):
cb(p.context, p, key)
case func(p *Context, s *Context):
cb(p.context, p)
} }
// 查找命令
for _, p := range []*Context{p, m.target, m.source} {
for s := p; s != nil; s = s.context {
if cmd, ok := s.Commands[key]; ok {
cb(s.context, s, key, cmd)
return m
}
}
}
case func(p *Context, s *Context, key string, conf *Config):
// 查找配置
for _, p := range []*Context{m.target, p, m.source} {
for s := p; s != nil; s = s.context {
if cmd, ok := s.Configs[key]; ok {
cb(s.context, s, key, cmd)
return m
}
}
}
case func(p *Context, s *Context, key string):
cb(p.context, p, key)
case func(p *Context, s *Context):
cb(p.context, p)
} }
return m return m
} }
func (m *Message) __cmd(arg ...interface{}) *Message { func (m *Message) _hand(arg ...interface{}) *Message {
list := kit.Simple(arg...) list := kit.Simple(arg...)
if len(list) == 0 && m.Hand == false { if len(list) == 0 && m.Hand == false {
list = m.meta[MSG_DETAIL] list = m.meta[MSG_DETAIL]
@ -647,19 +631,19 @@ func (m *Message) __cmd(arg ...interface{}) *Message {
return m return m
} }
func (m *Message) Cmdy(arg ...interface{}) *Message { func (m *Message) Cmdy(arg ...interface{}) *Message {
return m.Copy(m.__cmd(arg...)) return m.Copy(m._hand(arg...))
} }
func (m *Message) Cmdx(arg ...interface{}) string { func (m *Message) Cmdx(arg ...interface{}) string {
return kit.Select("", m.__cmd(arg...).meta[MSG_RESULT], 0) return kit.Select("", m._hand(arg...).meta[MSG_RESULT], 0)
} }
func (m *Message) Cmds(arg ...interface{}) *Message { func (m *Message) Cmds(arg ...interface{}) *Message {
return m.Go(func() { m.__cmd(arg...) }) return m.Go(func() { m._hand(arg...) })
} }
func (m *Message) Cmd(arg ...interface{}) *Message { func (m *Message) Cmd(arg ...interface{}) *Message {
return m.__cmd(arg...) return m._hand(arg...)
} }
func (m *Message) Confv(arg ...interface{}) (val interface{}) { func (m *Message) Confv(arg ...interface{}) (val interface{}) {
m.Search(arg[0], func(p *Context, s *Context, key string, conf *Config) { m.Search(kit.Format(arg[0]), func(p *Context, s *Context, key string, conf *Config) {
if len(arg) == 1 { if len(arg) == 1 {
val = conf.Value val = conf.Value
return // 读配置 return // 读配置