From 396c088e4d39cd14bf6400ce3d44eecd989a3723 Mon Sep 17 00:00:00 2001 From: harveyshao Date: Wed, 16 Feb 2022 10:01:25 +0800 Subject: [PATCH] opt cli --- base/aaa/user.go | 2 +- base/cli/cli.go | 2 +- base/cli/cli.shy | 3 +- base/cli/daemon.go | 19 ++---- base/cli/forever.go | 26 ++++---- base/cli/qrcode.go | 12 ++-- base/cli/runtime.go | 119 +++++++++++++++++-------------------- base/cli/system.go | 28 +++++---- base/nfs/cat.go | 3 +- base/nfs/save.go | 4 ++ base/ssh/scripts.go | 11 ++-- base/web/dream.go | 72 ++++++++++------------ base/web/serve.go | 3 + base/web/spide.go | 6 +- conf.go | 2 + core/chat/header.go | 1 + core/chat/river.go | 1 - core/code/autogen.go | 77 ++++++++++++------------ core/code/compile.go | 58 +++++++++--------- core/code/install.go | 19 ------ core/code/publish.go | 16 +++-- core/code/upgrade.go | 2 +- core/code/vimer.go | 1 - go.mod | 2 +- go.sum | 4 +- info.go | 39 ++++++------ init.go | 4 +- logs.go | 2 +- misc.go | 3 +- misc/git/status.go | 104 ++++++++++++++++---------------- misc/git/total.go | 16 +++-- misc/lark/duty.go | 2 +- misc/ssh/connect.go | 6 +- misc/ssh/service.go | 7 +-- misc/ssh/service_darwin.go | 5 +- misc/ssh/service_linux.go | 5 +- option.go | 3 +- type.go | 3 +- 38 files changed, 335 insertions(+), 357 deletions(-) diff --git a/base/aaa/user.go b/base/aaa/user.go index bc4d1dba..6a8c61d1 100644 --- a/base/aaa/user.go +++ b/base/aaa/user.go @@ -48,8 +48,8 @@ func _user_search(m *ice.Message, name, text string) { } func UserRoot(m *ice.Message, arg ...string) { // password username userrole + username := m.Option(ice.MSG_USERNAME, kit.Select(ice.Info.UserName, arg, 1)) userrole := m.Option(ice.MSG_USERROLE, kit.Select(ROOT, arg, 2)) - username := m.Option(ice.MSG_USERNAME, kit.Select(kit.Select(ROOT, ice.Info.UserName), arg, 1)) if len(arg) > 0 { _user_create(m, userrole, username, kit.Select("", arg, 0)) } diff --git a/base/cli/cli.go b/base/cli/cli.go index 1230c1de..9c36209f 100644 --- a/base/cli/cli.go +++ b/base/cli/cli.go @@ -6,4 +6,4 @@ const CLI = "cli" var Index = &ice.Context{Name: CLI, Help: "命令模块"} -func init() { ice.Index.Register(Index, nil, RUNTIME, SYSTEM, DAEMON, QRCODE, FOREVER) } +func init() { ice.Index.Register(Index, nil, RUNTIME, QRCODE, SYSTEM, DAEMON, FOREVER) } diff --git a/base/cli/cli.shy b/base/cli/cli.shy index c751d0a3..4627ac49 100644 --- a/base/cli/cli.shy +++ b/base/cli/cli.shy @@ -1,7 +1,8 @@ chapter "cli" field "环境" runtime +field "扫码" qrcode field "命令" system field "守护" daemon -field "扫码" qrcode +field "启动" forever diff --git a/base/cli/daemon.go b/base/cli/daemon.go index c4676a83..36a0fa79 100644 --- a/base/cli/daemon.go +++ b/base/cli/daemon.go @@ -1,7 +1,6 @@ package cli import ( - "io" "os/exec" ice "shylinux.com/x/icebergs" @@ -42,23 +41,15 @@ func _daemon_exec(m *ice.Message, cmd *exec.Cmd) { m.Cmd(mdb.MODIFY, DAEMON, "", mdb.HASH, mdb.HASH, h, STATUS, STOP) } - switch cb := m.OptionCB(DAEMON).(type) { + switch m.Sleep300ms(); cb := m.OptionCB(DAEMON).(type) { case func(string): - m.Sleep300ms() cb(m.Conf(DAEMON, kit.Keys(mdb.HASH, h, kit.Keym(STATUS)))) case func(): - m.Sleep300ms() cb() } - if w, ok := m.Optionv(CMD_INPUT).(io.Closer); ok { - w.Close() - } - if w, ok := m.Optionv(CMD_OUTPUT).(io.Closer); ok { - w.Close() - } - if w, ok := m.Optionv(CMD_ERRPUT).(io.Closer); ok { - w.Close() + for _, p := range kit.Simple(CMD_INPUT, CMD_OUTPUT, CMD_ERRPUT) { + kit.Close(m.Optionv(p)) } }) } @@ -77,12 +68,12 @@ const ( CHECK = "check" BENCH = "bench" PPROF = "pprof" + CLEAR = "clear" TIMEOUT = "timeout" STATUS = "status" ERROR = "error" START = "start" - CLEAR = "clear" RESTART = "restart" RELOAD = "reload" STOP = "stop" @@ -130,7 +121,7 @@ func init() { m.OptionFields(m.Config(mdb.FIELD)) m.Cmd(mdb.SELECT, DAEMON, "", mdb.HASH, m.OptionSimple(mdb.HASH)).Table(func(index int, value map[string]string, head []string) { m.Cmd(mdb.MODIFY, DAEMON, "", mdb.HASH, m.OptionSimple(mdb.HASH), STATUS, STOP) - m.Cmdy(SYSTEM, "kill", "-9", value[PID]) + m.Cmdy(SYSTEM, "kill", value[PID]) }) }}, }, mdb.HashAction()), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { diff --git a/base/cli/forever.go b/base/cli/forever.go index bfb3897e..b98bbad3 100644 --- a/base/cli/forever.go +++ b/base/cli/forever.go @@ -9,6 +9,10 @@ import ( kit "shylinux.com/x/toolkits" ) +func BinPath(arg ...string) string { + return kit.Join(kit.Simple(arg, kit.Path(ice.BIN), kit.Path(ice.USR_LOCAL_BIN), kit.Path(ice.USR_LOCAL_GO_BIN), kit.Env(PATH)), ice.DF) +} + const FOREVER = "forever" func init() { @@ -16,24 +20,22 @@ func init() { Index.Merge(&ice.Context{Commands: map[string]*ice.Command{ FOREVER: {Name: "forever", Help: "启动", Action: map[string]*ice.Action{ SERVE: {Name: "serve", Help: "服务", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(FOREVER, os.Args[0], SERVE, START, ice.DEV, "", aaa.USERNAME, aaa.ROOT, aaa.PASSWORD, aaa.ROOT, arg) + env := []string{PATH, BinPath()} + for _, k := range []string{HOME, CTX_SHY, CTX_DEV, CTX_OPS, CTX_ARG, CTX_PID, CTX_USER, CTX_SHARE, CTX_RIVER} { + env = append(env, k, kit.Env(k)) + } + m.Option(CMD_ENV, env) + + m.Option(CMD_ERRPUT, kit.Select(ice.BIN_BOOT_LOG, kit.Env(CTX_LOG))) + m.Cmdy(FOREVER, kit.Select(os.Args[0], nfs.PWD+ice.BIN_ICE_BIN, kit.FileExists(ice.BIN_ICE_BIN)), + SERVE, START, ice.DEV, "", aaa.USERNAME, aaa.ROOT, aaa.PASSWORD, aaa.ROOT, arg) }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { for { - if arg[1] == SERVE { - if _, e := os.Stat(ice.BIN_ICE_BIN); e == nil { - arg[0] = nfs.PWD + ice.BIN_ICE_BIN - } - } println(kit.Format("%s run %s", kit.Now(), kit.Join(arg, ice.SP))) - m.Option(CMD_OUTPUT, os.Stdout) - m.Option(CMD_ERRPUT, os.Stderr) - switch msg := m.Cmd(SYSTEM, arg); msg.Append(CODE) { - case "0": + if m.Sleep("1s"); IsSuccess(m.Cmd(SYSTEM, arg, kit.Dict(CMD_INPUT, os.Stdin, CMD_OUTPUT, os.Stdout))) { println(kit.Format("%s exit", kit.Now())) return - default: - m.Sleep("1s") } } }}}, diff --git a/base/cli/qrcode.go b/base/cli/qrcode.go index aa0cb02c..b8499487 100644 --- a/base/cli/qrcode.go +++ b/base/cli/qrcode.go @@ -47,7 +47,7 @@ func _parse_color(str string) color.Color { } return _trans_web[str] } -func _trans_cli(str string) string { +func _parse_cli_color(str string) string { res := 0 r, g, b, _ := _parse_color(str).RGBA() if r > LIGHT { @@ -63,8 +63,8 @@ func _trans_cli(str string) string { } func _qrcode_cli(m *ice.Message, text string) { qr, _ := qrcode.New(text, qrcode.Medium) - fg := _trans_cli(m.Option(FG)) - bg := _trans_cli(m.Option(BG)) + fg := _parse_cli_color(m.Option(FG)) + bg := _parse_cli_color(m.Option(BG)) data := qr.Bitmap() for i, row := range data { @@ -95,7 +95,7 @@ func _qrcode_web(m *ice.Message, text string) { func Color(m *ice.Message, c string, str interface{}) string { wrap, color := `%v`, c if m.IsCliUA() { - wrap, color = "\033[3%sm%v\033[0m", _trans_cli(c) + wrap, color = "\033[3%sm%v\033[0m", _parse_cli_color(c) } return fmt.Sprintf(wrap, color, str) } @@ -128,9 +128,7 @@ const ( const QRCODE = "qrcode" func init() { - Index.Merge(&ice.Context{Configs: map[string]*ice.Config{ - QRCODE: {Name: QRCODE, Help: "二维码", Value: kit.Data()}, - }, Commands: map[string]*ice.Command{ + Index.Merge(&ice.Context{Commands: map[string]*ice.Command{ QRCODE: {Name: "qrcode text fg bg size auto", Help: "二维码", Action: map[string]*ice.Action{ ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { ice.AddRender(ice.RENDER_QRCODE, func(m *ice.Message, cmd string, args ...interface{}) string { diff --git a/base/cli/runtime.go b/base/cli/runtime.go index 6baa7c10..0adf92af 100644 --- a/base/cli/runtime.go +++ b/base/cli/runtime.go @@ -1,8 +1,6 @@ package cli import ( - "bytes" - "io/ioutil" "os" "os/user" "path" @@ -10,6 +8,7 @@ import ( "strings" ice "shylinux.com/x/icebergs" + "shylinux.com/x/icebergs/base/aaa" "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" @@ -24,14 +23,14 @@ func _runtime_init(m *ice.Message) { // 环境变量 conf for _, k := range []string{CTX_SHY, CTX_DEV, CTX_OPS, CTX_ARG, CTX_PID, CTX_USER, CTX_SHARE, CTX_RIVER} { - m.Conf(RUNTIME, kit.Keys(CONF, k), os.Getenv(k)) + m.Conf(RUNTIME, kit.Keys(CONF, k), kit.Env(k)) } // 主机信息 host m.Conf(RUNTIME, kit.Keys(HOST, GOARCH), runtime.GOARCH) m.Conf(RUNTIME, kit.Keys(HOST, GOOS), runtime.GOOS) - m.Conf(RUNTIME, kit.Keys(HOST, "pid"), os.Getpid()) - m.Conf(RUNTIME, kit.Keys(HOST, HOME), os.Getenv(HOME)) + m.Conf(RUNTIME, kit.Keys(HOST, PID), os.Getpid()) + m.Conf(RUNTIME, kit.Keys(HOST, HOME), kit.Env(HOME)) osid := "" m.Cmd(nfs.CAT, "/etc/os-release", func(text string) { if ls := kit.Split(text, "="); len(ls) > 1 { @@ -45,19 +44,19 @@ func _runtime_init(m *ice.Message) { // 启动信息 boot if name, e := os.Hostname(); e == nil { - m.Conf(RUNTIME, kit.Keys(BOOT, HOSTNAME), kit.Select(name, os.Getenv("HOSTNAME"))) + m.Conf(RUNTIME, kit.Keys(BOOT, HOSTNAME), kit.Select(name, kit.Env("HOSTNAME"))) } if name, e := os.Getwd(); e == nil { - name = path.Base(kit.Select(name, os.Getenv("PWD"))) - ls := strings.Split(name, ice.PS) - name = ls[len(ls)-1] - ls = strings.Split(name, "\\") - name = ls[len(ls)-1] + name = path.Base(kit.Select(name, kit.Env("PWD"))) + name = kit.Slice(strings.Split(name, ice.PS), -1)[0] + name = kit.Slice(strings.Split(name, "\\"), -1)[0] m.Conf(RUNTIME, kit.Keys(BOOT, PATHNAME), name) } - if m.Conf(RUNTIME, kit.Keys(BOOT, USERNAME), kit.Select(os.Getenv(USER), os.Getenv(CTX_USER))) == "" { + if m.Conf(RUNTIME, kit.Keys(BOOT, USERNAME), kit.Select(kit.Env(USER), kit.Env(CTX_USER))) == "" { if user, e := user.Current(); e == nil && user.Name != "" { - m.Conf(RUNTIME, kit.Keys(BOOT, USERNAME), kit.Select(user.Name, os.Getenv(CTX_USER))) + m.Conf(RUNTIME, kit.Keys(BOOT, USERNAME), kit.Select(user.Name, kit.Env(CTX_USER))) + } else { + m.Conf(RUNTIME, kit.Keys(BOOT, USERNAME), aaa.ROOT) } } ice.Info.HostName = m.Conf(RUNTIME, kit.Keys(BOOT, HOSTNAME)) @@ -65,44 +64,34 @@ func _runtime_init(m *ice.Message) { ice.Info.UserName = m.Conf(RUNTIME, kit.Keys(BOOT, USERNAME)) // 启动次数 boot - count := kit.Int(m.Conf(RUNTIME, kit.Keys(BOOT, mdb.COUNT))) + 1 - m.Conf(RUNTIME, kit.Keys(BOOT, mdb.COUNT), count) - m.Conf(RUNTIME, kit.Keys(BOOT, ice.BIN), m.Cmdx(SYSTEM, "which", os.Args[0])) - - // 节点信息 node - m.Conf(RUNTIME, kit.Keys(NODE, mdb.TIME), m.Time()) - NodeInfo(m, "worker", m.Conf(RUNTIME, kit.Keys(BOOT, PATHNAME))) - - runtime.GOMAXPROCS(kit.Int(kit.Select("1", m.Conf(RUNTIME, kit.Keys(HOST, "GOMAXPROCS"))))) + m.Conf(RUNTIME, kit.Keys(BOOT, mdb.COUNT), kit.Int(m.Conf(RUNTIME, kit.Keys(BOOT, mdb.COUNT)))+1) + m.Conf(RUNTIME, kit.Keys(BOOT, ice.BIN), _system_find(m, os.Args[0])) } func _runtime_hostinfo(m *ice.Message) { - if f, e := os.Open("/proc/cpuinfo"); e == nil { - defer f.Close() - if b, e := ioutil.ReadAll(f); e == nil { - m.Push("nCPU", bytes.Count(b, []byte("processor"))) - } - } - if f, e := os.Open("/proc/meminfo"); e == nil { - defer f.Close() - if b, e := ioutil.ReadAll(f); e == nil { - for i, ls := range strings.Split(string(b), ice.NL) { - vs := kit.Split(ls, ": ") - m.Push(strings.TrimSpace(vs[0]), kit.FmtSize(kit.Int64(strings.TrimSpace(vs[1]))*1024)) - if i > 1 { - break - } - } + m.Push("nCPU", strings.Count(m.Cmdx(nfs.CAT, "/proc/cpuinfo"), "processor")) + for i, ls := range strings.Split(m.Cmdx(nfs.CAT, "/proc/meminfo"), ice.NL) { + vs := kit.Split(ls, ": ") + if m.Push(strings.TrimSpace(vs[0]), kit.FmtSize(kit.Int64(strings.TrimSpace(vs[1]))*1024)); i > 1 { + break } } m.Push("uptime", kit.Split(m.Cmdx(SYSTEM, "uptime"), ice.FS)[0]) } +func _runtime_diskinfo(m *ice.Message) { + m.Spawn().Split(m.Cmdx(SYSTEM, "df", "-h"), "", ice.SP, ice.NL).Table(func(index int, value map[string]string, head []string) { + if strings.HasPrefix(value["Filesystem"], "/dev") { + m.Push("", value, head) + } + }) + m.Display("/plugin/story/pie.js?field=Size") + m.RenameAppend("%iused", "piused") + m.RenameAppend("Use%", "Usep") +} func NodeInfo(m *ice.Message, kind, name string) { - name = strings.ReplaceAll(name, ice.PT, "_") - m.Conf(RUNTIME, kit.Keys(NODE, mdb.TYPE), kind) - m.Conf(RUNTIME, kit.Keys(NODE, mdb.NAME), name) - ice.Info.NodeName = name - ice.Info.NodeType = kind + m.Conf(RUNTIME, kit.Keys(NODE, mdb.TIME), m.Time()) + ice.Info.NodeType = m.Conf(RUNTIME, kit.Keys(NODE, mdb.TYPE), kind) + ice.Info.NodeName = m.Conf(RUNTIME, kit.Keys(NODE, mdb.NAME), strings.ReplaceAll(name, ice.PT, "_")) } const ( @@ -114,20 +103,21 @@ const ( NODE = "node" ) const ( - GOARCH = "GOARCH" + GOARCH = "GOARCH" + X386 = "386" + AMD64 = "amd64" + ARM64 = "arm64" + ARM = "arm" + GOOS = "GOOS" - X386 = "386" - AMD64 = "amd64" - ARM64 = "arm64" - ARM = "arm" LINUX = "linux" DARWIN = "darwin" WINDOWS = "windows" OSID = "OSID" + ALPINE = "alpine" CENTOS = "centos" UBUNTU = "ubuntu" - ALPINE = "alpine" ) const ( USER = "USER" @@ -152,10 +142,12 @@ const ( USERNAME = "username" ) const ( + MAXPROCS = "maxprocs" IFCONFIG = "ifconfig" HOSTINFO = "hostinfo" USERINFO = "userinfo" PROCINFO = "procinfo" + PROCKILL = "prockill" BOOTINFO = "bootinfo" DISKINFO = "diskinfo" ) @@ -168,6 +160,13 @@ func init() { RUNTIME: {Name: "runtime info=ifconfig,hostinfo,hostname,userinfo,procinfo,bootinfo,diskinfo auto", Help: "运行环境", Action: map[string]*ice.Action{ ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { _runtime_init(m) + m.Cmd(RUNTIME, MAXPROCS, "1") + }}, + MAXPROCS: {Name: "maxprocs", Help: "最大并发", Hand: func(m *ice.Message, arg ...string) { + if len(arg) > 0 { + runtime.GOMAXPROCS(kit.Int(m.Conf(RUNTIME, kit.Keys(HOST, "GOMAXPROCS"), kit.Select("1", arg, 0)))) + } + m.Echo("%d", runtime.GOMAXPROCS(0)) }}, IFCONFIG: {Name: "ifconfig", Help: "网卡配置", Hand: func(m *ice.Message, arg ...string) { m.Cmdy("tcp.host") @@ -177,9 +176,7 @@ func init() { }}, HOSTNAME: {Name: "hostname", Help: "主机域名", Hand: func(m *ice.Message, arg ...string) { if len(arg) > 0 { - m.Conf(RUNTIME, kit.Keys(NODE, mdb.NAME), arg[0]) - m.Conf(RUNTIME, kit.Keys(BOOT, HOSTNAME), arg[0]) - ice.Info.HostName = arg[0] + ice.Info.HostName = m.Conf(RUNTIME, kit.Keys(BOOT, HOSTNAME), m.Conf(RUNTIME, kit.Keys(NODE, mdb.NAME), arg[0])) } m.Echo(ice.Info.HostName) }}, @@ -187,30 +184,22 @@ func init() { m.Split(m.Cmdx(SYSTEM, "who"), "user term time") }}, PROCINFO: {Name: "procinfo", Help: "进程信息", Hand: func(m *ice.Message, arg ...string) { - m.Split(m.Cmdx(SYSTEM, "ps", "u")) - m.PushAction("prockill") + m.Split(m.Cmdx(SYSTEM, "ps", "u")).PushAction(PROCKILL) m.StatusTimeCount() }}, - "prockill": {Name: "prockill", Help: "结束进程", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(SYSTEM, "prockill", m.Option("PID")) + PROCKILL: {Name: "prockill", Help: "结束进程", Hand: func(m *ice.Message, arg ...string) { + m.Cmdy(SYSTEM, "kill", m.Option("PID")) m.ProcessRefresh30ms() }}, DISKINFO: {Name: "diskinfo", Help: "磁盘信息", Hand: func(m *ice.Message, arg ...string) { - m.Spawn().Split(m.Cmdx(SYSTEM, "df", "-h"), "", ice.SP, ice.NL).Table(func(index int, value map[string]string, head []string) { - if strings.HasPrefix(value["Filesystem"], "/dev") { - m.Push("", value, head) - } - }) - m.Display("/plugin/story/pie.js?field=Size") - m.RenameAppend("%iused", "piused") - m.RenameAppend("Use%", "Usep") + _runtime_diskinfo(m) }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if len(arg) > 0 && arg[0] == BOOTINFO { arg = arg[1:] } m.Cmdy(ctx.CONFIG, RUNTIME, arg) - m.Display("/plugin/story/json.js") + m.DisplayStory("json.js") }}, }}) } diff --git a/base/cli/system.go b/base/cli/system.go index 217c2dd2..4694abb1 100644 --- a/base/cli/system.go +++ b/base/cli/system.go @@ -3,7 +3,6 @@ package cli import ( "bytes" "io" - "io/ioutil" "os" "os/exec" "path" @@ -21,8 +20,7 @@ func _system_cmd(m *ice.Message, arg ...string) *exec.Cmd { // 运行目录 if cmd.Dir = m.Option(CMD_DIR); len(cmd.Dir) > 0 { - m.Log_EXPORT(CMD_DIR, cmd.Dir) - if _, e := os.Stat(cmd.Dir); e != nil && os.IsNotExist(e) { + if m.Log_EXPORT(CMD_DIR, cmd.Dir); !kit.FileExists(cmd.Dir) { os.MkdirAll(cmd.Dir, ice.MOD_DIR) } } @@ -38,11 +36,11 @@ func _system_cmd(m *ice.Message, arg ...string) *exec.Cmd { } } - // // 定制目录 - if buf, err := ioutil.ReadFile(ice.ETC_PATH); err == nil && len(buf) > 0 { - if file := _system_find(m, arg[0], strings.Split(string(buf), ice.NL)...); file != "" { - // m.Debug("cmd: %v", file) - // cmd.Path = file + // 定制目录 + if text := kit.ReadFile(ice.ETC_PATH); len(text) > 0 { + if file := _system_find(m, arg[0], strings.Split(text, ice.NL)...); file != "" { + m.Debug("cmd: %v", file) + cmd.Path = file } } m.Debug("cmd: %v", cmd.Path) @@ -65,12 +63,18 @@ func _system_out(m *ice.Message, out string) io.Writer { return nil } func _system_find(m *ice.Message, bin string, dir ...string) string { + if strings.HasPrefix(bin, ice.PS) { + return bin + } + if strings.HasPrefix(bin, nfs.PWD) { + return kit.Path(bin) + } if len(dir) == 0 { - dir = append(dir, strings.Split(os.Getenv(PATH), ice.DF)...) + dir = append(dir, strings.Split(kit.Env(PATH), ice.DF)...) } for _, p := range dir { if _, err := os.Stat(path.Join(p, bin)); err == nil { - return path.Join(p, bin) + return kit.Path(path.Join(p, bin)) } } return "" @@ -99,7 +103,7 @@ func _system_exec(m *ice.Message, cmd *exec.Cmd) { } // 执行命令 - if e := cmd.Run(); !m.Warn(e, ice.ErrNotFound, kit.Format(cmd.Args)) { + if e := cmd.Run(); !m.Warn(e, ice.ErrNotFound, cmd.Args) { m.Cost(CODE, cmd.ProcessState.ExitCode(), ctx.ARGS, cmd.Args) } @@ -131,7 +135,7 @@ func init() { Index.Merge(&ice.Context{Configs: map[string]*ice.Config{ SYSTEM: {Name: SYSTEM, Help: "系统命令", Value: kit.Data(mdb.FIELD, "time,id,cmd")}, }, Commands: map[string]*ice.Command{ - SYSTEM: {Name: "system cmd run:button", Help: "系统命令", Action: map[string]*ice.Action{ + SYSTEM: {Name: "system cmd run", Help: "系统命令", Action: map[string]*ice.Action{ nfs.FIND: {Name: "find", Help: "查找", Hand: func(m *ice.Message, arg ...string) { m.Echo(_system_find(m, arg[0], arg[1:]...)) }}, diff --git a/base/nfs/cat.go b/base/nfs/cat.go index 4515ad6e..c5d70633 100644 --- a/base/nfs/cat.go +++ b/base/nfs/cat.go @@ -73,7 +73,7 @@ func _cat_list(m *ice.Message, name string) { } f := _cat_find(m, name) - if m.Warn(f == nil, ice.ErrNotFound) { + if m.Warn(f == nil, ice.ErrNotFound, name) { return // 没有文件 } defer f.Close() @@ -117,6 +117,7 @@ const ( TEMPLATE = "template" SOURCE = "source" + BINARY = "binary" TARGET = "target" MASTER = "master" diff --git a/base/nfs/save.go b/base/nfs/save.go index 23f65c5a..57305e67 100644 --- a/base/nfs/save.go +++ b/base/nfs/save.go @@ -12,6 +12,10 @@ import ( func _defs_file(m *ice.Message, name string, text ...string) { if _, e := os.Stat(path.Join(m.Option(DIR_ROOT), name)); os.IsNotExist(e) { + for i, v := range text { + b, _ := kit.Render(v, m) + text[i] = string(b) + } _save_file(m, name, text...) } } diff --git a/base/ssh/scripts.go b/base/ssh/scripts.go index a8958ed7..87c21bf8 100644 --- a/base/ssh/scripts.go +++ b/base/ssh/scripts.go @@ -122,6 +122,7 @@ func (f *Frame) parse(m *ice.Message, line string) string { f.res = Render(msg, msg.Option(ice.MSG_OUTPUT), msg.Optionv(ice.MSG_ARGS).([]interface{})...) } + m.Sleep("10ms") return "" } func (f *Frame) scan(m *ice.Message, h, line string) *Frame { @@ -129,7 +130,7 @@ func (f *Frame) scan(m *ice.Message, h, line string) *Frame { f.ps2 = kit.Simple(m.Confv(PROMPT, kit.Keym(PS2))) ps := f.ps1 - m.Sleep300ms() + m.Sleep("100ms") m.I, m.O = f.stdin, f.stdout bio := bufio.NewScanner(f.stdin) for f.prompt(m, ps...); bio.Scan() && f.stdin != nil; f.prompt(m, ps...) { @@ -264,21 +265,21 @@ func init() { return // 脚本解析 } }}, - TARGET: {Name: "target name run:button", Help: "当前模块", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + TARGET: {Name: "target name run", Help: "当前模块", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { f := c.Server().(*Frame) m.Search(arg[0]+ice.PT, func(p *ice.Context, s *ice.Context, key string) { f.target = s }) f.prompt(m) }}, - PROMPT: {Name: "prompt arg run:button", Help: "命令提示", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + PROMPT: {Name: "prompt arg run", Help: "命令提示", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { f := m.Optionv(FRAME).(*Frame) f.ps1 = arg f.prompt(m) }}, - PRINTF: {Name: "printf run:button text", Help: "输出显示", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + PRINTF: {Name: "printf run text", Help: "输出显示", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { f := m.Optionv(FRAME).(*Frame) f.printf(m, arg[0]) }}, - SCREEN: {Name: "screen run:button text", Help: "输出命令", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + SCREEN: {Name: "screen run text", Help: "输出命令", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { f := m.Optionv(FRAME).(*Frame) for _, line := range kit.Split(arg[0], ice.NL, ice.NL) { fmt.Fprintf(f.pipe, line+ice.NL) diff --git a/base/web/dream.go b/base/web/dream.go index 88a4341e..2285e7f3 100644 --- a/base/web/dream.go +++ b/base/web/dream.go @@ -1,7 +1,6 @@ package web import ( - "io/ioutil" "os" "path" "strings" @@ -21,7 +20,7 @@ func _dream_list(m *ice.Message) *ice.Message { m.Push(mdb.TYPE, val[mdb.TYPE]) m.Push(cli.STATUS, cli.START) m.PushButton(cli.STOP) - m.PushAnchor(strings.Split(kit.MergePOD(m.Option(ice.MSG_USERWEB), value[mdb.NAME]), "?")[0]) + m.PushAnchor(strings.Split(m.MergePOD(value[mdb.NAME]), "?")[0]) }) == nil { m.Push(mdb.TYPE, WORKER) m.Push(cli.STATUS, cli.STOP) @@ -48,48 +47,42 @@ func _dream_show(m *ice.Message, name string) { // 任务模板 if m.Option(nfs.TEMPLATE) != "" { for _, file := range []string{ice.ETC_MISS_SH, ice.SRC_MAIN_SHY, ice.SRC_MAIN_GO, ice.GO_MOD, ice.MAKEFILE} { - if _, e := os.Stat(path.Join(p, file)); os.IsNotExist(e) { - switch m.Cmdy(nfs.COPY, path.Join(p, file), path.Join(m.Option(nfs.TEMPLATE), file)); file { - case ice.GO_MOD: - kit.Rewrite(path.Join(p, file), func(line string) string { - return kit.Select(line, "module "+name, strings.HasPrefix(line, "module")) - }) - } + if kit.FileExists(path.Join(p, file)) { + continue + } + switch m.Cmdy(nfs.COPY, path.Join(p, file), path.Join(m.Option(nfs.TEMPLATE), file)); file { + case ice.GO_MOD: + kit.Rewrite(path.Join(p, file), func(line string) string { + return kit.Select(line, "module "+name, strings.HasPrefix(line, "module")) + }) } } } // 任务脚本 - miss := path.Join(p, ice.ETC_MISS_SH) - if _, e := os.Stat(miss); os.IsNotExist(e) { - m.Cmd(nfs.SAVE, miss, m.Config("miss")) - } + m.Cmd(nfs.DEFS, path.Join(p, ice.ETC_MISS_SH), m.Config("miss")) defer m.Cmdy(nfs.DIR, p) - if b, e := ioutil.ReadFile(path.Join(p, m.Conf(gdb.SIGNAL, kit.Keym(cli.PID)))); e == nil { - if s, e := os.Stat("/proc/" + string(b)); e == nil && s.IsDir() { - m.Info("already exists %v", string(b)) - return // 已经启动 - } - } - if m.Cmd(SPACE, name).Length() > 0 { + if pid := m.Cmdx(nfs.CAT, path.Join(p, m.Conf(gdb.SIGNAL, kit.Keym(nfs.PATH)))); pid != "" && kit.FileExists("/proc/"+pid) { + m.Info("already exists %v", pid) + return // 已经启动 + } else if m.Cmd(SPACE, name).Length() > 0 { return // 已经启动 } - m.ToastProcess() - defer m.ToastSuccess() + defer m.ToastProcess() m.Optionv(cli.CMD_DIR, p) m.Optionv(cli.CMD_ENV, kit.Simple( - cli.CTX_DEV, "http://:"+m.Cmd(SERVE, ice.OptionFields("")).Append(tcp.PORT), - cli.PATH, kit.Path(path.Join(p, ice.BIN))+":"+kit.Path(ice.BIN)+":"+os.Getenv(cli.PATH), - cli.USER, ice.Info.UserName, cli.HOME, os.Getenv(cli.HOME), m.Configv(cli.ENV), + cli.CTX_OPS, "http://:"+m.Cmd(SERVE, ice.OptionFields("")).Append(tcp.PORT), + cli.PATH, cli.BinPath(kit.Path(p, ice.BIN)), cli.HOME, kit.Env(cli.HOME), + cli.USER, ice.Info.UserName, m.Configv(cli.ENV), )) - m.Optionv(cli.CMD_OUTPUT, path.Join(p, m.Config(kit.Keys(cli.ENV, cli.CTX_LOG)))) + m.Optionv(cli.CMD_OUTPUT, path.Join(p, ice.BIN_BOOT_LOG)) // 启动任务 - bin := cli.SystemFind(m, "ice.bin", kit.Path(path.Join(p, ice.BIN)), kit.Path(ice.BIN)) - m.Cmd(cli.DAEMON, kit.Select(kit.Path(os.Args[0]), bin), SPACE, tcp.DIAL, ice.DEV, ice.OPS, mdb.NAME, name, m.OptionSimple(RIVER)) + bin := kit.Select(os.Args[0], cli.SystemFind(m, ice.ICE_BIN, kit.Path(path.Join(p, ice.BIN)), kit.Path(ice.BIN))) + m.Cmd(cli.DAEMON, bin, SPACE, tcp.DIAL, ice.DEV, ice.OPS, m.OptionSimple(mdb.NAME, RIVER)) defer m.Event(DREAM_CREATE, kit.SimpleKV("", m.Option(mdb.TYPE), name)...) m.Sleep3s() } @@ -104,23 +97,23 @@ const DREAM = "dream" func init() { Index.Merge(&ice.Context{Commands: map[string]*ice.Command{ DREAM: {Name: "dream name path auto start", Help: "梦想家", Action: map[string]*ice.Action{ + mdb.INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) { + _dream_list(m).Cut("name,status,time") + }}, cli.START: {Name: "start name repos river", Help: "启动", Hand: func(m *ice.Message, arg ...string) { _dream_show(m, m.Option(mdb.NAME, kit.Select(path.Base(m.Option(nfs.REPOS)), m.Option(mdb.NAME)))) }}, + cli.STOP: {Name: "stop", Help: "停止", Hand: func(m *ice.Message, arg ...string) { + m.Cmdy(SPACE, mdb.MODIFY, m.OptionSimple(mdb.NAME), mdb.STATUS, cli.STOP) + m.Cmdy(SPACE, m.Option(mdb.NAME), ice.EXIT) + }}, DREAM_STOP: {Name: "dream.stop type name", Help: "停止", Hand: func(m *ice.Message, arg ...string) { if m.Cmd(SPACE, m.Option(mdb.NAME)).Append(mdb.STATUS) == cli.STOP { m.Cmdy(SPACE, mdb.REMOVE, m.OptionSimple(mdb.NAME)) - return + } else { + m.Cmdy(SPACE, mdb.REMOVE, m.OptionSimple(mdb.NAME)) + m.Sleep("1s", DREAM, cli.START, m.OptionSimple(mdb.NAME)) } - m.Cmdy(SPACE, mdb.REMOVE, m.OptionSimple(mdb.NAME)) - m.Sleep("1s", DREAM, cli.START, m.OptionSimple(mdb.NAME)) - }}, - cli.STOP: {Name: "stop", Help: "停止", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(SPACE, mdb.MODIFY, m.OptionSimple(mdb.NAME), mdb.STATUS, cli.STOP) - m.Cmdy(SPACE, m.Option(mdb.NAME), "exit", "0") - }}, - mdb.INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) { - _dream_list(m).Cut("name,status,time") }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if len(arg) == 0 { @@ -133,8 +126,7 @@ func init() { }}, }, Configs: map[string]*ice.Config{ DREAM: {Name: DREAM, Help: "梦想家", Value: kit.Data(nfs.PATH, ice.USR_LOCAL_WORK, - cli.ENV, kit.Dict(cli.CTX_LOG, ice.BIN_BOOT_LOG), - "miss", `#!/bin/bash + "miss", `#! /bin/sh if [ "$ISH_CONF_PRE" = "" ]; then [ -f $PWD/.ish/plug.sh ] || [ -f $HOME/.ish/plug.sh ] || git clone ${ISH_CONF_HUB_PROXY:="https://"}shylinux.com/x/intshell $PWD/.ish source $PWD/.ish/plug.sh || source $HOME/.ish/plug.sh diff --git a/base/web/serve.go b/base/web/serve.go index bb89e99e..d2ae0592 100644 --- a/base/web/serve.go +++ b/base/web/serve.go @@ -254,6 +254,7 @@ func init() { }, Commands: map[string]*ice.Command{ SERVE: {Name: "serve name auto start spide", Help: "服务器", Action: ice.MergeAction(map[string]*ice.Action{ ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { + cli.NodeInfo(m, WORKER, ice.Info.PathName) AddRewrite(func(w http.ResponseWriter, r *http.Request) bool { if r.Method == SPIDE_GET && r.URL.Path == ice.PS { msg := m.Spawn(SERVE, w, r) @@ -282,6 +283,8 @@ func init() { } }}, cli.START: {Name: "start dev name=ops proto=http host port=9020 nodename password username userrole", Help: "启动", Hand: func(m *ice.Message, arg ...string) { + ice.Info.Address = kit.Select(kit.Format("%s://%s:%s", m.Option(tcp.PROTO), + kit.Select(m.Cmd(tcp.HOST).Append(aaa.IP), m.Option(tcp.HOST)), m.Option(tcp.PORT)), ice.Info.Address) if cli.NodeInfo(m, SERVER, kit.Select(ice.Info.HostName, m.Option("nodename"))); m.Option(tcp.PORT) == tcp.RANDOM { m.Option(tcp.PORT, m.Cmdx(tcp.PORT, aaa.RIGHT)) } diff --git a/base/web/spide.go b/base/web/spide.go index 5a069392..7577fe08 100644 --- a/base/web/spide.go +++ b/base/web/spide.go @@ -336,7 +336,7 @@ func init() { LOGHEADERS, ice.FALSE, )}, }, Commands: map[string]*ice.Command{ - SPIDE: {Name: "spide client.name action=raw,msg,save,cache method=GET,PUT,POST,DELETE url format=form,part,json,data,file arg run:button create", Help: "蜘蛛侠", Action: ice.MergeAction(map[string]*ice.Action{ + SPIDE: {Name: "spide client.name action=raw,msg,save,cache method=GET,PUT,POST,DELETE url format=form,part,json,data,file arg run create", Help: "蜘蛛侠", Action: ice.MergeAction(map[string]*ice.Action{ ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { conf := m.Confm(cli.RUNTIME, "conf") m.Cmd(SPIDE, mdb.CREATE, ice.OPS, kit.Select("http://:9020", conf["ctx_ops"])) @@ -355,14 +355,14 @@ func init() { _spide_list(m, arg...) }}, - SPIDE_GET: {Name: "GET url key value run:button", Help: "蜘蛛侠", Action: map[string]*ice.Action{ + SPIDE_GET: {Name: "GET url key value run", Help: "蜘蛛侠", Action: map[string]*ice.Action{ mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(mdb.DELETE, SPIDE, "", mdb.HASH, m.OptionSimple(CLIENT_NAME)) }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Echo(kit.Formats(kit.UnMarshal(m.Cmdx(SPIDE, ice.DEV, SPIDE_RAW, SPIDE_GET, arg[0], arg[1:])))) }}, - SPIDE_POST: {Name: "POST url key value run:button", Help: "蜘蛛侠", Action: map[string]*ice.Action{ + SPIDE_POST: {Name: "POST url key value run", Help: "蜘蛛侠", Action: map[string]*ice.Action{ mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(mdb.DELETE, SPIDE, "", mdb.HASH, m.OptionSimple(CLIENT_NAME)) }}, diff --git a/conf.go b/conf.go index e76f2ade..c4b13c3c 100644 --- a/conf.go +++ b/conf.go @@ -110,6 +110,7 @@ const ( // DIR USR_LOCAL = "usr/local" USR_LOCAL_GO = "usr/local/go" + USR_LOCAL_GO_BIN = "usr/local/go/bin" USR_LOCAL_BIN = "usr/local/bin" USR_LOCAL_LIB = "usr/local/lib" USR_LOCAL_WORK = "usr/local/work" @@ -143,6 +144,7 @@ const ( // DIR SRC_VERSION_GO = "src/version.go" SRC_BINPACK_GO = "src/binpack.go" MAKEFILE = "Makefile" + ICE_BIN = "ice.bin" GO_MOD = "go.mod" GO_SUM = "go.sum" ) diff --git a/core/chat/header.go b/core/chat/header.go index 7110ba3a..08afc57d 100644 --- a/core/chat/header.go +++ b/core/chat/header.go @@ -23,6 +23,7 @@ func _header_check(m *ice.Message, arg ...string) { m.Option(web.LOGIN, m.Config(web.LOGIN)) m.Option(web.SSO, m.Conf(web.SERVE, kit.Keym(web.SSO))) } + m.Option("login.dev", m.Cmd(web.SPACE, ice.DEV).Append(mdb.TEXT)) } func _header_grant(m *ice.Message, arg ...string) { m.Cmd(GRANT, mdb.INSERT, kit.SimpleKV("space,grant,userrole,username", diff --git a/core/chat/river.go b/core/chat/river.go index 95e647ca..b5b52d9c 100644 --- a/core/chat/river.go +++ b/core/chat/river.go @@ -168,7 +168,6 @@ func init() { }}, aaa.INVITE: {Name: "invite", Help: "脚本", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(code.PUBLISH, ice.CONTEXTS) - m.Cmd(code.PUBLISH, mdb.CREATE, nfs.FILE, ice.BIN_ICE_SH) m.Cmd(code.PUBLISH, mdb.CREATE, nfs.FILE, ice.BIN_ICE_BIN) }}, SHARE: {Name: "share", Help: "共享", Hand: func(m *ice.Message, arg ...string) { _header_share(m, arg...) }}, diff --git a/core/code/autogen.go b/core/code/autogen.go index 5033d885..20bbb671 100644 --- a/core/code/autogen.go +++ b/core/code/autogen.go @@ -1,7 +1,6 @@ package code import ( - "os" "path" "strings" @@ -22,7 +21,7 @@ func _defs(m *ice.Message, args ...string) { } } func _autogen_module(m *ice.Message, dir string) { - buf, _ := kit.Render(`package {{.Option "zone"}} + m.Cmd(nfs.DEFS, dir, `package {{.Option "zone"}} import ( "shylinux.com/x/ice" @@ -39,8 +38,7 @@ func (h {{.Option "name"}}) List(m *ice.Message, arg ...string) { } func init() { ice.Cmd("{{.Option "key"}}", {{.Option "name"}}{}) } -`, m) - m.Cmd(nfs.DEFS, dir, string(buf)) +`) } func _autogen_import(m *ice.Message, main string, ctx string, mod string) (list []string) { m.Cmd(nfs.DEFS, main, `package main @@ -59,7 +57,7 @@ func main() { print(ice.Run()) } list = append(list, kit.Format(` _ "%s/src/%s"`, mod, ctx), "") done = true } else if strings.HasPrefix(line, "import") { - list = append(list, "", kit.Format(`import _ "%s/src/%s"`, mod, ctx), "") + list = append(list, kit.Format(`import _ "%s/src/%s"`, mod, ctx)) done = true } }) @@ -68,11 +66,10 @@ func main() { print(ice.Run()) } return } func _autogen_script(m *ice.Message, dir string) { - buf, _ := kit.Render(`chapter "{{.Option "name"}}" + m.Cmd(nfs.DEFS, dir, `chapter "{{.Option "name"}}" field "{{.Option "help"}}" {{.Option "key"}} -`, m) - m.Cmd(nfs.DEFS, dir, string(buf)) +`) } func _autogen_source(m *ice.Message, zone, name string) { m.Cmd(nfs.PUSH, ice.SRC_MAIN_SHY, ice.NL, nfs.SOURCE+ice.SP+path.Join(zone, kit.Keys(name, SHY)), ice.NL) @@ -92,11 +89,26 @@ go 1.11 return } +func _autogen_git(m *ice.Message, arg ...string) map[string]interface{} { + return kit.Dict("Time", m.Time(), arg, + "Hash", strings.TrimSpace(m.Cmdx(cli.SYSTEM, "git", "log", "-n1", `--pretty=%H`)), + "Remote", strings.TrimSpace(m.Cmdx(cli.SYSTEM, "git", "config", "remote.origin.url")), + "Branch", strings.TrimSpace(m.Cmdx(cli.SYSTEM, "git", "rev-parse", "--abbrev-ref", "HEAD")), + "Version", strings.TrimSpace(m.Cmdx(cli.SYSTEM, "git", "describe", "--tags")), + ) +} +func _autogen_gits(m *ice.Message, arg ...string) string { + res := []string{} + kit.Fetch(_autogen_git(m, arg...), func(k string, v interface{}) { + res = append(res, kit.Format(` %s: "%s",`, k, v)) + }) + return kit.Join(res, ice.NL) +} func _autogen_version(m *ice.Message) { - if _, e := os.Stat(".git"); os.IsNotExist(e) { + if !kit.FileExists(".git") { m.Cmdy(cli.SYSTEM, "git", "init") } - if _, e := os.Stat("go.mod"); os.IsNotExist(e) { + if !kit.FileExists("go.mod") { m.Cmdy(cli.SYSTEM, "go", "mod", "init", path.Base(kit.Path(""))) } @@ -106,30 +118,20 @@ func _autogen_version(m *ice.Message) { m.Cmd(nfs.SAVE, ice.SRC_VERSION_GO, kit.Format(`package main import ( - "shylinux.com/x/icebergs" + ice "shylinux.com/x/icebergs" ) func init() { - ice.Info.Make.Time = "%s" - ice.Info.Make.Hash = "%s" - ice.Info.Make.Remote = "%s" - ice.Info.Make.Branch = "%s" - ice.Info.Make.Version = "%s" - ice.Info.Make.HostName = "%s" - ice.Info.Make.UserName = "%s" + ice.Info.Make = ice.MakeInfo{ +%s + } } -`, - m.Time(), - strings.TrimSpace(m.Cmdx(cli.SYSTEM, "git", "log", "-n1", `--pretty=%H`)), - strings.TrimSpace(m.Cmdx(cli.SYSTEM, "git", "config", "remote.origin.url")), - strings.TrimSpace(m.Cmdx(cli.SYSTEM, "git", "rev-parse", "--abbrev-ref", "HEAD")), - strings.TrimSpace(m.Cmdx(cli.SYSTEM, "git", "describe", "--tags")), - ice.Info.HostName, ice.Info.UserName, - )) +`, _autogen_gits(m, "HostName", ice.Info.HostName, "UserName", ice.Info.UserName))) - m.Cmdy(nfs.DIR, ice.SRC_BINPACK_GO) - m.Cmdy(nfs.DIR, ice.SRC_VERSION_GO) m.Cmdy(nfs.DIR, ice.SRC_MAIN_GO) + m.Cmdy(nfs.DIR, ice.SRC_VERSION_GO) + m.Cmdy(nfs.DIR, ice.SRC_BINPACK_GO) + m.Cmdy(nfs.DIR, "usr/release/binpack.go") } func _autogen_miss(m *ice.Message) { m.Cmd(nfs.DEFS, ice.ETC_MISS_SH, m.Conf(web.DREAM, kit.Keym("miss"))) @@ -148,8 +150,7 @@ func init() { mdb.INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) { switch arg[0] { case MAIN: - m.Cmdy(nfs.DIR, ice.SRC, "path,size,time", ice.Option{nfs.DIR_REG, `.*\.go`}) - m.RenameAppend(nfs.PATH, arg[0]) + m.Cmdy(nfs.DIR, ice.SRC, "path,size,time", kit.Dict(nfs.DIR_REG, `.*\.go`)).RenameAppend(nfs.PATH, arg[0]) } }}, mdb.CREATE: {Name: "create main=src/main.go@key zone name=hi help type=Hash,Zone,Lists,Data,Code list key", Help: "模块", Hand: func(m *ice.Message, arg ...string) { @@ -157,23 +158,22 @@ func init() { _defs(m, mdb.KEY, kit.Keys("web.code", m.Option(mdb.ZONE), m.Option(mdb.NAME))) switch kit.Select("Zone", m.Option(mdb.TYPE)) { case "Hash": - _defs(m, "list", m.Option(mdb.NAME)+" hash auto create") + _defs(m, mdb.LIST, m.Option(mdb.NAME)+" hash auto create") case "Zone": - _defs(m, "list", m.Option(mdb.NAME)+" zone id auto insert") + _defs(m, mdb.LIST, m.Option(mdb.NAME)+" zone id auto insert") case "Lists": - _defs(m, "list", m.Option(mdb.NAME)+" id auto insert") + _defs(m, mdb.LIST, m.Option(mdb.NAME)+" id auto insert") case "Data": - _defs(m, "list", m.Option(mdb.NAME)+" path auto") + _defs(m, mdb.LIST, m.Option(mdb.NAME)+" path auto") case "Code": - _defs(m, "list", m.Option(mdb.NAME)+" port path auto start order build download") + _defs(m, mdb.LIST, m.Option(mdb.NAME)+" port path auto start order build download") } - m.Option("tags", kit.Format("`name:\"%s\" help:\"%s\"`", m.Option("list"), m.Option("help"))) + m.Option("tags", kit.Format("`name:\"%s\" help:\"%s\"`", m.Option(mdb.LIST), m.Option(mdb.HELP))) if p := path.Join(ice.SRC, m.Option(mdb.ZONE), kit.Keys(m.Option(mdb.NAME), GO)); !kit.FileExists(p) { _autogen_module(m, p) _autogen_import(m, m.Option(MAIN), m.Option(mdb.ZONE), _autogen_mod(m, ice.GO_MOD)) } - if p := path.Join(ice.SRC, m.Option(mdb.ZONE), kit.Keys(m.Option(mdb.NAME), SHY)); !kit.FileExists(p) { _autogen_script(m, p) _autogen_source(m, m.Option(mdb.ZONE), m.Option(mdb.NAME)) @@ -187,9 +187,10 @@ func init() { _autogen_version(m) m.Cmd(BINPACK, mdb.CREATE) m.Cmd(cli.SYSTEM, "sh", "-c", `cat src/binpack.go|sed 's/package main/package ice/g' > usr/release/binpack.go`) + m.Cmd(nfs.COPY, path.Join(ice.USR_RELEASE, "conf.go"), path.Join(ice.USR_ICEBERGS, "conf.go")) }}, "relay": {Name: "relay alias username host port list", Help: "跳板", Hand: func(m *ice.Message, arg ...string) { - m.Cmd(nfs.SAVE, path.Join(os.Getenv(cli.HOME), ".ssh/"+m.Option(mdb.ALIAS)+".json"), + m.Cmd(nfs.SAVE, path.Join(kit.Env(cli.HOME), ".ssh/"+m.Option(mdb.ALIAS)+".json"), kit.Formats(kit.Dict(m.OptionSimple("username,host,port,list")))) m.Cmd(nfs.LINK, path.Join(ice.USR_PUBLISH, m.Option(mdb.ALIAS)), "relay") }}, diff --git a/core/code/compile.go b/core/code/compile.go index bf2eb14a..3cd7c312 100644 --- a/core/code/compile.go +++ b/core/code/compile.go @@ -1,42 +1,52 @@ package code import ( - "os" "path" + "strings" ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/cli" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" "shylinux.com/x/icebergs/base/tcp" + "shylinux.com/x/icebergs/base/web" kit "shylinux.com/x/toolkits" ) const COMPILE = "compile" func init() { + const GIT = "git" Index.Merge(&ice.Context{Configs: map[string]*ice.Config{ - COMPILE: {Name: COMPILE, Help: "编译", Value: kit.Data( - nfs.PATH, ice.USR_PUBLISH, cli.ENV, kit.Dict( - "GOPRIVATE", "shylinux.com,github.com", "GOPROXY", "https://goproxy.cn,direct", - "CGO_ENABLED", "0", - ), GO, kit.List(GO, cli.BUILD), + COMPILE: {Name: COMPILE, Help: "编译", Value: kit.Data(nfs.PATH, ice.USR_PUBLISH, + cli.ENV, kit.Dict("GOPROXY", "https://goproxy.cn,direct", "GOPRIVATE", "shylinux.com,github.com", "CGO_ENABLED", "0"), )}, }, Commands: map[string]*ice.Command{ - COMPILE: {Name: "compile arch=amd64,386,arm,arm64 os=linux,darwin,windows src=src/main.go@key run:button", Help: "编译", Action: map[string]*ice.Action{ + COMPILE: {Name: "compile arch=amd64,386,arm,arm64 os=linux,darwin,windows src=src/main.go@key run binpack install", Help: "编译", Action: map[string]*ice.Action{ mdb.INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(nfs.DIR, ice.SRC, "path,size,time", ice.Option{nfs.DIR_REG, `.*\.go$`}) - m.Sort(nfs.PATH) + m.Cmdy(nfs.DIR, ice.SRC, "path,size,time", kit.Dict(nfs.DIR_REG, `.*\.go$`)).Sort(nfs.PATH) + }}, + BINPACK: {Name: "binpack", Help: "打包", Hand: func(m *ice.Message, arg ...string) { + m.Cmdy(AUTOGEN, BINPACK) + }}, + INSTALL: {Name: "compile", Help: "安装", Hand: func(m *ice.Message, arg ...string) { + if strings.Contains(m.Cmdx(cli.RUNTIME, kit.Keys(tcp.HOST, cli.OSID)), cli.ALPINE) { + web.PushStream(m) + m.Cmd(cli.SYSTEM, "apk", "add", GIT, GO) + return + } + if m.Cmdx(cli.SYSTEM, nfs.FIND, GIT) == "" { + m.Toast("please install git") + m.Echo(ice.FALSE) + return + } + m.Cmd(INSTALL, web.DOWNLOAD, "https://golang.google.cn/dl/go1.15.5.linux-amd64.tar.gz", ice.USR_LOCAL) }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - if len(arg) == 0 { - m.Cmdy(nfs.DIR, m.Config(nfs.PATH)) + if m.Cmdx(cli.SYSTEM, nfs.FIND, GO) == "" && m.Cmdx(COMPILE, INSTALL) == ice.FALSE { return } - if m.Cmdx(cli.SYSTEM, nfs.FIND, "go") == "" { - m.Cmd(INSTALL, COMPILE) - } - m.Cmd(cli.SYSTEM, "go", "get", "shylinux.com/x/ice") + m.Cmd(cli.SYSTEM, GO, "get", "shylinux.com/x/ice") // 交叉编译 main, file := ice.SRC_MAIN_GO, "" @@ -57,29 +67,21 @@ func init() { } } if file == "" { - file = path.Join(kit.Select("", m.Config(nfs.PATH), m.Option(cli.CMD_DIR) == ""), - kit.Keys(kit.Select(ice.ICE, kit.TrimExt(main), main != ice.SRC_MAIN_GO), goos, arch)) + file = path.Join(m.Config(nfs.PATH), kit.Keys(kit.Select(ice.ICE, kit.TrimExt(main), main != ice.SRC_MAIN_GO), goos, arch)) } // 执行编译 _autogen_version(m.Spawn()) - m.Optionv(cli.CMD_ENV, kit.Simple(m.Configv(cli.ENV), cli.HOME, os.Getenv(cli.HOME), cli.PATH, os.Getenv(cli.PATH), cli.GOOS, goos, cli.GOARCH, arch)) - if msg := m.Cmd(cli.SYSTEM, "go", "build", "-o", file, main, ice.SRC_VERSION_GO, ice.SRC_BINPACK_GO); !cli.IsSuccess(msg) { + m.Optionv(cli.CMD_ENV, kit.Simple(m.Configv(cli.ENV), cli.HOME, kit.Env(cli.HOME), cli.PATH, kit.Env(cli.PATH), cli.GOOS, goos, cli.GOARCH, arch)) + if msg := m.Cmd(cli.SYSTEM, GO, cli.BUILD, "-o", file, main, ice.SRC_VERSION_GO, ice.SRC_BINPACK_GO); !cli.IsSuccess(msg) { m.Copy(msg) return } // 编译成功 m.Log_EXPORT(nfs.SOURCE, main, nfs.TARGET, file) - m.Cmdy(nfs.DIR, file, "time,path,size,link,action") - name := path.Base(m.Append(nfs.PATH)) - m.EchoScript(kit.Format("# 下载启动\nwget %s && chmod u+x %s\n./%s forever serve dev %s\ntail -f var/log/bench.log", - m.MergeURL2(kit.Format("/publish/%s", name)), name, name, m.MergeURL2(ice.PS))) - m.EchoScript(kit.Format("# 下载启动\ncurl -fOL %s && chmod u+x %s\n./%s forever serve dev %s\ntail -f var/log/bench.log", - m.MergeURL2(kit.Format("/publish/%s", name)), name, name, m.MergeURL2(ice.PS))) - m.Cmd(PUBLISH, mdb.CREATE, ice.BIN_ICE_SH) - m.Cmdy(PUBLISH, ice.CONTEXTS, ice.CORE) - m.Cmdy(PUBLISH, ice.CONTEXTS, "binary") + m.Cmdy(PUBLISH, ice.CONTEXTS, "core", "binary") + m.Cmdy(nfs.DIR, file, "time,path,size,link") m.StatusTimeCount() }}, }}) diff --git a/core/code/install.go b/core/code/install.go index cb302d84..7541da50 100644 --- a/core/code/install.go +++ b/core/code/install.go @@ -176,25 +176,6 @@ func init() { defer m.StatusTime(nfs.PATH, m.Option(nfs.DIR_ROOT)) m.Cmdy(nfs.DIR, m.Option(nfs.PATH)) }}, - COMPILE: {Name: "compile", Help: "编译", Hand: func(m *ice.Message, arg ...string) { - web.PushStream(m) - defer m.ProcessHold() - - osid := m.Cmdx(cli.RUNTIME, "host.OSID") - switch { - case strings.Contains(osid, cli.ALPINE): - m.Cmd(cli.SYSTEM, "apk", "add", "git", "go") - case strings.Contains(osid, cli.CENTOS): - m.Cmdy(INSTALL, web.DOWNLOAD, "https://golang.google.cn/dl/go1.15.5.linux-amd64.tar.gz", ice.USR_LOCAL) - - case strings.Contains(osid, cli.UBUNTU): - m.Cmdy(INSTALL, web.DOWNLOAD, "https://golang.google.cn/dl/go1.15.5.linux-amd64.tar.gz", ice.USR_LOCAL) - default: - m.Toast("please install git and go") - return - } - m.ToastSuccess() - }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { switch len(arg) { case 0: // 源码列表 diff --git a/core/code/publish.go b/core/code/publish.go index f39fd3f3..403d68a8 100644 --- a/core/code/publish.go +++ b/core/code/publish.go @@ -35,6 +35,7 @@ func _bin_list(m *ice.Message, dir string) { func _publish_file(m *ice.Message, file string, arg ...string) string { if strings.HasSuffix(file, "ice.bin") { // 打包应用 arg = kit.Simple(kit.Keys(ice.ICE, runtime.GOOS, runtime.GOARCH)) + file = kit.Path(os.Args[0]) } else if s, e := os.Stat(file); m.Assert(e) && s.IsDir() { p := path.Base(file) + ".tar.gz" @@ -99,7 +100,8 @@ echo "hello world" }}, ice.CONTEXTS: {Name: "contexts", Help: "环境", Hand: func(m *ice.Message, arg ...string) { u := kit.ParseURL(tcp.ReplaceLocalhost(m, 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, ice.DF)[0], + kit.Select(kit.Select("80", "443", u.Scheme == "https"), strings.Split(u.Host, ice.DF), 1))) if len(arg) == 0 { arg = append(arg, "core", "binary") @@ -139,7 +141,7 @@ echo "hello world" web.PushStream(m) defer m.ProcessHold() defer m.StatusTimeCount() - m.Cmd(nfs.TAR, kit.Path(ice.USR_PUBLISH, "vim.tar.gz"), ".vim/plugged", kit.Dict(nfs.DIR_ROOT, os.Getenv(cli.HOME))) + m.Cmd(nfs.TAR, kit.Path(ice.USR_PUBLISH, "vim.tar.gz"), ".vim/plugged", kit.Dict(nfs.DIR_ROOT, kit.Env(cli.HOME))) m.Cmd(nfs.TAR, kit.Path(ice.USR_PUBLISH, "contexts.lib.tar.gz"), ice.USR_LOCAL_LIB) m.Cmd(nfs.TAR, kit.Path(ice.USR_PUBLISH, "contexts.bin.tar.gz"), list) m.Cmd(PUBLISH, mdb.CREATE, ice.ETC_PATH) @@ -159,11 +161,13 @@ echo "hello world" } var _contexts = kit.Dict( - "binary", `# 官方启动 -ctx_temp=$(mktemp); curl -fsSL https://shylinux.com -o $ctx_temp; source $ctx_temp binary + "core", `# 定制版 +export ctx_dev={{.Option "httphost"}}; ctx_temp=$(mktemp); curl -o $ctx_temp -fsSL $ctx_dev; source $ctx_temp app +export ctx_dev={{.Option "httphost"}}; ctx_temp=$(mktemp); wget -O $ctx_temp $ctx_dev; source $ctx_temp app `, - "core", `# 脚本启动 -export ctx_dev={{.Option "httphost"}}; ctx_temp=$(mktemp); curl -fsSL $ctx_dev -o $ctx_temp; source $ctx_temp app + "binary", `# 官方版 +ctx_temp=$(mktemp); curl -o $ctx_temp -fsSL https://shylinux.com; source $ctx_temp binary +ctx_temp=$(mktemp); wget -O $ctx_temp https://shylinux.com; source $ctx_temp binary `, "source", `# 下载源码 diff --git a/core/code/upgrade.go b/core/code/upgrade.go index 98e9d651..3fc40764 100644 --- a/core/code/upgrade.go +++ b/core/code/upgrade.go @@ -28,7 +28,7 @@ func init() { )), ))}, }, Commands: map[string]*ice.Command{ - UPGRADE: {Name: "upgrade item=system,source run:button", Help: "升级", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + UPGRADE: {Name: "upgrade item=system,source run", Help: "升级", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Grows(cmd, kit.Keys(mdb.HASH, kit.Select(cli.SYSTEM, arg, 0)), "", "", func(index int, value map[string]interface{}) { if value[nfs.PATH] == ice.BIN_ICE_BIN { // 程序文件 value[nfs.FILE] = kit.Keys(ice.ICE, runtime.GOOS, runtime.GOARCH) diff --git a/core/code/vimer.go b/core/code/vimer.go index f0ca34e2..7592dcd6 100644 --- a/core/code/vimer.go +++ b/core/code/vimer.go @@ -32,7 +32,6 @@ func init() { m.Cmdy(AUTOGEN, BINPACK) m.Cmd(nfs.COPY, ice.GO_MOD, path.Join(ice.SRC_RELEASE, ice.GO_MOD)) m.Cmd(nfs.COPY, ice.GO_SUM, path.Join(ice.SRC_RELEASE, ice.GO_SUM)) - m.Cmd(nfs.COPY, path.Join(ice.USR_RELEASE, "conf.go"), path.Join(ice.USR_ICEBERGS, "conf.go")) m.ProcessInner() }}, DEVPACK: {Name: "devpack", Help: "开发模式", Hand: func(m *ice.Message, arg ...string) { diff --git a/go.mod b/go.mod index f598c7be..056f03be 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,6 @@ go 1.11 require ( shylinux.com/x/go-qrcode v0.0.1 - shylinux.com/x/toolkits v0.4.9 + shylinux.com/x/toolkits v0.5.0 shylinux.com/x/websocket v0.0.1 ) diff --git a/go.sum b/go.sum index ddcb3d70..93e5dc93 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,6 @@ shylinux.com/x/go-qrcode v0.0.1 h1:/eOGqMj1qtgs9Ymd12zTUa1gcJZs9S92kj2lb0QzKsE= shylinux.com/x/go-qrcode v0.0.1/go.mod h1:KAbtU+KwiiABMZ/CJ0zh9PI2AX82Uf9rRYcQ4ODm4po= -shylinux.com/x/toolkits v0.4.9 h1:1RQR+XQQ5x2Jwga9LxGjOyrQ0AdzDhRIvdNSFbxfVBA= -shylinux.com/x/toolkits v0.4.9/go.mod h1:8LbYHe7oxBIqb6s4MSOD+4d28QvPdvkyCVtwB/JW7AA= +shylinux.com/x/toolkits v0.5.0 h1:dUgMiBIrlQWkZoB2vXdf5g/RqsImoh3d5D0Us2++yHQ= +shylinux.com/x/toolkits v0.5.0/go.mod h1:8LbYHe7oxBIqb6s4MSOD+4d28QvPdvkyCVtwB/JW7AA= shylinux.com/x/websocket v0.0.1 h1:OBc21DxqsGlQ2+Pz76xqLyDNo1LV+PUUqfWi+1PZPDE= shylinux.com/x/websocket v0.0.1/go.mod h1:AaSpMToOxbMULKQytzczeHPuqb708vK1vrAzCxLo/XE= diff --git a/info.go b/info.go index 81b5aadd..46cf1839 100644 --- a/info.go +++ b/info.go @@ -7,33 +7,37 @@ import ( kit "shylinux.com/x/toolkits" ) +type MakeInfo struct { + Time string + Hash string + Remote string + Branch string + Version string + HostName string + UserName string +} + var Info = struct { HostName string PathName string UserName string PassWord string + Address string NodeType string NodeName string CtxShare string CtxRiver string - Make struct { - Time string - Hash string - Remote string - Branch string - Version string - HostName string - UserName string - } + Make MakeInfo + + Help string + Pack map[string][]byte + File map[string]string + Log func(m *Message, p, l, s string) - Help string - Pack map[string][]byte - names map[string]interface{} render map[string]func(*Message, string, ...interface{}) string - Log func(m *Message, p, l, s string) - File map[string]string + names map[string]interface{} }{ Help: ` ^_^ 欢迎使用冰山框架 ^_^ @@ -43,10 +47,11 @@ report: shylinuxc@gmail.com server: https://shylinux.com source: https://shylinux.com/x/icebergs `, - Pack: map[string][]byte{}, - names: map[string]interface{}{}, + Pack: map[string][]byte{}, + File: map[string]string{}, + render: map[string]func(*Message, string, ...interface{}) string{}, - File: map[string]string{}, + names: map[string]interface{}{}, } func Dump(w io.Writer, name string, cb func(string)) bool { diff --git a/init.go b/init.go index c834fe10..034a1dee 100644 --- a/init.go +++ b/init.go @@ -102,8 +102,8 @@ func init() { Index.root, Pulse.root = Index, Pulse } func Run(arg ...string) string { if len(arg) == 0 { // 进程参数 - if arg = append(arg, os.Args[1:]...); os.Getenv("ctx_arg") != "" { - arg = append(arg, kit.Split(os.Getenv("ctx_arg"))...) + if arg = append(arg, os.Args[1:]...); kit.Env("ctx_arg") != "" { + arg = append(arg, kit.Split(kit.Env("ctx_arg"))...) } } diff --git a/logs.go b/logs.go index 8ac21555..257758ac 100644 --- a/logs.go +++ b/logs.go @@ -59,7 +59,7 @@ func (m *Message) join(arg ...interface{}) string { if i == len(args)-1 { list = append(list, args[i]) } else { - list = append(list, args[i]+kit.Select("", ":", !strings.HasSuffix(strings.TrimSpace(args[i]), ":")), args[i+1]) + list = append(list, args[i]+kit.Select("", ":", !strings.HasSuffix(strings.TrimSpace(args[i]), ":")), kit.Format(args[i+1])) } } return kit.Join(list, SP) diff --git a/misc.go b/misc.go index 4778be84..cbe382f2 100644 --- a/misc.go +++ b/misc.go @@ -154,7 +154,7 @@ func (m *Message) MergeURL2(url string, arg ...interface{}) string { return kit.MergeURL2(m.Option(MSG_USERWEB), url, arg...) } func (m *Message) MergePOD(name string, arg ...interface{}) string { - return kit.MergePOD(kit.Select("http://localhost:9020", m.Option(MSG_USERWEB)), name, arg...) + return kit.MergePOD(kit.Select(Info.Address, m.Option(MSG_USERWEB)), name, arg...) } func (m *Message) cmd(arg ...interface{}) *Message { @@ -309,6 +309,7 @@ func (c *Context) split(name string) (list []interface{}) { case "run": item = kit.Dict(TYPE, BUTTON, NAME, "run") list = append(list, item) + button = true case "text", "args": item = kit.Dict(TYPE, TEXTAREA, NAME, ls[i]) list = append(list, item) diff --git a/misc/git/status.go b/misc/git/status.go index d8710b27..861c0987 100644 --- a/misc/git/status.go +++ b/misc/git/status.go @@ -107,14 +107,14 @@ func _status_each(m *ice.Message, title string, cmds ...string) { }) } func _status_stat(m *ice.Message, files, adds, dels int) (int, int, int) { - for _, v := range kit.Split(m.Cmdx(cli.SYSTEM, GIT, DIFF, "--shortstat"), ice.FS, ice.FS) { + for _, v := range kit.Split(m.Cmdx(cli.SYSTEM, GIT, DIFF, "--shortstat"), ice.FS) { n := kit.Int(kit.Split(strings.TrimSpace(v))[0]) switch { case strings.Contains(v, "file"): files += n case strings.Contains(v, "insert"): adds += n - case strings.Contains(v, "delete"): + case strings.Contains(v, "delet"): dels += n } } @@ -196,55 +196,6 @@ const STATUS = "status" func init() { Index.Merge(&ice.Context{Commands: map[string]*ice.Command{ STATUS: {Name: "status repos auto", Help: "状态机", Action: map[string]*ice.Action{ - PULL: {Name: "pull", Help: "下载", Hand: func(m *ice.Message, arg ...string) { - _status_each(m, PULL, cli.SYSTEM, GIT, PULL) - m.ProcessHold() - }}, - MAKE: {Name: "make", Help: "编译", Hand: func(m *ice.Message, arg ...string) { - web.PushStream(m) - m.Cmdy(cli.SYSTEM, MAKE) - m.Toast(ice.SUCCESS) - m.ProcessHold() - }}, - TAGS: {Name: "tags", Help: "标签", Hand: func(m *ice.Message, arg ...string) { - _status_tags(m) - m.ProcessHold() - }}, - PUSH: {Name: "push", Help: "上传", Hand: func(m *ice.Message, arg ...string) { - if m.Option(REPOS) == "" { - _status_each(m, PUSH, cli.SYSTEM, GIT, PUSH) - m.ProcessHold() - return - } - - _repos_cmd(m, m.Option(REPOS), PUSH) - _repos_cmd(m, m.Option(REPOS), PUSH, "--tags") - }}, - - TAG: {Name: "tag version@key", Help: "标签", Hand: func(m *ice.Message, arg ...string) { - if m.Option(VERSION) == "" { - m.Option(VERSION, _status_tag(m, m.Option(TAGS))) - } - _repos_cmd(m, m.Option(REPOS), TAG, m.Option(VERSION)) - _repos_cmd(m, m.Option(REPOS), PUSH, "--tags") - }}, - STASH: {Name: "stash", Help: "缓存", Hand: func(m *ice.Message, arg ...string) { - _status_each(m, STASH, cli.SYSTEM, GIT, STASH) - m.ProcessHold() - }}, - ADD: {Name: "add", Help: "添加", Hand: func(m *ice.Message, arg ...string) { - _repos_cmd(m, m.Option(REPOS), ADD, m.Option(nfs.FILE)) - }}, OPT: {Name: "opt", Help: "优化"}, PRO: {Name: "pro", Help: "升级"}, - COMMIT: {Name: "commit action=opt,add,pro comment=some@key", Help: "提交", Hand: func(m *ice.Message, arg ...string) { - if arg[0] == ctx.ACTION { - m.Option(mdb.TEXT, arg[1]+ice.SP+arg[3]) - } else { - m.Option(mdb.TEXT, kit.Select("opt some", strings.Join(arg, ice.SP))) - } - - _repos_cmd(m, m.Option(REPOS), COMMIT, "-am", m.Option(mdb.TEXT)) - m.ProcessBack() - }}, mdb.INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) { switch arg[0] { case mdb.NAME: @@ -264,12 +215,61 @@ func init() { } } }}, + PULL: {Name: "pull", Help: "下载", Hand: func(m *ice.Message, arg ...string) { + _status_each(m, PULL, cli.SYSTEM, GIT, PULL) + m.ProcessHold() + }}, + MAKE: {Name: "make", Help: "编译", Hand: func(m *ice.Message, arg ...string) { + web.PushStream(m) + m.Cmdy(cli.SYSTEM, MAKE) + m.ToastSuccess() + m.ProcessHold() + }}, + PUSH: {Name: "push", Help: "上传", Hand: func(m *ice.Message, arg ...string) { + if m.Option(REPOS) == "" { + _status_each(m, PUSH, cli.SYSTEM, GIT, PUSH) + m.ProcessHold() + return + } + + _repos_cmd(m, m.Option(REPOS), PUSH) + _repos_cmd(m, m.Option(REPOS), PUSH, "--tags") + }}, + TAGS: {Name: "tags", Help: "标签", Hand: func(m *ice.Message, arg ...string) { + _status_tags(m) + m.ProcessHold() + }}, + STASH: {Name: "stash", Help: "缓存", Hand: func(m *ice.Message, arg ...string) { + _status_each(m, STASH, cli.SYSTEM, GIT, STASH) + m.ProcessHold() + }}, PIE: {Name: "pie", Help: "饼图", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(TOTAL, PIE) }}, + + ADD: {Name: "add", Help: "添加", Hand: func(m *ice.Message, arg ...string) { + _repos_cmd(m, m.Option(REPOS), ADD, m.Option(nfs.FILE)) + }}, OPT: {Name: "opt", Help: "优化"}, PRO: {Name: "pro", Help: "升级"}, + COMMIT: {Name: "commit action=opt,add,pro comment=some@key", Help: "提交", Hand: func(m *ice.Message, arg ...string) { + if arg[0] == ctx.ACTION { + m.Option(mdb.TEXT, arg[1]+ice.SP+arg[3]) + } else { + m.Option(mdb.TEXT, kit.Select("opt some", strings.Join(arg, ice.SP))) + } + + _repos_cmd(m, m.Option(REPOS), COMMIT, "-am", m.Option(mdb.TEXT)) + m.ProcessBack() + }}, + TAG: {Name: "tag version@key", Help: "标签", Hand: func(m *ice.Message, arg ...string) { + if m.Option(VERSION) == "" { + m.Option(VERSION, _status_tag(m, m.Option(TAGS))) + } + _repos_cmd(m, m.Option(REPOS), TAG, m.Option(VERSION)) + _repos_cmd(m, m.Option(REPOS), PUSH, "--tags") + }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if len(arg) == 0 { - m.Action(PULL, MAKE, PUSH, TAGS, PIE) + m.Action(PULL, MAKE, PUSH, TAGS, STASH, PIE) files, adds, dels, last := _status_list(m) m.Status("files", files, "adds", adds, "dels", dels, "last", last.Format(ice.MOD_TIME)) diff --git a/misc/git/total.go b/misc/git/total.go index 42d96a51..1a9f1653 100644 --- a/misc/git/total.go +++ b/misc/git/total.go @@ -124,15 +124,13 @@ func init() { add, del := "0", "0" if len(l) > 3 { - fs := strings.Split(strings.TrimSpace(l[3]), ", ") - if adds := strings.Split(fs[1], ice.SP); len(fs) > 2 { - dels := strings.Split(fs[2], ice.SP) - add = adds[0] - del = dels[0] - } else if strings.Contains(adds[1], "insertion") { - add = adds[0] - } else { - del = adds[0] + for _, v := range kit.Split(strings.TrimSpace(l[3]), ice.FS) { + switch { + case strings.Contains(v, "insert"): + add = kit.Split(v)[0] + case strings.Contains(v, "delet"): + del = kit.Split(v)[0] + } } } diff --git a/misc/lark/duty.go b/misc/lark/duty.go index bed1a526..44ece266 100644 --- a/misc/lark/duty.go +++ b/misc/lark/duty.go @@ -8,7 +8,7 @@ const DUTY = "duty" func init() { Index.Merge(&ice.Context{Commands: map[string]*ice.Command{ - DUTY: {Name: "duty [title] text run:button", Help: "通告", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { + DUTY: {Name: "duty [title] text run", Help: "通告", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { msg := m.Cmd(APP, m.Option(APP_ID)) m.Cmdy(SEND, msg.Append(APPID), msg.Append(DUTY), arg) }}, diff --git a/misc/ssh/connect.go b/misc/ssh/connect.go index 6b862922..b2045298 100644 --- a/misc/ssh/connect.go +++ b/misc/ssh/connect.go @@ -44,7 +44,7 @@ func _ssh_open(m *ice.Message, arg ...string) { }, arg...) } func _ssh_dial(m *ice.Message, cb func(net.Conn), arg ...string) { - p := path.Join(os.Getenv(cli.HOME), ".ssh/", fmt.Sprintf("%s@%s:%s", m.Option(aaa.USERNAME), m.Option(tcp.HOST), m.Option(tcp.PORT))) + p := path.Join(kit.Env(cli.HOME), ".ssh/", fmt.Sprintf("%s@%s:%s", m.Option(aaa.USERNAME), m.Option(tcp.HOST), m.Option(tcp.PORT))) if _, e := os.Stat(p); e == nil { if c, e := net.Dial("unix", p); e == nil { cb(c) // 会话连接 @@ -84,7 +84,7 @@ func _ssh_dial(m *ice.Message, cb func(net.Conn), arg ...string) { session.Stdout = c session.Stderr = c - session.RequestPty(os.Getenv("TERM"), h, w, ssh.TerminalModes{ + session.RequestPty(kit.Env("TERM"), h, w, ssh.TerminalModes{ ssh.ECHO: 1, ssh.TTY_OP_ISPEED: 14400, ssh.TTY_OP_OSPEED: 14400, @@ -131,7 +131,7 @@ func _ssh_conn(m *ice.Message, cb func(*ssh.Client), arg ...string) { return })) methods = append(methods, ssh.PublicKeysCallback(func() ([]ssh.Signer, error) { - key, err := ssh.ParsePrivateKey([]byte(m.Cmdx(nfs.CAT, path.Join(os.Getenv(cli.HOME), m.Option(PRIVATE))))) + key, err := ssh.ParsePrivateKey([]byte(m.Cmdx(nfs.CAT, path.Join(kit.Env(cli.HOME), m.Option(PRIVATE))))) return []ssh.Signer{key}, err })) methods = append(methods, ssh.PasswordCallback(func() (string, error) { diff --git a/misc/ssh/service.go b/misc/ssh/service.go index 92c47905..80d3c10a 100644 --- a/misc/ssh/service.go +++ b/misc/ssh/service.go @@ -6,7 +6,6 @@ import ( "errors" "fmt" "net" - "os" "path" "strings" @@ -65,7 +64,7 @@ func _ssh_config(m *ice.Message, h string) *ssh.ServerConfig { }, } - if key, err := ssh.ParsePrivateKey([]byte(m.Cmdx(nfs.CAT, path.Join(os.Getenv(cli.HOME), m.Option(PRIVATE))))); m.Assert(err) { + if key, err := ssh.ParsePrivateKey([]byte(m.Cmdx(nfs.CAT, path.Join(kit.Env(cli.HOME), m.Option(PRIVATE))))); m.Assert(err) { config.AddHostKey(key) } return config @@ -142,11 +141,11 @@ func init() { }) if len(list) > 0 { - m.Cmdy(nfs.SAVE, path.Join(os.Getenv(cli.HOME), m.Option(AUTHKEY)), strings.Join(list, ice.NL)+ice.NL) + m.Cmdy(nfs.SAVE, path.Join(kit.Env(cli.HOME), m.Option(AUTHKEY)), strings.Join(list, ice.NL)+ice.NL) } }}, mdb.IMPORT: {Name: "import authkey=.ssh/authorized_keys", Help: "导入", Hand: func(m *ice.Message, arg ...string) { - p := path.Join(os.Getenv(cli.HOME), m.Option(AUTHKEY)) + p := path.Join(kit.Env(cli.HOME), m.Option(AUTHKEY)) for _, pub := range strings.Split(strings.TrimSpace(m.Cmdx(nfs.CAT, p)), ice.NL) { m.Cmd(SERVICE, mdb.INSERT, mdb.TEXT, pub) } diff --git a/misc/ssh/service_darwin.go b/misc/ssh/service_darwin.go index 75ae5b6b..0924f23a 100644 --- a/misc/ssh/service_darwin.go +++ b/misc/ssh/service_darwin.go @@ -4,7 +4,6 @@ import ( "encoding/binary" "io" "net" - "os" "syscall" "unsafe" @@ -34,8 +33,8 @@ func _ssh_handle(m *ice.Message, meta map[string]string, c net.Conn, channel ssh m.Logs(CHANNEL, tcp.HOSTPORT, c.RemoteAddr(), "->", c.LocalAddr()) defer m.Logs("dischan", tcp.HOSTPORT, c.RemoteAddr(), "->", c.LocalAddr()) - shell := kit.Select("bash", os.Getenv("SHELL")) - list := []string{cli.PATH + "=" + os.Getenv(cli.PATH)} + shell := kit.Select("bash", kit.Env("SHELL")) + list := []string{cli.PATH + "=" + kit.Env(cli.PATH)} pty, tty, err := pty.Open() if m.Warn(err) { diff --git a/misc/ssh/service_linux.go b/misc/ssh/service_linux.go index 75ae5b6b..0924f23a 100644 --- a/misc/ssh/service_linux.go +++ b/misc/ssh/service_linux.go @@ -4,7 +4,6 @@ import ( "encoding/binary" "io" "net" - "os" "syscall" "unsafe" @@ -34,8 +33,8 @@ func _ssh_handle(m *ice.Message, meta map[string]string, c net.Conn, channel ssh m.Logs(CHANNEL, tcp.HOSTPORT, c.RemoteAddr(), "->", c.LocalAddr()) defer m.Logs("dischan", tcp.HOSTPORT, c.RemoteAddr(), "->", c.LocalAddr()) - shell := kit.Select("bash", os.Getenv("SHELL")) - list := []string{cli.PATH + "=" + os.Getenv(cli.PATH)} + shell := kit.Select("bash", kit.Env("SHELL")) + list := []string{cli.PATH + "=" + kit.Env(cli.PATH)} pty, tty, err := pty.Open() if m.Warn(err) { diff --git a/option.go b/option.go index 367475f7..44c50d0e 100644 --- a/option.go +++ b/option.go @@ -128,7 +128,7 @@ func (m *Message) StatusTimeCountTotal(arg ...interface{}) { func (m *Message) Confirm(text string) string { return m.Cmdx(SPACE, m.Option(MSG_DAEMON), "confirm", text) } -func (m *Message) ToastProcess(arg ...interface{}) { +func (m *Message) ToastProcess(arg ...interface{}) func() { if len(arg) == 0 { arg = kit.List("", "-1") } @@ -136,6 +136,7 @@ func (m *Message) ToastProcess(arg ...interface{}) { arg = append(arg, "-1") } m.Toast(PROCESS, arg...) + return func() { m.Toast(SUCCESS, arg...) } } func (m *Message) ToastSuccess(arg ...interface{}) { m.Toast(SUCCESS, arg...) diff --git a/type.go b/type.go index acc45b8c..f7fa7090 100644 --- a/type.go +++ b/type.go @@ -471,7 +471,8 @@ func (m *Message) Cmds(arg ...interface{}) *Message { return m.Go(func() { m.cmd(arg...) }) } func (m *Message) Cmdx(arg ...interface{}) string { - return kit.Select("", m.cmd(arg...).meta[MSG_RESULT], 0) + res := kit.Select("", m.cmd(arg...).meta[MSG_RESULT], 0) + return kit.Select("", res, res != ErrWarn) } func (m *Message) Cmdy(arg ...interface{}) *Message { return m.Copy(m.cmd(arg...))