diff --git a/base/gdb/gdb.go b/base/gdb/gdb.go index 0fbaf657..ed708a83 100644 --- a/base/gdb/gdb.go +++ b/base/gdb/gdb.go @@ -46,9 +46,12 @@ func (f *Frame) Close(m *ice.Message, arg ...string) bool { const ( RESTART = "restart" + BUILD = "build" + SPAWN = "spawn" START = "start" STOP = "stop" + BENCH = "bench" BEGIN = "begin" END = "end" ) diff --git a/base/gdb/routine.go b/base/gdb/routine.go index 6fe9de32..89b87634 100644 --- a/base/gdb/routine.go +++ b/base/gdb/routine.go @@ -19,7 +19,7 @@ func init() { ROUTINE: {Name: ROUTINE, Help: "协程池", Value: kit.Data()}, }, 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) { m.Cmdy(mdb.INSERT, ROUTINE, "", mdb.HASH, arg) }}, diff --git a/base/ssh/scripts.go b/base/ssh/scripts.go index 7fe9aadd..8ff0844b 100644 --- a/base/ssh/scripts.go +++ b/base/ssh/scripts.go @@ -305,6 +305,7 @@ func (f *Frame) Start(m *ice.Message, arg ...string) bool { } 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.scan(m, STDIO, "", r) } else { diff --git a/base/web/cache.go b/base/web/cache.go index 75f16a6d..30352a67 100644 --- a/base/web/cache.go +++ b/base/web/cache.go @@ -88,7 +88,7 @@ func _cache_download(m *ice.Message, r *http.Response) (file, size string) { for { if n, _ := r.Body.Read(buf); n > 0 { f.Write(buf[0:n]) - switch size += n; cb := m.Optionv("progress").(type) { + switch size += n; cb := m.Optionv(DOWNLOAD_CB).(type) { case []string: m.Richs(cb[0], cb[1], cb[2], func(key string, value map[string]interface{}) { value = value[kit.MDB_META].(map[string]interface{}) @@ -126,8 +126,9 @@ const ( CATCH = "catch" WRITE = "write" - UPLOAD = "upload" - DOWNLOAD = "download" + UPLOAD = "upload" + DOWNLOAD = "download" + DOWNLOAD_CB = "download.cb" ) const CACHE = "cache" diff --git a/base/web/space.go b/base/web/space.go index c6523a48..04e01d86 100644 --- a/base/web/space.go +++ b/base/web/space.go @@ -30,9 +30,7 @@ func _space_list(m *ice.Message, space string) { m.Sort(kit.MDB_NAME) } 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.Debug("what") client := kit.Value(value, "client").(map[string]interface{}) redial := m.Confm(SPACE, "meta.redial") 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") 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) { - m.Debug("what") m.Go(func() { - m.Debug("what") for i := 0; i >= 0 && i < kit.Int(redial["c"]); i++ { m.Option(tcp.DIAL_CB, func(s net.Conn, e error) { 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 { 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 } else { socket, msg := c, m.Spawn(b) target := kit.Simple(msg.Optionv(ice.MSG_TARGET)) 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 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.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{}) { // 查询节点 + name := target[0] if s, ok := value["socket"].(*websocket.Conn); ok { socket, source, target = s, source, target[1:] } else { socket, source, target = s, source, target[1:] } + _space_echo(msg, source, target, socket, name) }) != nil { // 转发报文 } else if res, ok := send[msg.Option(ice.MSG_TARGET)]; len(target) == 1 && ok { // 接收响应 res.Back(msg) - continue } else if msg.Warn(msg.Option("_handle") == "true", "space miss") { // 回复失败 - continue } else { // 下发失败 msg.Warn(true, "space error") source, target = []string{}, kit.Revert(source)[1:] - continue } - - _space_echo(msg, source, target, socket, name) } } return false diff --git a/core/code/autogen.go b/core/code/autogen.go index 0e1ff236..745a3d70 100644 --- a/core/code/autogen.go +++ b/core/code/autogen.go @@ -15,12 +15,12 @@ const AUTOGEN = "autogen" func init() { Index.Merge(&ice.Context{ 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", )}, }, 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) { 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")) @@ -89,8 +89,13 @@ func init() { } }}, }, 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)) - m.Cmdy(mdb.SELECT, m.Prefix(AUTOGEN), "", mdb.LIST, kit.MDB_ID, arg) + if len(arg) > 0 && !strings.HasSuffix(arg[0], "/") { + 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) diff --git a/core/code/code.shy b/core/code/code.shy new file mode 100644 index 00000000..42eb574e --- /dev/null +++ b/core/code/code.shy @@ -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 diff --git a/core/code/compile.go b/core/code/compile.go index ad099f32..a97613f6 100644 --- a/core/code/compile.go +++ b/core/code/compile.go @@ -1,6 +1,8 @@ package code import ( + "strings" + ice "github.com/shylinux/icebergs" "github.com/shylinux/icebergs/base/cli" "github.com/shylinux/icebergs/base/nfs" @@ -15,8 +17,8 @@ const COMPILE = "compile" func init() { Index.Merge(&ice.Context{ Configs: map[string]*ice.Config{ - COMPILE: {Name: "compile", Help: "编译", Value: kit.Data( - "path", "usr/publish", "env", kit.Dict( + COMPILE: {Name: COMPILE, Help: "编译", Value: kit.Data( + kit.MDB_PATH, "usr/publish", "env", kit.Dict( "PATH", os.Getenv("PATH"), "HOME", os.Getenv("HOME"), "GOCACHE", os.Getenv("GOCACHE"), @@ -27,32 +29,39 @@ func init() { )}, }, 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 { // 目录列表 - 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 } - // 编译目标 - main := kit.Select("src/main.go", arg, 2) - arch := kit.Select(m.Conf(cli.RUNTIME, "host.GOARCH"), arg, 1) - goos := kit.Select(m.Conf(cli.RUNTIME, "host.GOOS"), arg, 0) - file := path.Join(m.Conf(cmd, "meta.path"), kit.Keys(kit.Select("ice"), goos, arch)) - if goos == "windows" { - // file += ".exe" + main := "src/main.go" + goos := m.Conf(cli.RUNTIME, "host.GOOS") + arch := m.Conf(cli.RUNTIME, "host.GOARCH") + for _, k := range arg { + switch k { + case "linux", "darwin", "windows": + 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)) if msg := m.Cmd(cli.SYSTEM, m.Confv(COMPILE, "meta.go"), file, main); msg.Append(cli.CMD_CODE) != "0" { 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) diff --git a/core/code/install.go b/core/code/install.go index 85f14aee..009f7d55 100644 --- a/core/code/install.go +++ b/core/code/install.go @@ -4,6 +4,7 @@ import ( ice "github.com/shylinux/icebergs" "github.com/shylinux/icebergs/base/aaa" "github.com/shylinux/icebergs/base/cli" + "github.com/shylinux/icebergs/base/gdb" "github.com/shylinux/icebergs/base/mdb" "github.com/shylinux/icebergs/base/nfs" "github.com/shylinux/icebergs/base/tcp" @@ -27,14 +28,15 @@ func init() { }, Commands: map[string]*ice.Command{ 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) { - name := path.Base(arg[0]) + web.DOWNLOAD: {Name: "download link", Help: "下载", Hand: func(m *ice.Message, arg ...string) { + name := path.Base(m.Option(kit.MDB_LINK)) 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)) - 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 { + m.Set(kit.MDB_LINK) m.Push("", value, kit.Split(m.Option(mdb.FIELDS))) } }); len(m.Appendv(kit.MDB_NAME)) > 0 { @@ -45,10 +47,10 @@ func init() { 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{}) { 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 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))) @@ -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)) - msg := m.Cmd(web.SPIDE, web.SPIDE_DEV, web.SPIDE_CACHE, web.SPIDE_GET, arg[0]) - m.Cmdy(nfs.LINK, p, msg.Append(kit.MDB_FILE)) + 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.Cmd(cli.SYSTEM, "tar", "xvf", name) }) }}, - "build": {Name: "build link", Help: "构建", Hand: func(m *ice.Message, arg ...string) { - m.Option("cache.button", "构建") - m.Option("_process", "_follow") + gdb.BUILD: {Name: "build link", Help: "构建", Hand: func(m *ice.Message, arg ...string) { + m.Option("cache.action", "build") + m.Option(ice.MSG_PROCESS, "_follow") if m.Option("cache.hash") != "" { m.Cmdy(cli.OUTPUT, m.Option("cache.hash")) - m.Sort(kit.MDB_ID) - m.Table(func(index int, value map[string]string, head []string) { + m.Sort(kit.MDB_ID).Table(func(index int, value map[string]string, head []string) { m.Option("cache.begin", value[kit.MDB_ID]) m.Echo(value[kit.SSH_RES]) }) @@ -81,25 +81,27 @@ func init() { return } - if m.Conf(cli.OUTPUT, kit.Keys(kit.MDB_HASH, m.Option("cache.hash"), kit.MDB_META, kit.MDB_STATUS)) == "stop" { - m.Echo("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(gdb.STOP) } 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.begin", 1) + m.Set(ice.MSG_RESULT) m.Go(func() { defer m.Cmdy(cli.OUTPUT, mdb.MODIFY, kit.MDB_STATUS, cli.Status.Stop) 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) { case func(string): cb(p) 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 } } @@ -108,21 +110,21 @@ func init() { 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) 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(cli.SYSTEM, "cp", "-r", strings.TrimSuffix(value[kit.MDB_PATH], "/"), target) }) m.Echo(target) }}, - "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])) + gdb.START: {Name: "start link cmd", Help: "启动", Hand: func(m *ice.Message, arg ...string) { + p := m.Option(cli.CMD_DIR, m.Cmdx(INSTALL, gdb.SPAWN)) args := []string{} switch cb := m.Optionv("prepare").(type) { @@ -132,43 +134,30 @@ func init() { 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) { if len(arg) == 0 { // 源码列表 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 } if len(arg) == 1 { // 服务列表 + arg = kit.Split(arg[0], "-.") m.Option(mdb.FIELDS, "time,port,status,pid,cmd,dir") - m.Cmdy(mdb.SELECT, cli.DAEMON, "", mdb.HASH) - m.Appendv("port", []string{}) + m.Cmd(mdb.SELECT, cli.DAEMON, "", mdb.HASH).Table(func(index int, value map[string]string, head []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.Push(kit.SSH_PORT, path.Base(value[kit.SSH_DIR])) }) 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.Cmdy(nfs.DIR, kit.Select("./", arg, 2)) diff --git a/core/code/publish.go b/core/code/publish.go index 6fe5b107..5a3408bb 100644 --- a/core/code/publish.go +++ b/core/code/publish.go @@ -42,7 +42,7 @@ func init() { )}, }, 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) { 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))) @@ -57,7 +57,6 @@ func init() { } }}, "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.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 `, ) - -/* -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 -*/ diff --git a/core/code/trash.go b/core/code/trash.go deleted file mode 100644 index 99d1fe9b..00000000 --- a/core/code/trash.go +++ /dev/null @@ -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) -} diff --git a/core/code/upgrade.go b/core/code/upgrade.go index c4d97de3..2b6daaf3 100644 --- a/core/code/upgrade.go +++ b/core/code/upgrade.go @@ -6,7 +6,6 @@ import ( "github.com/shylinux/icebergs/base/web" kit "github.com/shylinux/toolkits" - "net/http" "os" ) @@ -15,8 +14,8 @@ const UPGRADE = "upgrade" func init() { Index.Merge(&ice.Context{ Configs: map[string]*ice.Config{ - UPGRADE: {Name: "upgrade", Help: "升级", Value: kit.Dict(kit.MDB_HASH, kit.Dict( - "path", "usr/upgrade", "system", kit.Dict(kit.MDB_LIST, kit.List( + UPGRADE: {Name: UPGRADE, Help: "升级", Value: kit.Dict(kit.MDB_HASH, kit.Dict( + 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.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]) os.Chmod(kit.Format(value[kit.MDB_PATH]), 0770) }) if exit { - m.Sleep("1s").Gos(m, func(m *ice.Message) { m.Cmd("exit", 1) }) + m.Sleep("1s").Go(func() { m.Cmd("exit", 1) }) } }}, }, diff --git a/init.go b/init.go index 7cfe2d98..d1762246 100644 --- a/init.go +++ b/init.go @@ -74,7 +74,7 @@ func (f *Frame) Close(m *Message, arg ...string) bool { var Index = &Context{Name: "ice", Help: "冰山模块", Caches: map[string]*Cache{ - CTX_FOLLOW: {Value: ""}, + CTX_FOLLOW: {Value: "ice"}, CTX_STREAM: {Value: "shy"}, CTX_STATUS: {Value: "begin"}, }, @@ -177,6 +177,7 @@ func Run(arg ...string) string { return Pulse.Result() } +var BinPack = map[string][]byte{} var names = map[string]interface{}{} var ErrNameExists = "name already exists: " diff --git a/logs.go b/logs.go index fdfe5095..2d56b9d7 100644 --- a/logs.go +++ b/logs.go @@ -25,6 +25,9 @@ func (m *Message) log(level string, str string, arg ...interface{}) *Message { Log(m, m.Format("prefix"), level, str) // 日志分流 } + if m.Option("_disable_log") == "true" { + return m // 屏蔽日志 + } // 日志颜色 prefix, suffix := "", "" @@ -34,7 +37,7 @@ func (m *Message) log(level string, str string, arg ...interface{}) *Message { case LOG_CMDS, LOG_START, LOG_SERVE: 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" case LOG_AUTH, LOG_COST: prefix, suffix = "\033[33m", "\033[0m" diff --git a/misc.go b/misc.go index 3ae5748c..f0c5bf27 100644 --- a/misc.go +++ b/misc.go @@ -1,6 +1,8 @@ package ice import ( + "path" + kit "github.com/shylinux/toolkits" "fmt" @@ -83,13 +85,15 @@ func (m *Message) PushRender(key, view, name string, arg ...string) *Message { m.Push(key, fmt.Sprintf(``, name, kit.Select("120", arg, 0))) case "a": m.Push(key, fmt.Sprintf(`%s`, kit.Select(name, arg, 0), name)) + case "download": + m.Push(key, fmt.Sprintf(`%s`, kit.Select(name, arg, 0), path.Base(kit.Select(name, arg, 0)), name)) default: m.Push(key, name) } return m } -func (m *Message) PushButton(key string, arg ...string) { - m.PushRender("action", "button", key, arg...) +func (m *Message) PushButton(arg ...string) { + m.PushRender("action", "button", strings.Join(arg, ",")) } func (m *Message) PushAction(list ...interface{}) { 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 return kit.Keys(m.target.Cap(CTX_FOLLOW), name) } - -var BinPack = map[string][]byte{} diff --git a/misc/git/repos.go b/misc/git/repos.go index 00c1469f..86b8c7f4 100644 --- a/misc/git/repos.go +++ b/misc/git/repos.go @@ -165,13 +165,13 @@ func init() { switch vs[0] { case "##": if strings.Contains(vs[1], "ahead") { - list = append(list, "上传") + list = append(list, "push") } default: if strings.Contains(vs[0], "??") { - list = append(list, "添加") + list = append(list, "add") } else { - list = append(list, "提交") + list = append(list, "submit") } } m.PushButton(strings.Join(list, ",")) diff --git a/misc/tmux/tmux.go b/misc/tmux/tmux.go index 4f2135d0..722395fd 100644 --- a/misc/tmux/tmux.go +++ b/misc/tmux/tmux.go @@ -3,14 +3,15 @@ package tmux import ( ice "github.com/shylinux/icebergs" "github.com/shylinux/icebergs/base/cli" + "github.com/shylinux/icebergs/base/gdb" "github.com/shylinux/icebergs/base/mdb" "github.com/shylinux/icebergs/base/web" "github.com/shylinux/icebergs/core/code" + "github.com/shylinux/icebergs/core/wiki" kit "github.com/shylinux/toolkits" "path" "strings" - "time" ) const ( @@ -48,24 +49,28 @@ var Index = &ice.Context{Name: TMUX, Help: "工作台", )}, }, Commands: map[string]*ice.Command{ - TMUX: {Name: "tmux port=auto path=auto auto 启动:button 构建:button 下载:button", Help: "服务", Action: map[string]*ice.Action{ - "download": {Name: "download", Help: "下载", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(code.INSTALL, "download", m.Conf(TMUX, kit.META_SOURCE)) + ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Load() }}, + ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Save() }}, + + 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) { - m.Cmdy(code.INSTALL, "build", m.Conf(TMUX, kit.META_SOURCE)) + gdb.BUILD: {Name: "build", Help: "构建", Hand: func(m *ice.Message, arg ...string) { + 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.Option(cli.CMD_DIR, p) 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) { 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) { if len(arg) > 0 && 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) { text := m.Cmdx(cli.SYSTEM, TMUX, "show-buffer") - m.Cmdy("web.wiki.spark", "inner", text) - m.Cmdy("web.wiki.image", "qrcode", text) + m.Cmdy(wiki.SPARK, "inner", text) + m.Cmdy(wiki.IMAGE, "qrcode", text) 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) { switch arg[0] { - case "text": - m.Cmd(cli.SYSTEM, TMUX, "set-buffer", "-b", m.Option("buffer"), arg[1]) + case kit.MDB_TEXT: + 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) { - m.Conf(m.Prefix(BUFFER), mdb.LIST, "") - m.Conf(m.Prefix(BUFFER), kit.Keys(mdb.META, "count"), "0") + m.Conf(BUFFER, mdb.LIST, "") + 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.Grow(m.Prefix(BUFFER), "", kit.Dict( - "name", value[head[0]], "text", m.Cmdx(cli.SYSTEM, TMUX, "show-buffer", "-b", value[head[0]]), + m.Cmd(BUFFER).Table(func(index int, value map[string]string, head []string) { + m.Grow(BUFFER, "", kit.Dict( + 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) }}, mdb.IMPORT: {Name: "import", Help: "导入", Hand: func(m *ice.Message, arg ...string) { - m.Conf(m.Prefix(BUFFER), mdb.LIST, "") - m.Conf(m.Prefix(BUFFER), kit.Keys(mdb.META, "count"), "0") + m.Conf(BUFFER, mdb.LIST, "") + m.Conf(BUFFER, kit.Keys(mdb.META, kit.MDB_COUNT), "0") m.Cmdy(mdb.IMPORT, m.Prefix(BUFFER), "", mdb.LIST) - m.Grows(m.Prefix(BUFFER), "", "", "", func(index int, value map[string]interface{}) { - m.Cmd(cli.SYSTEM, TMUX, "set-buffer", "-b", value["name"], value["text"]) + m.Grows(BUFFER, "", "", "", func(index int, value map[string]interface{}) { + 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) { @@ -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") { ls := strings.SplitN(v, ": ", 3) - m.Push("buffer", ls[0]) - m.Push("size", ls[1]) + m.Push(kit.MDB_NAME, ls[0]) + m.Push(kit.MDB_SIZE, ls[1]) 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 { - 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{ - mdb.INSERT: {Name: "insert type=shell,tmux,vim name=hi text:textarea=pwd", Help: "添加", Hand: func(m *ice.Message, arg ...string) { + SCRIPT: {Name: "script name auto create export import", Help: "脚本", Action: map[string]*ice.Action{ + 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) }}, 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) }}, - 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)) }}, 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) }}, }, 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, mdb.DETAIL) - } + m.Option(mdb.FIELDS, kit.Select(m.Conf(SCRIPT, kit.META_FIELD), mdb.DETAIL, len(arg) > 0)) 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{ - mdb.CREATE: {Name: "create name", Help: "创建", Hand: func(m *ice.Message, arg ...string) { + 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) { m.Option(cli.CMD_ENV, "TMUX", "") if 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")) } }}, - 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) { switch arg[0] { 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]) } }}, - 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) != "" { m.Cmd(cli.SYSTEM, TMUX, "kill-pane", "-t", m.Option(SESSION)+":"+m.Option(WINDOW)+"."+m.Option(PANE)) } 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) { - m.Option(mdb.FIELDS, "time,type,name,text") + m.Option(mdb.FIELDS, "name,type,text") 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) { switch value[kit.MDB_TYPE] { 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") } 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) } case "vim": @@ -221,7 +225,7 @@ var Index = &ice.Context{Name: TMUX, Help: "工作台", // 执行命令 target := arg[0] + ":" + arg[1] + "." + arg[2] 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 { // 终端内容 @@ -238,7 +242,7 @@ var Index = &ice.Context{Name: TMUX, Help: "工作台", case "1": m.PushButton("") default: - m.PushButton("进入", "删除") + m.PushButton(mdb.SELECT, mdb.REMOVE) } }) return @@ -247,14 +251,14 @@ var Index = &ice.Context{Name: TMUX, Help: "工作台", if len(arg) == 1 { // 窗口列表 m.Cmdy(WINDOW, arg[0]) - m.PushAction("进入", "删除") + m.PushAction(mdb.SELECT, mdb.REMOVE) return } if len(arg) == 2 { // 终端列表 m.Cmdy(PANE, arg[0]+":"+arg[1]) - m.PushAction("进入", "删除") + m.PushAction(mdb.SELECT, mdb.REMOVE) return } }}, diff --git a/misc/tmux/tmux.shy b/misc/tmux/tmux.shy index 84d0b7e8..cd38b65f 100644 --- a/misc/tmux/tmux.shy +++ b/misc/tmux/tmux.shy @@ -12,24 +12,22 @@ field tmux web.code.inner args `[ usr/install/tmux-3.1b cmd-bind-key.c ]` section "构建" 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 tar xvf tmux-3.1b.tar.gz && cd tmux-3.1b -./configure --prefix=$PWD/install +./configure --prefix=$PWD/_install make -j8 && make install ` section "启动" spark shell ` -cd ./install +cd ./_install ./bin/tmux -S $PWD/tmux.socket ` chapter "应用" -field paste web.chat.paste.paste - field text web.code.tmux.text field buffer web.code.tmux.buffer field script web.code.tmux.script @@ -37,21 +35,3 @@ field session web.code.tmux.session chapter "项目" 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 -` - diff --git a/type.go b/type.go index 77a399cb..70061476 100644 --- a/type.go +++ b/type.go @@ -95,7 +95,7 @@ func (c *Context) _hand(m *Message, cmd *Command, key string, k string, h *Actio 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 { 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 { 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 h, ok := cmd.Action[arg[0]]; ok { 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, @@ -139,10 +129,7 @@ func (c *Context) cmd(m *Message, cmd *Command, key string, arg ...string) *Mess return m } func (c *Context) Cmd(m *Message, cmd string, key string, arg ...string) *Message { - if s, ok := m.Target().Commands[cmd]; ok { - c.cmd(m, s, cmd, arg...) - } - return m + return c.cmd(m, m.Target().Commands[cmd], cmd, arg...) } func (c *Context) Server() Server { return c.server @@ -169,6 +156,7 @@ func (c *Context) Merge(s *Context, x Server) *Context { } for k, v := range s.Commands { c.Commands[k] = v + if v.List == nil { 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 { - kit.Value(v.Meta, kit.Keys("trans", k), a.Help) if a.List == nil { a.List = c._split(a.Name) } if len(a.List) > 0 { - v.Meta[a.Help] = 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 "=": 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, "values", strings.Split(ls[i+1], ",")) if kit.Value(item, kit.MDB_NAME) == "scale" { 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 { 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...)) } else { c.Register(s, nil) @@ -264,17 +253,10 @@ func (c *Context) Spawn(m *Message, name string, help string, arg ...string) *Co return s } func (c *Context) Begin(m *Message, arg ...string) *Context { - c.Caches[CTX_FOLLOW] = &Cache{Name: CTX_FOLLOW, Value: ""} - c.Caches[CTX_STATUS] = &Cache{Name: CTX_STATUS, 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: CTX_BEGIN} 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)) - c.Cap(CTX_STATUS, CTX_BEGIN) if c.begin = m; c.server != nil { 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 { wait := make(chan bool) - m.Hold(1) + m.Hold(1) m.Go(func() { m.Log(LOG_START, c.Cap(CTX_FOLLOW)) 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...) } if m.Done(true); m.wait != nil { @@ -302,7 +284,7 @@ func (c *Context) Start(m *Message, arg ...string) bool { return true } 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) if c.server != nil { @@ -319,9 +301,8 @@ type Message struct { meta map[string][]string data map[string]interface{} - messages []*Message - message *Message - root *Message + message *Message + root *Message source *Context target *Context @@ -501,7 +482,7 @@ func (m *Message) Travel(cb interface{}) *Message { for i := 0; i < len(list); i++ { switch cb := cb.(type) { case func(*Context, *Context): - // 模块回调 + // 遍历模块 cb(list[i].context, list[i]) case func(*Context, *Context, string, *Command): ls := []string{} @@ -509,8 +490,9 @@ func (m *Message) Travel(cb interface{}) *Message { ls = append(ls, k) } sort.Strings(ls) + for _, k := range ls { - // 命令回调 + // 遍历命令 cb(list[i].context, list[i], k, list[i].Commands[k]) } case func(*Context, *Context, string, *Config): @@ -519,114 +501,116 @@ func (m *Message) Travel(cb interface{}) *Message { ls = append(ls, k) } sort.Strings(ls) + for _, k := range ls { - // 配置回调 + // 遍历配置 cb(list[i].context, list[i], k, list[i].Configs[k]) } } - // 下级模块 ls := []string{} for k := range list[i].contexts { ls = append(ls, k) } sort.Strings(ls) + + // 遍历递进 for _, k := range ls { list = append(list, list[i].contexts[k]) } } return m } -func (m *Message) Search(key interface{}, cb interface{}) *Message { +func (m *Message) Search(key string, cb interface{}) *Message { if key == "" { return m } - switch key := key.(type) { - case string: - // 查找模块 - p := m.target.root - if ctx, ok := names[key].(*Context); ok { - p = ctx - } else if key == "ice." { - p, key = m.target.root, "" - } else if key == "." { - p, key = m.target, "" - } else if key == ".." { - if m.target.context != nil { - p, key = m.target.context, "" + + // 查找模块 + p := m.target.root + if ctx, ok := names[key].(*Context); ok { + p = ctx + } else if key == "ice." { + p, key = m.target.root, "" + } else if key == "." { + p, key = m.target, "" + } else if key == ".." { + if m.target.context != nil { + 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, ".") { - list := strings.Split(key, ".") - for _, p = range []*Context{m.target.root, m.target, m.source} { - if p == nil { - continue - } - for _, v := range list[:len(list)-1] { - if s, ok := p.contexts[v]; ok { - p = s - } else { - p = nil - break - } - } - if 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 { - m.Log(LOG_WARN, "not found %s", key) + if p != nil { break } - key = list[len(list)-1] - } else { - p = m.target + } + if m.Warn(p == nil, ErrNotFound, key) { + 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) } - // 遍历命令 - switch cb := cb.(type) { - case func(key string, cmd *Command): - if key == "" { - for k, v := range p.Commands { - cb(k, v) - } - 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) } - - 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) + 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) } return m } -func (m *Message) __cmd(arg ...interface{}) *Message { +func (m *Message) _hand(arg ...interface{}) *Message { list := kit.Simple(arg...) if len(list) == 0 && m.Hand == false { list = m.meta[MSG_DETAIL] @@ -647,19 +631,19 @@ func (m *Message) __cmd(arg ...interface{}) *Message { return m } 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 { - 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 { - return m.Go(func() { m.__cmd(arg...) }) + return m.Go(func() { m._hand(arg...) }) } func (m *Message) Cmd(arg ...interface{}) *Message { - return m.__cmd(arg...) + return m._hand(arg...) } 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 { val = conf.Value return // 读配置