From eba92ecf125a3eaa213b1d7be1d229bec94c562b Mon Sep 17 00:00:00 2001 From: shylinux Date: Fri, 28 Jul 2023 00:48:59 +0800 Subject: [PATCH] add web.route --- base/cli/runtime.go | 38 ++++++++++++------ base/cli/system.go | 3 +- base/mdb/mdb.go | 5 ++- base/web/dream.go | 11 +++++- base/web/option.go | 18 ++++++--- base/web/route.go | 88 +++++++++++++++++++++++++++++++++++++++++ base/web/serve.go | 14 +++---- base/web/space.go | 5 ++- conf.go | 2 + core/chat/action.go | 6 +-- core/chat/macos/dock.go | 1 + core/code/autogen.go | 6 +-- core/code/compile.go | 2 +- core/code/install.go | 3 +- core/wiki/spark.go | 2 +- exec.go | 4 +- info.go | 2 + misc/git/repos.go | 38 +++++++++++------- misc/git/status.go | 14 ++++++- 19 files changed, 206 insertions(+), 56 deletions(-) create mode 100644 base/web/route.go diff --git a/base/cli/runtime.go b/base/cli/runtime.go index 08925dd1..0eb12611 100644 --- a/base/cli/runtime.go +++ b/base/cli/runtime.go @@ -51,23 +51,16 @@ func _runtime_init(m *ice.Message) { m.Conf(RUNTIME, kit.Keys(BOOT, mdb.HASH), msg.Append(mdb.HASH)) m.Conf(RUNTIME, kit.Keys(BOOT, nfs.SIZE), msg.Append(nfs.SIZE)) m.Conf(RUNTIME, kit.Keys(BOOT, ice.BIN), msg.Append(nfs.PATH)) + ice.Info.Hash = msg.Append(mdb.HASH) + ice.Info.Size = msg.Append(nfs.SIZE) } m.Conf(RUNTIME, kit.Keys(BOOT, mdb.COUNT), count+1) m.Conf(RUNTIME, mdb.META, "") m.Conf(RUNTIME, mdb.HASH, "") } func _runtime_hostinfo(m *ice.Message) { + m.Push("time", ice.Info.Make.Time) m.Push("nCPU", runtime.NumCPU()) - if runtime.GOOS == LINUX { - for i, ls := range strings.Split(m.Cmdx(nfs.CAT, "/proc/meminfo"), lex.NL) { - if vs := kit.Split(ls, ": "); len(vs) > 1 { - 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"), mdb.FS)[0]) m.Push("GOMAXPROCS", runtime.GOMAXPROCS(0)) m.Push("NumGoroutine", runtime.NumGoroutine()) var stats runtime.MemStats @@ -77,6 +70,20 @@ func _runtime_hostinfo(m *ice.Message) { m.Push("Objects", stats.HeapObjects) m.Push("NumGC", stats.NumGC) m.Push("LastGC", time.Unix(int64(stats.LastGC)/int64(time.Second), int64(stats.LastGC)%int64(time.Second))) + m.Push("uptime", kit.Split(m.Cmdx(SYSTEM, "uptime"), mdb.FS)[0]) + if runtime.GOOS == LINUX { + for i, ls := range strings.Split(m.Cmdx(nfs.CAT, "/proc/meminfo"), lex.NL) { + if vs := kit.Split(ls, ": "); len(vs) > 1 { + if m.Push(strings.TrimSpace(vs[0]), kit.FmtSize(kit.Int64(strings.TrimSpace(vs[1]))*1024)); i > 1 { + break + } + } + } + } else { + m.Push("MemAvailable", "") + m.Push("MemTotal", "") + m.Push("MemFree", "") + } } func _runtime_diskinfo(m *ice.Message) { m.Spawn().Split(kit.Replace(m.Cmdx(SYSTEM, "df", "-h"), "Mounted on", "Mountedon"), "", lex.SP, lex.NL).Table(func(index int, value ice.Maps, head []string) { @@ -150,7 +157,7 @@ const RUNTIME = "runtime" func init() { Index.MergeCommands(ice.Commands{ - RUNTIME: {Name: "runtime info=bootinfo,ifconfig,diskinfo,hostinfo,userinfo,procstat,procinfo,bootinfo,role,api,cli,cmd,mod,env,path,chain,routine auto", Help: "运行环境", Actions: ice.MergeActions(ice.Actions{ + RUNTIME: {Name: "runtime info=bootinfo,ifconfig,diskinfo,hostinfo,userinfo,procstat,procinfo,bootinfo,role,api,cli,cmd,mod,env,path,chain,routine auto upgrade restart", Help: "运行环境", Actions: ice.MergeActions(ice.Actions{ ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { aaa.White(m, ice.ETC_PATH) aaa.White(m, ice.LICENSE) @@ -233,7 +240,9 @@ func init() { nfs.PATH: {Hand: func(m *ice.Message, arg ...string) { kit.For(_path_split(os.Getenv(PATH)), func(p string) { m.Push(nfs.PATH, p) }) }}, - "chain": {Hand: func(m *ice.Message, arg ...string) { m.Echo(m.FormatChain()) }}, + "chain": {Hand: func(m *ice.Message, arg ...string) { m.Echo(m.FormatChain()) }}, + "upgrade": {Hand: func(m *ice.Message, arg ...string) { m.Cmdy("web.code.upgrade") }}, + RESTART: {Hand: func(m *ice.Message, arg ...string) { m.Cmd(ice.EXIT, 1) }}, aaa.ROLE: {Hand: func(m *ice.Message, arg ...string) { m.Cmd(aaa.ROLE, func(value ice.Maps) { m.Push(mdb.KEY, kit.Keys(value[aaa.ROLE], value[mdb.ZONE], value[mdb.KEY])) }) ctx.DisplayStorySpide(m.Options(nfs.DIR_ROOT, "ice."), mdb.FIELD, mdb.KEY, lex.SPLIT, nfs.PT) @@ -242,6 +251,11 @@ func init() { kit.If(len(arg) > 0 && arg[0] == BOOTINFO, func() { arg = arg[1:] }) m.Cmdy(ctx.CONFIG, RUNTIME, arg) ctx.DisplayStoryJSON(m) + m.Status(mdb.TIME, ice.Info.Make.Time, + mdb.HASH, kit.Cut(ice.Info.Hash, 6), nfs.SIZE, ice.Info.Size, + ice.BIN, _system_find(m, os.Args[0]), mdb.NAME, ice.Info.NodeName, + nfs.REMOTE, ice.Info.Make.Remote, nfs.VERSION, ice.Info.Make.Versions(), + ) }}, }) } diff --git a/base/cli/system.go b/base/cli/system.go index ddcba822..bab9685d 100644 --- a/base/cli/system.go +++ b/base/cli/system.go @@ -10,6 +10,7 @@ import ( "strings" ice "shylinux.com/x/icebergs" + "shylinux.com/x/icebergs/base/aaa" "shylinux.com/x/icebergs/base/lex" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" @@ -32,7 +33,7 @@ func _system_cmd(m *ice.Message, arg ...string) *exec.Cmd { } }) if bin == "" && nfs.Exists(m, ice.ETC_PATH) { - if text := m.Cmdx(nfs.CAT, ice.ETC_PATH); len(text) > 0 { + if text := m.Cmdx(nfs.CAT, ice.ETC_PATH, kit.Dict(aaa.UserRole, aaa.ROOT)); len(text) > 0 { if bin = _system_find(m, arg[0], strings.Split(text, lex.NL)...); bin != "" { m.Logs(FIND, "etcpath cmd", bin) } diff --git a/base/mdb/mdb.go b/base/mdb/mdb.go index 7b443273..afa81684 100644 --- a/base/mdb/mdb.go +++ b/base/mdb/mdb.go @@ -143,7 +143,10 @@ var Index = &ice.Context{Name: MDB, Help: "数据模块", Commands: ice.Commands INPUTS: {Name: "inputs key sub type field value", Hand: func(m *ice.Message, arg ...string) { switch arg[3] { case "index": - m.Cmdy("command", SEARCH, "command", "", "", ice.OptionFields("index")) + m.Cmdy("command") + return + case "args": + m.Cmdy("command", INPUTS, m.Option("index")) return } kit.Switch(arg[2], diff --git a/base/web/dream.go b/base/web/dream.go index 6ccb54da..7ea62ad0 100644 --- a/base/web/dream.go +++ b/base/web/dream.go @@ -101,8 +101,12 @@ func _dream_template(m *ice.Message, p string) { const ( DREAM_CREATE = "dream.create" + DREAM_START = "dream.start" + DREAM_STOP = "dream.stop" DREAM_OPEN = "dream.open" DREAM_CLOSE = "dream.close" + DREAM_TRASH = "dream.trash" + DREAM_REMOVE = "dream.remove" DREAM_INPUTS = "dream.inputs" DREAM_TABLES = "dream.tables" @@ -139,14 +143,19 @@ func init() { } }}, cli.START: {Hand: func(m *ice.Message, arg ...string) { + gdb.Event(m, DREAM_START, arg) _dream_start(m, m.Option(mdb.NAME)) }}, cli.STOP: {Hand: func(m *ice.Message, arg ...string) { + gdb.Event(m, DREAM_STOP, arg) m.Cmd(SPACE, mdb.MODIFY, m.OptionSimple(mdb.NAME), mdb.STATUS, cli.STOP) m.Go(func() { m.Cmd(SPACE, m.Option(mdb.NAME), ice.EXIT) }) m.Sleep30ms() }}, - nfs.TRASH: {Hand: func(m *ice.Message, arg ...string) { nfs.Trash(m, path.Join(ice.USR_LOCAL_WORK, m.Option(mdb.NAME))) }}, + nfs.TRASH: {Hand: func(m *ice.Message, arg ...string) { + gdb.Event(m, DREAM_TRASH, arg) + nfs.Trash(m, path.Join(ice.USR_LOCAL_WORK, m.Option(mdb.NAME))) + }}, DREAM_CLOSE: {Hand: func(m *ice.Message, arg ...string) { if m.Option(cli.DAEMON) == ice.OPS && m.Cmdv(SPACE, m.Option(mdb.NAME), mdb.STATUS) != cli.STOP { m.Go(func() { m.Sleep300ms(DREAM, cli.START, m.OptionSimple(mdb.NAME)) }) diff --git a/base/web/option.go b/base/web/option.go index 9d1b99e5..46323517 100644 --- a/base/web/option.go +++ b/base/web/option.go @@ -9,6 +9,7 @@ import ( "shylinux.com/x/icebergs/base/aaa" "shylinux.com/x/icebergs/base/cli" "shylinux.com/x/icebergs/base/ctx" + "shylinux.com/x/icebergs/base/lex" "shylinux.com/x/icebergs/base/log" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/tcp" @@ -61,7 +62,7 @@ func ProcessIframe(m *ice.Message, name, link string, arg ...string) { }, arg...) } func PushPodCmd(m *ice.Message, cmd string, arg ...string) { - kit.If(m.Length() > 0 && len(m.Appendv(SPACE)) == 0, func() { m.Table(func(value ice.Maps) { m.Push(SPACE, m.Option(ice.MSG_USERPOD)) }) }) + kit.If(m.Length() > 0 && len(m.Appendv(SPACE)) == 0, func() { m.Table(func(value ice.Maps) { m.Push(SPACE, "") }) }) m.Cmds(SPACE, func(value ice.Maps) { if kit.IsIn(value[mdb.TYPE], WORKER, SERVER) { m.Cmd(SPACE, value[mdb.NAME], kit.Select(m.PrefixKey(), cmd), arg).Table(func(index int, val ice.Maps, head []string) { @@ -118,12 +119,19 @@ func ToastProcess(m *ice.Message, arg ...ice.Any) func() { Toast(m, ice.PROCESS, arg...) return func() { Toast(m, ice.SUCCESS) } } -func GoToast(m *ice.Message, title string, cb func(toast func(string, int, int))) { - cb(func(name string, count, total int) { +func GoToast(m *ice.Message, title string, cb func(toast func(string, int, int)) []string) { + _total := 0 + toast := func(name string, count, total int) { kit.If(total == 0, func() { total = 1 }) Toast(m, kit.Format("%s %s/%s", name, strings.TrimSuffix(kit.FmtSize(int64(count)), "B"), strings.TrimSuffix(kit.FmtSize(int64(total)), "B")), - kit.Format("%s %d%%", title, count*100/total), kit.Select("1000", "30000", count < total), count*100/total, + kit.Format("%s %d%%", kit.Select(m.ActionKey(), title), count*100/total), kit.Select("1000", "30000", count < total), count*100/total, ) - }) + _total = total + } + if list := cb(toast); len(list) > 0 { + Toast(m, strings.Join(list, lex.NL), ice.FAILURE, "30s") + } else { + toast(ice.SUCCESS, _total, _total) + } } diff --git a/base/web/route.go b/base/web/route.go new file mode 100644 index 00000000..34baf05e --- /dev/null +++ b/base/web/route.go @@ -0,0 +1,88 @@ +package web + +import ( + ice "shylinux.com/x/icebergs" + "shylinux.com/x/icebergs/base/cli" + "shylinux.com/x/icebergs/base/ctx" + "shylinux.com/x/icebergs/base/lex" + "shylinux.com/x/icebergs/base/mdb" + "shylinux.com/x/icebergs/base/nfs" + kit "shylinux.com/x/toolkits" +) + +const ROUTE = "route" + +func init() { + Index.MergeCommands(ice.Commands{ + ROUTE: {Name: "route space auto travel spide cmds compile", Help: "路由表", Actions: ice.MergeActions(ice.Actions{ + ice.MAIN: {Help: "首页", Hand: func(m *ice.Message, arg ...string) { + ctx.ProcessField(m, CHAT_IFRAME, m.MergePod(kit.Select(m.Option(SPACE), arg, 0)), arg...) + }}, + "compile": {Hand: func(m *ice.Message, arg ...string) { + args := []string{CODE_VIMER, "compile"} + GoToast(m, "", func(toast func(string, int, int)) (list []string) { + msg := m.Cmd("") + count, total := 0, msg.Length() + msg.Table(func(value ice.Maps) { + if toast(value[SPACE], count, total); value[SPACE] == "" { + + } else if msg := m.Cmd(SPACE, value[SPACE], args, ice.Maps{ice.MSG_DAEMON: ""}); !cli.IsSuccess(msg) { + list = append(list, value[SPACE]) + } + count++ + }) + toast(ice.Info.NodeName, count, total) + if msg := m.Cmd(args, ice.Maps{ice.MSG_DAEMON: ""}); cli.IsSuccess(msg) { + list = append(list, ice.Info.NodeName) + } + return + }) + }}, + "cmds": {Name: "cmds index* args", Help: "命令", Hand: func(m *ice.Message, arg ...string) { + args := []string{m.Option(ctx.INDEX)} + kit.If(m.Option(ctx.ARGS), func() { args = append(args, kit.Split(m.Option(ctx.ARGS))...) }) + GoToast(m, "", func(toast func(string, int, int)) (list []string) { + push := func(space string, msg *ice.Message) { + if msg.IsErr() { + list = append(list, space) + } else { + msg.Table(func(index int, val ice.Maps, head []string) { + val[SPACE], head = space, append(head, SPACE) + m.Push("", val, head) + }) + } + } + msg := m.Cmd("") + count, total := 0, msg.Length() + msg.Table(func(value ice.Maps) { + if toast(value[SPACE], count, total); value[SPACE] != "" { + push(value[SPACE], m.Cmd(SPACE, value[SPACE], args, ice.Maps{ice.MSG_DAEMON: ""})) + } + count++ + }) + toast(ice.Info.NodeName, count, total) + push("", m.Cmd(args)) + m.StatusTimeCount(ice.SUCCESS, kit.Format("%d/%d", total-len(list), total)) + return + }) + }}, + "spide": {Help: "导图", Hand: func(m *ice.Message, arg ...string) { + ctx.DisplayStorySpide(m.Cmdy(""), nfs.DIR_ROOT, ice.Info.NodeName, mdb.FIELD, SPACE, lex.SPLIT, nfs.PT, ctx.ACTION, ice.MAIN) + }}, + "travel": {Help: "遍历", Hand: func(m *ice.Message, arg ...string) { + m.Push(mdb.TIME, ice.Info.Make.Time) + m.Push("md5", ice.Info.Hash) + m.Push(nfs.SIZE, ice.Info.Size) + m.Push(nfs.MODULE, ice.Info.Make.Module) + m.Push(nfs.VERSION, ice.Info.Make.Versions()) + PushPodCmd(m, "", m.ActionKey()) + m.Table(func(value ice.Maps) { kit.If(value[SPACE], func() { mdb.HashCreate(m.Spawn(), kit.Simple(value)) }) }) + m.StatusTimeCount() + }}, + }, ctx.CmdAction(), mdb.HashAction(mdb.SHORT, SPACE, mdb.FIELD, "time,space,module,version,md5,size", mdb.ACTION, ice.MAIN)), Hand: func(m *ice.Message, arg ...string) { + if mdb.HashSelect(m, arg...).Sort(SPACE); len(arg) > 0 { + m.EchoIFrame(m.MergePod(arg[0])) + } + }}, + }) +} diff --git a/base/web/serve.go b/base/web/serve.go index 3a704e8a..ddc4652e 100644 --- a/base/web/serve.go +++ b/base/web/serve.go @@ -60,7 +60,7 @@ func _serve_main(m *ice.Message, w http.ResponseWriter, r *http.Request) bool { if m.Logs(r.Header.Get(ice.MSG_USERIP), r.Method, r.URL.String()); r.Method == http.MethodGet { if msg := m.Spawn(w, r).Options(ice.MSG_USERUA, r.UserAgent()); path.Join(r.URL.Path) == nfs.PS { if !msg.IsCliUA() { - if r.URL.Path = kit.Select(nfs.PS, mdb.Config(m, "main")); path.Join(r.URL.Path) != nfs.PS { + if r.URL.Path = kit.Select(nfs.PS, mdb.Config(m, ice.MAIN)); path.Join(r.URL.Path) != nfs.PS { return true } } @@ -69,16 +69,14 @@ func _serve_main(m *ice.Message, w http.ResponseWriter, r *http.Request) bool { return !Render(msg, ice.RENDER_DOWNLOAD, p) } } else if r.Method == http.MethodPost && path.Join(r.URL.Path) == nfs.PS { - r.URL.Path = kit.Select(nfs.PS, mdb.Config(m, "main")) + r.URL.Path = kit.Select(nfs.PS, mdb.Config(m, ice.MAIN)) } return true } func _serve_handle(key string, cmd *ice.Command, m *ice.Message, w http.ResponseWriter, r *http.Request) { debug := strings.Contains(r.URL.String(), "debug=true") || strings.Contains(r.Header.Get(Referer), "debug=true") - debug = true _log := func(level string, arg ...ice.Any) *ice.Message { - return m.Logs(strings.Title(level), arg...) - if debug || arg[0] == "cmds" { + if debug || arg[0] == ice.MSG_CMDS { return m.Logs(strings.Title(level), arg...) } return m @@ -101,7 +99,7 @@ func _serve_handle(key string, cmd *ice.Command, m *ice.Message, w http.Response r.ParseMultipartForm(kit.Int64(kit.Select("4096", r.Header.Get(ContentLength)))) kit.For(r.PostForm, func(k string, v []string) { _log(FORM, k, kit.Join(v, lex.SP)).Optionv(k, v) }) } - m.Option("_cmd_count", 0) + m.Option(ice.MSG_COUNT, "0") kit.For(r.Cookies(), func(k, v string) { m.Optionv(k, v) }) m.OptionDefault(ice.MSG_HEIGHT, "480", ice.MSG_WIDTH, "320") m.Options(ice.MSG_USERWEB, _serve_domain(m), ice.MSG_USERPOD, m.Option(ice.POD)) @@ -157,8 +155,8 @@ func _serve_auth(m *ice.Message, key string, cmds []string, w http.ResponseWrite m.Auth(aaa.USERNICK, m.Option(ice.MSG_USERNICK, ls[1]), aaa.USERNAME, m.Option(ice.MSG_USERNAME, ls[2]), aaa.USERROLE, m.Option(ice.MSG_USERROLE, ls[3]), CACHE, ls[0]) } } - m.Cmd(COUNT, mdb.CREATE, aaa.IP, m.Option(ice.MSG_USERIP), m.Option(ice.MSG_USERUA)) - m.Cmd(COUNT, mdb.CREATE, m.R.Method, m.R.URL.Path, kit.Join(kit.Simple(m.Optionv(ice.MSG_CMDS)), " ")) + m.Cmd(COUNT, mdb.CREATE, aaa.IP, m.Option(ice.MSG_USERIP), m.Option(ice.MSG_USERUA), kit.Dict(ice.LOG_DISABLE, ice.TRUE)) + m.Cmd(COUNT, mdb.CREATE, m.R.Method, m.R.URL.Path, kit.Join(kit.Simple(m.Optionv(ice.MSG_CMDS)), " "), kit.Dict(ice.LOG_DISABLE, ice.TRUE)) return cmds, aaa.Right(m, key, cmds) } diff --git a/base/web/space.go b/base/web/space.go index b2d2dbe3..aecfcd44 100644 --- a/base/web/space.go +++ b/base/web/space.go @@ -121,7 +121,7 @@ func _space_exec(m *ice.Message, source, target []string, c *websocket.Conn) { case cli.PWD: m.Push(mdb.LINK, m.MergePod(kit.Select("", source, -1))) default: - m.Options("__target", kit.Reverse(kit.Simple(source)), "_cmd_count", 0) + m.Options("__target", kit.Reverse(kit.Simple(source))).OptionDefault(ice.MSG_COUNT, "0") kit.If(aaa.Right(m, m.Detailv()), func() { m.TryCatch(m, true, func(_ *ice.Message) { m = m.Cmd() }) }) } defer m.Cost(kit.Format("%v->%v %v %v", source, target, m.Detailv(), m.FormatSize())) @@ -216,6 +216,7 @@ func init() { }, mdb.HashAction(mdb.SHORT, mdb.NAME, mdb.FIELD, "time,type,name,text,module,version", ctx.ACTION, OPEN, REDIAL, kit.Dict("a", 3000, "b", 1000, "c", 1000)), mdb.ClearOnExitHashAction()), Hand: func(m *ice.Message, arg ...string) { if len(arg) < 2 { defer m.StatusTimeCount() + m.Option(ice.MSG_USERWEB, tcp.PublishLocalhost(m, m.Option(ice.MSG_USERWEB))) mdb.HashSelect(m.Spawn(), arg...).Sort("").Table(func(index int, value ice.Maps, field []string) { if kit.IsIn(value[mdb.TYPE], CHROME, "send") { return @@ -224,7 +225,7 @@ func init() { m.Push(mdb.STATUS, value[mdb.STATUS]) } if kit.IsIn(value[mdb.TYPE], SERVER, WORKER) { - m.Push(mdb.LINK, tcp.PublishLocalhost(m, m.MergePod(value[mdb.NAME]))) + m.Push(mdb.LINK, m.MergePod(value[mdb.NAME])) } else { m.Push(mdb.LINK, "") } diff --git a/conf.go b/conf.go index 7600d5cb..2636c2c5 100644 --- a/conf.go +++ b/conf.go @@ -215,6 +215,7 @@ const ( // MSG MSG_WIDTH = "sess.width" MSG_HEIGHT = "sess.height" MSG_DAEMON = "sess.daemon" + MSG_COUNT = "sess.count" MSG_FILES = "file.system" YAC_STACK = "yac.stack" YAC_MESSAGE = "yac.message" @@ -295,6 +296,7 @@ const ( // Err ErrNotStart = "not start: " ErrNotImplement = "not implement: " + ErrTooDeepCount = "too deep count: " ) const ( // ctx COMMAND = "command" diff --git a/core/chat/action.go b/core/chat/action.go index 0ccbd0e7..045b3811 100644 --- a/core/chat/action.go +++ b/core/chat/action.go @@ -21,10 +21,8 @@ func _action_exec(m *ice.Message, river, storm, index string, arg ...string) { }).Length() == 0, ice.ErrNotRight, index, arg) { return } - m.Cmd(web.COUNT, mdb.CREATE, ACTION, index, kit.Join(arg)) - if !ctx.PodCmd(m, index, arg) { - m.Cmdy(index, arg) - } + m.Cmd(web.COUNT, mdb.CREATE, ACTION, index, kit.Join(arg), kit.Dict(ice.LOG_DISABLE, ice.TRUE)) + kit.If(!ctx.PodCmd(m, index, arg), func() { m.Cmdy(index, arg) }) } func _action_auth(m *ice.Message, share string) *ice.Message { msg := m.Cmd(web.SHARE, share) diff --git a/core/chat/macos/dock.go b/core/chat/macos/dock.go index 233ede10..6850baf3 100644 --- a/core/chat/macos/dock.go +++ b/core/chat/macos/dock.go @@ -17,6 +17,7 @@ func init() { DockAppend(m, "Safari", web.CHAT_IFRAME) DockAppend(m, "Terminal", web.CODE_XTERM) DockAppend(m, "", web.CODE_VIMER) + DockAppend(m, "", web.CODE_GIT_STATUS, mdb.ICON, "usr/icons/git.jpg") } }}, ice.CTX_EXIT: {Hand: func(m *ice.Message, arg ...string) { mdb.HashExport(m) }}, diff --git a/core/code/autogen.go b/core/code/autogen.go index 71a85823..df90d872 100644 --- a/core/code/autogen.go +++ b/core/code/autogen.go @@ -57,9 +57,9 @@ func _autogen_import(m *ice.Message, main string, ctx string, mod string) { } func _autogen_version(m *ice.Message) string { if mod := _autogen_mod(m, ice.GO_MOD); !nfs.Exists(m, ".git") { - m.Cmd(REPOS, "init", nfs.ORIGIN, strings.Split(kit.MergeURL2(kit.Select(m.Option(ice.MSG_USERWEB), ice.Info.Make.Remote, ice.Info.Make.Domain), "/x/"+path.Base(mod)), mdb.QS)[0], mdb.NAME, path.Base(mod), nfs.PATH, nfs.PWD) + m.Cmd(REPOS, "init", nfs.ORIGIN, strings.Split(kit.MergeURL2(kit.Select(m.Option(ice.MSG_USERWEB), ice.Info.Make.Remote), "/x/"+path.Base(mod)), mdb.QS)[0], mdb.NAME, path.Base(mod), nfs.PATH, nfs.PWD) defer m.Cmd(REPOS, "add", kit.Dict(nfs.REPOS, path.Base(mod), nfs.FILE, nfs.SRC)) - defer m.Cmd(REPOS, "add", kit.Dict(nfs.REPOS, path.Base(mod), nfs.FILE, "go.mod")) + defer m.Cmd(REPOS, "add", kit.Dict(nfs.REPOS, path.Base(mod), nfs.FILE, ice.GO_MOD)) } m.Cmd(nfs.DEFS, ".gitignore", nfs.Template(m, "gitignore")) m.Cmd(nfs.DEFS, ice.SRC_BINPACK_GO, nfs.Template(m, ice.SRC_BINPACK_GO)) @@ -88,7 +88,7 @@ func _autogen_git(m *ice.Message, arg ...string) ice.Map { ) } func _autogen_mod(m *ice.Message, file string) (mod string) { - host := kit.ParseURL(kit.Select(m.Option(ice.MSG_USERHOST), ice.Info.Make.Domain)).Hostname() + host := kit.ParseURL(kit.Select(m.Option(ice.MSG_USERHOST), ice.Info.Make.Remote, m.Cmdx("web.code.git.repos", "remoteURL"))).Hostname() if host == "" { host = path.Base(kit.Path("")) } else { diff --git a/core/code/compile.go b/core/code/compile.go index 5f2c0707..584faf64 100644 --- a/core/code/compile.go +++ b/core/code/compile.go @@ -92,7 +92,7 @@ func init() { m.Logs(nfs.SAVE, nfs.TARGET, file, nfs.SOURCE, main) m.Cmdy(nfs.DIR, file, "time,path,size,hash,link") if !m.IsCliUA() { - kit.If(strings.Contains(file, ice.ICE), func() { m.Cmdy(PUBLISH, ice.CONTEXTS, "app") }) + kit.If(strings.Contains(file, ice.ICE), func() { m.Cmdy(PUBLISH, ice.CONTEXTS, ice.APP) }) } }}, }) diff --git a/core/code/install.go b/core/code/install.go index 0677391a..e106e2f6 100644 --- a/core/code/install.go +++ b/core/code/install.go @@ -36,7 +36,7 @@ func _install_download(m *ice.Message) { return } mdb.HashCreate(m.Cmd(nfs.SAVE, file, ""), mdb.NAME, name, nfs.PATH, file, web.LINK, link) - web.GoToast(m, name, func(toast func(string, int, int)) { + web.GoToast(m, name, func(toast func(string, int, int)) (list []string) { defer nfs.TarExport(m, file) begin := time.Now() web.SpideSave(m, file, link, func(count, total, value int) { @@ -44,6 +44,7 @@ func _install_download(m *ice.Message) { mdb.HashSelectUpdate(m, name, func(value ice.Map) { value[mdb.COUNT], value[mdb.TOTAL], value[mdb.VALUE] = count, total, value }) toast(kit.FormatShow(nfs.FROM, begin.Format("15:04:05"), cli.COST, kit.FmtDuration(cost), cli.REST, kit.FmtDuration(cost*time.Duration(101)/time.Duration(value+1)-cost)), count, total) }) + return }) if s, e := nfs.StatFile(m, file); e == nil && s.Size() > 0 { m.Cmdy(nfs.DIR, file) diff --git a/core/wiki/spark.go b/core/wiki/spark.go index e7f3193d..e86c6028 100644 --- a/core/wiki/spark.go +++ b/core/wiki/spark.go @@ -69,7 +69,7 @@ func init() { SPARK: {Name: "spark type=inner,shell,redis,mysql text", Help: "段落", Actions: ice.MergeActions(ice.Actions{ ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { ice.AddRender(ice.RENDER_SCRIPT, func(msg *ice.Message, args ...ice.Any) string { - m.Option("_cmd_count", 0) + m.Option(ice.MSG_COUNT, "0") return m.Cmdx(SPARK, SHELL, args) }) }}, diff --git a/exec.go b/exec.go index e0206def..69c1443d 100644 --- a/exec.go +++ b/exec.go @@ -143,7 +143,9 @@ func (m *Message) _command(arg ...Any) *Message { } } } - m.Assert(kit.Int(m.Option("_cmd_count", kit.Int(m.Option("_cmd_count"))+1)) < 300) + if count := kit.Int(m.Option(MSG_COUNT, kit.Format(kit.Int(m.Option(MSG_COUNT))+1))); m.Warn(count > 300, ErrTooDeepCount) { + panic(count) + } list := kit.Simple(args...) kit.If(len(list) == 0, func() { list = m.meta[MSG_DETAIL] }) if len(list) == 0 { diff --git a/info.go b/info.go index 8a715315..45d49e8c 100644 --- a/info.go +++ b/info.go @@ -47,6 +47,8 @@ func (s MakeInfo) Versions() string { var Info = struct { Make MakeInfo + Hash string + Size string Username string Hostname string diff --git a/misc/git/repos.go b/misc/git/repos.go index a06bcc2d..7b383387 100644 --- a/misc/git/repos.go +++ b/misc/git/repos.go @@ -83,14 +83,18 @@ func _repos_insert(m *ice.Message, p string) { args = append(args, VERSION, refer.Name().Short()) } } - if remote, err := repos.Remote(ORIGIN); err == nil { - args = append(args, ORIGIN, remote.Config().URLs[0]) - } else if remote, err := repos.Remotes(); err == nil && len(remote) > 0 { - args = append(args, ORIGIN, remote[0].Config().URLs[0]) - } + args = append(args, ORIGIN, _repos_origin(m, repos)) mdb.HashCreate(m.Options(mdb.TARGET, repos), args) } } +func _repos_origin(m *ice.Message, repos *git.Repository) string { + if remote, err := repos.Remote(ORIGIN); err == nil { + return remote.Config().URLs[0] + } else if remote, err := repos.Remotes(); err == nil && len(remote) > 0 { + return remote[0].Config().URLs[0] + } + return "" +} func _repos_path(m *ice.Message, p string, arg ...string) string { if p == path.Base(kit.Path("")) { return kit.Path("", arg...) @@ -111,8 +115,8 @@ func _repos_each(m *ice.Message, title string, cb func(*git.Repository, ice.Maps if msg.Length() == 0 { return } - web.GoToast(m, kit.Select(m.CommandKey()+lex.SP+m.ActionKey(), title), func(toast func(string, int, int)) { - list, count, total := []string{}, 0, msg.Length() + web.GoToast(m, kit.Select(m.CommandKey()+lex.SP+m.ActionKey(), title), func(toast func(string, int, int)) (list []string) { + count, total := 0, msg.Length() msg.Table(func(value ice.Maps) { toast(value[REPOS], count, total) if err := cb(_repos_open(m, value[REPOS]), value); err != nil && err != git.NoErrAlreadyUpToDate { @@ -122,11 +126,7 @@ func _repos_each(m *ice.Message, title string, cb func(*git.Repository, ice.Maps } count++ }) - if len(list) > 0 { - web.Toast(m, strings.Join(list, lex.NL), ice.FAILURE, "30s") - } else { - toast(ice.SUCCESS, count, total) - } + return }) } @@ -476,6 +476,7 @@ func init() { m.Cmd(nfs.DEFS, kit.Path(".git/config"), nfs.Template(m, "config", m.Option(ORIGIN))) git.PlainInit(m.Option(nfs.PATH), false) _repos_insert(m, kit.Path("")) + m.ProcessRefresh() }}, PULL: {Help: "下载", Hand: func(m *ice.Message, arg ...string) { _repos_each_origin(m, "", func(repos *git.Repository, remoteURL string, auth *http.BasicAuth, value ice.Maps) error { @@ -546,6 +547,9 @@ func init() { return _repos_status(m, value[REPOS], repos) }) remote := ice.Info.Make.Remote + if repos, ok := mdb.HashSelectTarget(m, path.Base(kit.Path("")), nil).(*git.Repository); ok { + remote = kit.Select(remote, _repos_origin(m, repos)) + } if insteadof := mdb.Config(m, INSTEADOF); insteadof != "" { remote = insteadof + path.Base(remote) } @@ -591,7 +595,10 @@ func init() { } }}, "remoteURL": {Hand: func(m *ice.Message, arg ...string) { - remoteURL := _git_remote(m) + remoteURL := "" + if repos, ok := mdb.HashSelectTarget(m, path.Base(kit.Path("")), nil).(*git.Repository); ok { + remoteURL = kit.Select(remoteURL, _repos_origin(m, repos)) + } if insteadof := mdb.Config(m, INSTEADOF); insteadof != "" { remoteURL = insteadof + path.Base(remoteURL) } @@ -638,6 +645,9 @@ func init() { m.Cmd("", CLONE, ORIGIN, p, nfs.PATH, m.Option(cli.CMD_DIR), ice.Maps{cli.CMD_DIR: ""}) }) }}, + web.DREAM_TRASH: {Hand: func(m *ice.Message, arg ...string) { + m.Cmd("", mdb.REMOVE, kit.Dict(REPOS, m.Option(mdb.NAME))) + }}, web.DREAM_TABLES: {Hand: func(m *ice.Message, arg ...string) { if !kit.IsIn(m.Option(mdb.TYPE), web.WORKER, web.SERVER) { return @@ -648,7 +658,7 @@ func init() { }}, web.DREAM_ACTION: {Hand: func(m *ice.Message, arg ...string) { web.DreamProcess(m, []string{}, arg...) }}, code.INNER: {Hand: func(m *ice.Message, arg ...string) { _repos_inner(m, _repos_path, arg...) }}, - }, aaa.RoleAction(REMOTE), gdb.EventsAction(web.DREAM_CREATE), mdb.ClearOnExitHashAction(), mdb.HashAction(mdb.SHORT, REPOS, mdb.FIELD, "time,repos,branch,version,comment,origin")), Hand: func(m *ice.Message, arg ...string) { + }, aaa.RoleAction(REMOTE), gdb.EventsAction(web.DREAM_CREATE, web.DREAM_TRASH), mdb.ClearOnExitHashAction(), mdb.HashAction(mdb.SHORT, REPOS, mdb.FIELD, "time,repos,branch,version,comment,origin")), Hand: func(m *ice.Message, arg ...string) { if len(arg) == 0 { mdb.HashSelect(m, arg...).Sort(REPOS).PushAction(STATUS, mdb.REMOVE).Action(CLONE, PULL, PUSH, STATUS) } else if len(arg) == 1 { diff --git a/misc/git/status.go b/misc/git/status.go index c291f194..d9af33a4 100644 --- a/misc/git/status.go +++ b/misc/git/status.go @@ -105,6 +105,13 @@ func init() { STATUS: {Name: "status repos:text auto", Help: "代码库", Actions: ice.MergeActions(ice.Actions{ mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) { switch m.Option(ctx.ACTION) { + case INIT: + switch arg[0] { + case ORIGIN: + m.Cmd("web.spide", func(value ice.Maps) { + m.Push(arg[0], kit.ParseURLMap(value[web.CLIENT_URL])[ORIGIN]+"/x/"+path.Base(kit.Path(""))) + }) + } case INSTEADOF: switch arg[0] { case nfs.FROM: @@ -112,7 +119,7 @@ func init() { case nfs.TO: m.Cmd(web.BROAD, func(value ice.Maps) { m.Push(arg[0], kit.Format("http://%s:%s/", value[tcp.HOST], value[tcp.PORT])) }) case REMOTE: - m.Cmd("web.spide", func(value ice.Maps) { m.Push(arg[0], kit.ParseURLMap(value["client.url"])["origin"]+"/x/") }) + m.Cmd("web.spide", func(value ice.Maps) { m.Push(arg[0], kit.ParseURLMap(value[web.CLIENT_URL])[ORIGIN]+"/x/") }) } return } @@ -125,6 +132,9 @@ func init() { m.Cmdy(REPOS, mdb.INPUTS, arg) } }}, + INIT: {Name: "init origin", Help: "初始化", Hand: func(m *ice.Message, arg ...string) { + m.Cmdy(REPOS, INIT) + }}, CONFIGS: {Name: "configs email* username* token", Help: "配置", Hand: func(m *ice.Message, arg ...string) { m.Cmd(nfs.DEFS, kit.HomePath(".gitconfig"), nfs.Template(m, "gitconfig", m.Option(aaa.USERNAME), m.Option(aaa.EMAIL))) mdb.Config(m, aaa.USERNAME, m.Option(aaa.USERNAME)) @@ -161,6 +171,8 @@ func init() { m.Cmdy(REPOS, arg) } else if config, err := config.LoadConfig(config.GlobalScope); err == nil && config.User.Email == "" && mdb.Config(m, aaa.EMAIL) == "" { m.Action(CONFIGS).Echo("please config email and name. ").EchoButton(CONFIGS) + } else if !nfs.Exists(m, ".git") { + m.Action("init").Echo("please init repos. ").EchoButton("init") } else if len(arg) == 0 { kit.If(config != nil, func() { m.Option(aaa.EMAIL, kit.Select(mdb.Config(m, aaa.EMAIL), config.User.Email)) }) m.Cmdy(REPOS, STATUS).Action(PULL, PUSH, INSTEADOF, "oauth", CONFIGS)