diff --git a/base/cli/system.go b/base/cli/system.go index 950f12a5..f27bbd20 100644 --- a/base/cli/system.go +++ b/base/cli/system.go @@ -4,6 +4,7 @@ import ( "bytes" "io" "net/http" + "os" "os/exec" "path" "strings" @@ -137,6 +138,7 @@ const ( CMD_ERR = "cmd_err" CMD_OUT = "cmd_out" + SH = "sh" MAN = "man" RUN = "run" KILL = "kill" @@ -191,6 +193,9 @@ func IsSuccess(m *ice.Message) bool { return m.Append(CODE) == "" || m.Append(CO var _cache_path []string +func Shell(m *ice.Message) string { + return kit.Select("/bin/sh", os.Getenv("SHELL")) +} func EtcPath(m *ice.Message) (res []string) { if len(_cache_path) > 0 { return _cache_path diff --git a/base/tcp/host.go b/base/tcp/host.go index 9b18a5f3..70710b7c 100644 --- a/base/tcp/host.go +++ b/base/tcp/host.go @@ -15,9 +15,9 @@ import ( func _host_domain(m *ice.Message) string { return kit.GetValid( - func() string { return m.Option("tcp_domain") }, + func() string { return m.Option(ice.TCP_DOMAIN) }, func() string { return mdb.Config(m, DOMAIN) }, - func() string { return os.Getenv("tcp_domain") }, + func() string { return os.Getenv(ice.TCP_DOMAIN) }, func() string { if !kit.IsIn(m.ActionKey(), "", ice.LIST) { return m.Cmdv(HOST, mdb.Config(m, ice.MAIN), aaa.IP) diff --git a/base/web/dream.go b/base/web/dream.go index fdb71050..17017b5d 100644 --- a/base/web/dream.go +++ b/base/web/dream.go @@ -56,11 +56,9 @@ func _dream_start(m *ice.Message, name string) { defer m.ProcessOpen(kit.MergeURL(S(name), m.OptionSimple(ice.MSG_DEBUG))) p := path.Join(ice.USR_LOCAL_WORK, name) if p := path.Join(p, ice.Info.PidPath); nfs.Exists(m, p) { - if nfs.Exists(m, "/proc/") { - if pid := m.Cmdx(nfs.CAT, p, kit.Dict(ice.MSG_USERROLE, aaa.TECH)); pid != "" && nfs.Exists(m, "/proc/"+pid) { - m.Info("already exists %v", pid) - return - } + if pid := m.Cmdx(nfs.CAT, p, kit.Dict(ice.MSG_USERROLE, aaa.TECH)); pid != "" && nfs.Exists(m, "/proc/"+pid) { + m.Info("already exists %v", pid) + return } for i := 0; i < 10; i++ { if m.Cmd(SPACE, name).Length() > 0 { @@ -71,7 +69,7 @@ func _dream_start(m *ice.Message, name string) { } } defer m.Options(cli.CMD_DIR, "", cli.CMD_ENV, "", cli.CMD_OUTPUT, "") - m.Options(cli.CMD_DIR, kit.Path(p), cli.CMD_ENV, kit.EnvList(kit.Simple(m.OptionSimple("tcp_domain"), + m.Options(cli.CMD_DIR, kit.Path(p), cli.CMD_ENV, kit.EnvList(kit.Simple(m.OptionSimple(ice.TCP_DOMAIN), cli.CTX_OPS, Domain(tcp.LOCALHOST, m.Cmdv(SERVE, tcp.PORT)), cli.CTX_LOG, ice.VAR_LOG_BOOT_LOG, cli.CTX_PID, ice.VAR_LOG_ICE_PID, cli.CTX_ROOT, kit.Path(""), cli.PATH, cli.BinPath(p, ""), cli.USER, ice.Info.Username, )...), cli.CMD_OUTPUT, path.Join(p, ice.VAR_LOG_BOOT_LOG), mdb.CACHE_CLEAR_ONEXIT, ice.TRUE) @@ -232,15 +230,17 @@ func init() { }) }}, cli.BUILD: {Hand: func(m *ice.Message, arg ...string) { - m.Cmd("", FOR_FLOW, kit.JoinWord("sh", ice.ETC_MISS_SH)) + m.Cmd("", FOR_FLOW, kit.JoinWord(cli.SH, ice.ETC_MISS_SH)) m.Sleep3s().Cmdy(ROUTE, cli.BUILD).ProcessInner() }}, PUBLISH: {Name: "publish name", Help: "发布", Icon: "bi bi-send-check", Hand: func(m *ice.Message, arg ...string) { DreamEach(m, m.Option(mdb.NAME), "", func(name string) { - m.Push(mdb.NAME, name).Push(mdb.TEXT, m.Cmdx(SPACE, name, "compile", cli.LINUX)) - m.Push(mdb.NAME, name).Push(mdb.TEXT, m.Cmdx(SPACE, name, "compile", cli.DARWIN)) - m.Push(mdb.NAME, name).Push(mdb.TEXT, m.Cmdx(SPACE, name, "compile", cli.WINDOWS)) + PushNoticeRich(m, mdb.NAME, name, mdb.TEXT, m.Cmdx(SPACE, name, CODE_AUTOGEN, "binpack")) + PushNoticeRich(m, mdb.NAME, name, mdb.TEXT, m.Cmdx(SPACE, name, CODE_COMPILE, cli.LINUX)) + PushNoticeRich(m, mdb.NAME, name, mdb.TEXT, m.Cmdx(SPACE, name, CODE_COMPILE, cli.DARWIN)) + PushNoticeRich(m, mdb.NAME, name, mdb.TEXT, m.Cmdx(SPACE, name, CODE_COMPILE, cli.WINDOWS)) }) + m.ProcessHold() }}, FOR_FLOW: {Name: "forFlow cmd*='sh etc/miss.sh'", Help: "流程", Icon: "bi bi-terminal", Hand: func(m *ice.Message, arg ...string) { m.Options(ctx.DISPLAY, PLUGIN_XTERM, cli.CMD_OUTPUT, nfs.NewWriteCloser(func(buf []byte) (int, error) { @@ -254,6 +254,7 @@ func init() { p := path.Join(ice.USR_LOCAL_WORK, value[mdb.NAME]) PushNoticeGrow(m, strings.ReplaceAll(kit.Format("[%s]%s$ %s\n", time.Now().Format(ice.MOD_TIME_ONLY), value[mdb.NAME], m.Option(ice.CMD)), lex.NL, "\r\n")) m.Cmd(cli.SYSTEM, kit.Split(m.Option(ice.CMD)), kit.Dict(cli.CMD_DIR, p)).Sleep300ms() + PushNoticeGrow(m, "\r\n\r\n\r\n") }) return nil }) diff --git a/base/web/html/html.go b/base/web/html/html.go index b5ab23e7..66da85fa 100644 --- a/base/web/html/html.go +++ b/base/web/html/html.go @@ -7,18 +7,19 @@ import ( ) const ( - Mozilla = "Mozilla" - UserAgent = "User-Agent" - Referer = "Referer" - Authorization = "Authorization" - Bearer = "Bearer" - Basic = "Basic" - Accept = "Accept" - AcceptLanguage = "Accept-Language" - ContentLength = "Content-Length" - ContentType = "Content-Type" - XForwardedFor = "X-Forwarded-For" - XHost = "X-Host" + Mozilla = "Mozilla" + UserAgent = "User-Agent" + Referer = "Referer" + Authorization = "Authorization" + Bearer = "Bearer" + Basic = "Basic" + Accept = "Accept" + AcceptLanguage = "Accept-Language" + ContentEncoding = "Content-Encoding" + ContentLength = "Content-Length" + ContentType = "Content-Type" + XForwardedFor = "X-Forwarded-For" + XHost = "X-Host" ApplicationForm = "application/x-www-form-urlencoded" ApplicationOctet = "application/octet-stream" diff --git a/base/web/option.go b/base/web/option.go index 55225393..ee163da2 100644 --- a/base/web/option.go +++ b/base/web/option.go @@ -118,6 +118,7 @@ func PushNotice(m *ice.Message, arg ...ice.Any) { } func PushNoticeToast(m *ice.Message, arg ...ice.Any) { PushNotice(m, kit.List("toast", arg)...) } func PushNoticeGrow(m *ice.Message, arg ...ice.Any) { PushNotice(m, kit.List("grow", arg)...) } +func PushNoticeRich(m *ice.Message, arg ...ice.Any) { PushNotice(m, kit.List("rich", arg)...) } func PushStream(m *ice.Message) *ice.Message { m.Options(cli.CMD_OUTPUT, file.NewWriteCloser(func(buf []byte) { PushNoticeGrow(m, string(buf)) }, nil)).ProcessHold(toastContent(m, ice.SUCCESS)) return m diff --git a/base/web/render.go b/base/web/render.go index d2242d2d..b61949c9 100644 --- a/base/web/render.go +++ b/base/web/render.go @@ -169,6 +169,7 @@ const ( CODE_GIT_SEARCH = "web.code.git.search" CODE_GIT_STATUS = "web.code.git.status" CODE_GIT_REPOS = "web.code.git.repos" + CODE_AUTOGEN = "web.code.autogen" CODE_COMPILE = "web.code.compile" CODE_UPGRADE = "web.code.upgrade" CODE_PUBLISH = "web.code.publish" @@ -179,10 +180,10 @@ const ( WIKI_DRAW = "web.wiki.draw" WIKI_WORD = "web.wiki.word" WIKI_PORTAL = "web.wiki.portal" - CHAT_OAUTH_CLIENT = "web.chat.oauth.client" CHAT_PORTAL = "web.chat.portal" CHAT_HEADER = "web.chat.header" CHAT_IFRAME = "web.chat.iframe" + CHAT_OAUTH_CLIENT = "web.chat.oauth.client" CHAT_FAVOR = "web.chat.favor" CHAT_FLOWS = "web.chat.flows" CHAT_GRANT = "web.chat.grant" diff --git a/base/web/share.go b/base/web/share.go index 4de036f8..3fff3221 100644 --- a/base/web/share.go +++ b/base/web/share.go @@ -76,7 +76,7 @@ func init() { // kit.If(m.Option(mdb.TYPE) == LOGIN, func() { arg = append(arg, mdb.TEXT, tcp.PublishLocalhost(m, m.Option(mdb.TEXT))) }) kit.If(m.Option(mdb.TYPE) == LOGIN && m.Option(mdb.TEXT) == "", func() { arg = append(arg, mdb.TEXT, tcp.PublishLocalhost(m, m.Option(ice.MSG_USERWEB))) }) mdb.HashCreate(m, arg, SPACE, m.Option(ice.MSG_USERPOD), aaa.USERNICK, m.Option(ice.MSG_USERNICK), aaa.USERNAME, m.Option(ice.MSG_USERNAME), aaa.USERROLE, m.Option(ice.MSG_USERROLE)) - m.Option(mdb.LINK, _share_link(m, P(SHARE, m.Result()))) + m.Option(mdb.LINK, _share_link(m, kit.MergeURL(P(SHARE, m.Result()), m.OptionSimple(ice.MSG_DEBUG)))) }}, LOGIN: {Help: "登录", Hand: func(m *ice.Message, arg ...string) { m.EchoQRCode(m.Cmd(SHARE, mdb.CREATE, mdb.TYPE, LOGIN).Option(mdb.LINK)).ProcessInner() diff --git a/base/web/token.go b/base/web/token.go index 717bd770..e17c3920 100644 --- a/base/web/token.go +++ b/base/web/token.go @@ -26,7 +26,7 @@ func init() { Index.MergeCommands(ice.Commands{ TOKEN: {Help: "令牌", Actions: ice.MergeActions(ice.Actions{ GEN: {Hand: func(m *ice.Message, arg ...string) { - m.Echo("请授权 %s %s 代码权限\n", m.Option(tcp.HOST), m.Option(mdb.TYPE)).EchoButton(CONFIRM) + m.EchoInfoButton(kit.Format("请授权 %s\n访问 %s\n", m.Option(tcp.HOST), m.Option(mdb.TYPE)), CONFIRM) }}, CONFIRM: {Hand: func(m *ice.Message, arg ...string) { if m.Warn(m.R.Method != http.MethodPost, ice.ErrNotAllow) { @@ -46,8 +46,7 @@ func init() { m.ProcessClose() }}, }, StatsAction("", "令牌总数"), mdb.HashAction(mdb.SHORT, mdb.UNIQ, mdb.FIELD, "time,hash,type,name,text", mdb.EXPIRE, mdb.MONTH)), Hand: func(m *ice.Message, arg ...string) { - mdb.HashSelect(m, arg...) - if len(arg) > 0 { + if mdb.HashSelect(m, arg...); len(arg) > 0 { m.EchoScript(kit.Format("ish_miss_serve_log dev %s token %s", UserHost(m), arg[0])) } }}, diff --git a/conf.go b/conf.go index c87169ed..a876bcc6 100644 --- a/conf.go +++ b/conf.go @@ -247,6 +247,7 @@ const ( // MSG TOAST_DURATION = "toast.duration" TABLE_CHECKBOX = "table.checkbox" + TCP_DOMAIN = "tcp_domain" ) const ( // RENDER RENDER_BUTTON = "_button" diff --git a/core/chat/macos/desktop.go b/core/chat/macos/desktop.go index ad69bf06..882793a2 100644 --- a/core/chat/macos/desktop.go +++ b/core/chat/macos/desktop.go @@ -44,10 +44,8 @@ func init() { Notify(m, "Infomation.png", cli.RUNTIME, "系统启动成功", ctx.INDEX, cli.RUNTIME) }}, DESKTOP: {Help: "应用桌面", Actions: ice.MergeActions(ice.Actions{ - web.DREAM_TABLES: {Hand: func(m *ice.Message, arg ...string) { - kit.Switch(m.Option(mdb.TYPE), kit.Simple(web.WORKER, web.SERVER), func() { m.PushButton(kit.Dict(m.CommandKey(), "桌面")) }) - }}, - web.DREAM_ACTION: {Hand: func(m *ice.Message, arg ...string) { web.DreamProcess(m, []string{}, arg...) }}, + web.DREAM_TABLES: {Hand: func(m *ice.Message, arg ...string) { m.PushButton(kit.Dict(m.CommandKey(), "桌面")) }}, + web.DREAM_ACTION: {Hand: func(m *ice.Message, arg ...string) { web.DreamProcess(m, nil, arg...) }}, }, aaa.RoleAction(), PodCmdAction(), CmdHashAction(), mdb.ExportHashAction())}, }) } diff --git a/core/code/autogen.go b/core/code/autogen.go index 802f3b36..82e2d6b7 100644 --- a/core/code/autogen.go +++ b/core/code/autogen.go @@ -148,7 +148,7 @@ func init() { USR_RELEASE_CONF_GO = "usr/release/conf.go" USR_RELEASE_BINPACK_GO = "usr/release/binpack.go" ) - if m.Cmd(BINPACK, mdb.CREATE); nfs.Exists(m, ice.USR_RELEASE) && m.Option(ice.MSG_USERPOD) == "" { + if m.Cmd(BINPACK, mdb.CREATE); ice.Info.NodeType == web.SERVER && nfs.Exists(m, ice.USR_RELEASE) { nfs.CopyFile(m, USR_RELEASE_BINPACK_GO, ice.SRC_BINPACK_GO, func(buf []byte, offset int) []byte { kit.If(offset == 0, func() { buf = bytes.Replace(buf, []byte("package main"), []byte("package ice"), 1) }) return buf diff --git a/core/code/publish.go b/core/code/publish.go index 6f88994e..f5348c2a 100644 --- a/core/code/publish.go +++ b/core/code/publish.go @@ -47,7 +47,7 @@ func _publish_contexts(m *ice.Message, arg ...string) { m.Options(nfs.DIR_ROOT, "").OptionDefault(ice.MSG_USERNAME, "demo") for _, k := range kit.Default(arg, ice.MISC) { m.Options(web.DOMAIN, web.UserHost(m), cli.CTX_ENV, kit.Select("", lex.SP+kit.JoinKV(mdb.EQ, lex.SP, cli.CTX_POD, m.Option(ice.MSG_USERPOD)), m.Option(ice.MSG_USERPOD) != "")) - m.Option("tcp_domain", kit.ParseURL(web.UserHost(m)).Hostname()) + m.Option(ice.TCP_DOMAIN, kit.ParseURL(web.UserHost(m)).Hostname()) switch k { case INSTALL: m.Option("format", "raw") diff --git a/core/code/vimer.go b/core/code/vimer.go index 638df356..9496dc05 100644 --- a/core/code/vimer.go +++ b/core/code/vimer.go @@ -183,7 +183,7 @@ func init() { } if msg := m.Cmd(cmds); cli.IsSuccess(msg) { if m.GoSleep30ms(func() { m.Cmd(UPGRADE, cli.RESTART) }); isWebview() { - m.Cmd(cli.DAEMON, "./bin/ice.bin", cli.FOREVER, cli.DELAY, "300ms", cli.SYSTEM, cli.OPEN, app) + m.Cmd(cli.DAEMON, ice.BIN_ICE_BIN, cli.FOREVER, cli.DELAY, "300ms", cli.SYSTEM, cli.OPEN, app) } } else { _vimer_make(m, nfs.PWD, msg) @@ -209,10 +209,8 @@ func init() { chat.FAVOR_ACTION: {Hand: func(m *ice.Message, arg ...string) { kit.If(m.Option(mdb.TYPE) == nfs.FILE, func() { ctx.ProcessField(m, m.PrefixKey(), nfs.SplitPath(m, m.Option(mdb.TEXT))) }) }}, - web.DREAM_TABLES: {Hand: func(m *ice.Message, arg ...string) { - kit.Switch(m.Option(mdb.TYPE), kit.Simple(web.WORKER, web.SERVER), func() { m.PushButton(kit.Dict(m.CommandKey(), "编程")) }) - }}, - web.DREAM_ACTION: {Hand: func(m *ice.Message, arg ...string) { web.DreamProcess(m, []string{}, arg...) }}, + web.DREAM_TABLES: {Hand: func(m *ice.Message, arg ...string) { m.PushButton(kit.Dict(m.CommandKey(), "编程")) }}, + web.DREAM_ACTION: {Hand: func(m *ice.Message, arg ...string) { web.DreamProcess(m, nil, arg...) }}, }, aaa.RoleAction(), chat.FavorAction(), ctx.ConfAction(ctx.TOOLS, "xterm,compile,runtime")), Hand: func(m *ice.Message, arg ...string) { if m.Cmdy(INNER, arg); arg[0] != ctx.ACTION { if web.IsLocalHost(m) { diff --git a/core/code/xterm.go b/core/code/xterm.go index ec321e37..25fe190e 100644 --- a/core/code/xterm.go +++ b/core/code/xterm.go @@ -153,12 +153,8 @@ func init() { ctx.ProcessField(m, m.PrefixKey(), m.Cmdx("", mdb.CREATE, mdb.TYPE, m.Option(mdb.TEXT), mdb.NAME, m.Option(mdb.NAME), mdb.TEXT, "")) }) }}, - web.DREAM_TABLES: {Hand: func(m *ice.Message, arg ...string) { - kit.Switch(m.Option(mdb.TYPE), kit.Simple(web.WORKER, web.SERVER), func() { m.PushButton(kit.Dict(m.CommandKey(), "终端")) }) - }}, - web.DREAM_ACTION: {Hand: func(m *ice.Message, arg ...string) { - web.DreamProcess(m, []string{}, arg...) - }}, + web.DREAM_TABLES: {Hand: func(m *ice.Message, arg ...string) { m.PushButton(kit.Dict(m.CommandKey(), "终端")) }}, + web.DREAM_ACTION: {Hand: func(m *ice.Message, arg ...string) { web.DreamProcess(m, cli.Shell(m), arg...) }}, }, chat.FavorAction(), ctx.ProcessAction(), mdb.HashAction(mdb.FIELD, "time,hash,type,name,text,path")), Hand: func(m *ice.Message, arg ...string) { if mdb.HashSelect(m, arg...); len(arg) == 0 { if web.IsLocalHost(m) { diff --git a/core/wiki/portal.go b/core/wiki/portal.go index b86272f7..e12cfaaa 100644 --- a/core/wiki/portal.go +++ b/core/wiki/portal.go @@ -8,7 +8,6 @@ import ( "shylinux.com/x/icebergs/base/aaa" "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/lex" - "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" "shylinux.com/x/icebergs/base/web" kit "shylinux.com/x/toolkits" @@ -81,9 +80,7 @@ func init() { m.Copy(m.Spawn([]byte(m.Cmdx(nfs.CAT, p)))) } }}, - web.DREAM_TABLES: {Hand: func(m *ice.Message, arg ...string) { - kit.Switch(m.Option(mdb.TYPE), kit.Simple(web.WORKER, web.SERVER), func() { m.PushButton(kit.Dict(PORTAL, "官网")) }) - }}, + web.DREAM_TABLES: {Hand: func(m *ice.Message, arg ...string) { m.PushButton(kit.Dict(PORTAL, "官网")) }}, web.DREAM_ACTION: {Hand: func(m *ice.Message, arg ...string) { web.DreamProcess(m, nil, arg...) }}, }, aaa.WhiteAction(), aaa.RoleAction()), Hand: func(m *ice.Message, arg ...string) { if m.Push(HEADER, m.Cmdx(WORD, path.Join(nfs.SRC_DOCUMENT, INDEX_SHY))); len(arg) > 0 { diff --git a/core/wiki/portal.js b/core/wiki/portal.js index 5c739b0e..b71c91ff 100644 --- a/core/wiki/portal.js +++ b/core/wiki/portal.js @@ -1,8 +1,8 @@ Volcanos(chat.ONIMPORT, { - _init: function(can, msg) { var p = "/cmd/web.wiki.portal" - can.isCmdMode() && (can.user.toast = function() {}) - can.db.prefix = location.pathname.indexOf(p) > 0? location.pathname.split(p)[0]+p: "/wiki/portal/" - can.db.current = can.isCmdMode()? can.base.trimPrefix(location.pathname, can.db.prefix+"/", can.db.prefix): can.Option(nfs.PATH) + _init: function(can, msg) { can.isCmdMode() && (can.user.toast = function() {}) + var p = "/cmd/"+web.WIKI_PORTAL; can.db.prefix = location.pathname.indexOf(p) > -1? location.pathname.split(p)[0]+p: nfs.WIKI_PORTAL + var p = "/c/"+web.WIKI_PORTAL; can.db.prefix = location.pathname.indexOf(p) > -1? location.pathname.split(p)[0]+p: nfs.WIKI_PORTAL + can.db.current = can.isCmdMode()? can.base.trimPrefix(location.pathname, can.db.prefix+nfs.PS, can.db.prefix): can.Option(nfs.PATH) can.sup.onexport.link = function() { return can.misc.MergeURL(can, {pod: can.ConfSpace(), cmd: can.ConfIndex()}) } can.require(["/plugin/local/wiki/word.js"]) can.Conf(html.PADDING, can.page.styleValueInt(can, "--portal-main-padding", can._output)) @@ -11,7 +11,7 @@ Volcanos(chat.ONIMPORT, { can.ui.header.innerHTML = msg.Append(html.HEADER), can.ui.nav.innerHTML = msg.Append(html.NAV) if (msg.Append(html.NAV) == "") { can.onmotion.hidden(can, can.ui.nav), can.onmotion.hidden(can, can.ui.aside) - can.base.isIn(can.db.current, "", "/") && can.onappend.style(can, ice.HOME), can.onimport.content(can, "content.shy") + can.base.isIn(can.db.current, "", nfs.PS) && can.onappend.style(can, ice.HOME), can.onimport.content(can, "content.shy") } else { can.page.styleWidth(can, can.ui.nav, 230), can.page.styleWidth(can, can.ui.aside, 200) if (can.ConfWidth() < 1000) { can.onmotion.hidden(can, can.ui.aside) } @@ -45,7 +45,7 @@ Volcanos(chat.ONIMPORT, { target.onclick = function(event) { can.onaction.route(event, can, item.route) } }, content: function(can, file) { - can.runActionCommand(event, web.WIKI_WORD, [(can.base.beginWith(file, "usr/", "src/")? "": nfs.SRC_DOCUMENT+can.db.current)+file], function(msg) { can.ui.main.innerHTML = msg.Result(), can.onmotion.clear(can, can.ui.aside) + can.runActionCommand(event, web.WIKI_WORD, [(can.base.beginWith(file, nfs.USR, nfs.SRC)? "": nfs.SRC_DOCUMENT+can.db.current)+file], function(msg) { can.ui.main.innerHTML = msg.Result(), can.onmotion.clear(can, can.ui.aside) can.onimport._content(can, can.ui.main, function(target, meta) { meta.type == wiki.TITLE && can.onappend.style(can, meta.name, target._menu = can.onimport.item(can, {name: meta.text}, function(event) { target.scrollIntoView() }, function() {}, can.ui.aside)) }), can.onmotion.select(can, can.ui.aside, html.DIV_ITEM, 0) diff --git a/misc/git/client.go b/misc/git/client.go index a694f6cb..0ffe7a00 100644 --- a/misc/git/client.go +++ b/misc/git/client.go @@ -13,9 +13,7 @@ const CLIENT = "client" func init() { Index.MergeCommands(ice.Commands{ CLIENT: {Help: "代码库", Actions: ice.MergeActions(ice.Actions{ - ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { - cli.IsRedhat(m, GIT, "git") - }}, + ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { cli.IsRedhat(m, GIT, GIT) }}, cli.ORDER: {Hand: func(m *ice.Message, arg ...string) { m.Cmd(code.INSTALL, cli.ORDER, mdb.Config(m, nfs.SOURCE), "_install/bin") m.Cmd(code.INSTALL, cli.ORDER, mdb.Config(m, nfs.SOURCE), "_install/libexec/git-core") diff --git a/misc/git/configs.go b/misc/git/configs.go index 18cd5f58..951b3555 100644 --- a/misc/git/configs.go +++ b/misc/git/configs.go @@ -41,7 +41,7 @@ func init() { mdb.HashRemove(m, m.Option(mdb.NAME)) }}, mdb.REMOVE: {Hand: func(m *ice.Message, arg ...string) { - mdb.HashCreate(m.Spawn(), m.OptionSimple(mdb.NAME, mdb.VALUE)) + mdb.HashCreate(m, m.OptionSimple(mdb.NAME, mdb.VALUE)) _configs_set(m, UNSET, m.Option(mdb.NAME)) }}, mdb.MODIFY: {Hand: func(m *ice.Message, arg ...string) { @@ -57,10 +57,10 @@ func init() { ))), Hand: func(m *ice.Message, arg ...string) { if len(arg) == 0 { _configs_list(m).Action(mdb.CREATE, ice.INIT) - return + } else { + kit.If(len(arg) > 1, func() { _configs_set(m, arg[0], arg[1]) }) + m.Echo(_configs_get(m, arg[0])) } - kit.If(len(arg) > 1, func() { _configs_set(m, arg[0], arg[1]) }) - m.Echo(_configs_get(m, arg[0])) }}, }) } diff --git a/misc/git/count.go b/misc/git/count.go deleted file mode 100644 index b0c419be..00000000 --- a/misc/git/count.go +++ /dev/null @@ -1,135 +0,0 @@ -package git - -import ( - "path" - "strings" - - ice "shylinux.com/x/icebergs" - "shylinux.com/x/icebergs/base/cli" - "shylinux.com/x/icebergs/base/lex" - "shylinux.com/x/icebergs/base/mdb" - "shylinux.com/x/icebergs/base/nfs" - "shylinux.com/x/icebergs/core/code" - kit "shylinux.com/x/toolkits" -) - -func _count_count(m *ice.Message, arg []string, cb func(string)) { - if m.Warn(len(arg) == 0 || arg[0] == nfs.USR, ice.ErrNotValid, nfs.DIR, "to many files, please select sub dir") { - return - } - nfs.DirDeepAll(m, "", arg[0], func(value ice.Maps) { - if file := value[nfs.PATH]; kit.Contains(file, nfs.BIN, nfs.VAR, "node_modules/") { - return - } else if kit.IsIn(kit.Ext(file), "tags", "sum", "log") { - return - } else { - cb(file) - } - }, nfs.PATH) -} - -const COUNT = "count" - -func init() { - const ( - FILES = "files" - LINES = "lines" - ) - Index.MergeCommands(ice.Commands{ - COUNT: {Name: "count path@key auto order count package tags", Help: "代码行", Actions: ice.Actions{ - mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(nfs.DIR, path.Dir(kit.Select(nfs.PWD, arg[1]))).CutTo(nfs.PATH, arg[0]) - }}, - cli.ORDER: {Help: "排行", Hand: func(m *ice.Message, arg ...string) { - files := map[string]int{} - _count_count(m, arg, func(file string) { - m.Cmdy(nfs.CAT, file, func(text string) { files[strings.TrimPrefix(file, arg[0])]++ }) - }) - kit.For(files, func(k string, v int) { m.Push(FILES, k).Push(LINES, v) }) - m.SortIntR(LINES) - }}, - COUNT: {Help: "计数", Hand: func(m *ice.Message, arg ...string) { - files, lines := map[string]int{}, map[string]int{} - _count_count(m, arg, func(file string) { - files[mdb.TOTAL]++ - files[kit.Ext(file)]++ - m.Cmdy(nfs.CAT, file, func(text string) { - if kit.Ext(file) == code.GO { - switch { - case strings.HasPrefix(text, "type "): - lines["_type"]++ - case strings.HasPrefix(text, "func "): - lines["_func"]++ - } - } - lines[kit.Ext(file)]++ - lines[mdb.TOTAL]++ - }) - }) - kit.For(lines, func(k string, v int) { m.Push(mdb.TYPE, k).Push(FILES, files[k]).Push(LINES, lines[k]) }) - m.SortIntR(LINES) - }}, - code.PACKAGE: {Help: "依赖", Hand: func(m *ice.Message, arg ...string) { - list := map[string]map[string]int{} - ls := map[string]int{} - pkg, block := "", false - add := func(mod string) { - if _, ok := list[pkg]; !ok { - list[pkg] = map[string]int{} - } - kit.If(mod, func() { list[pkg][mod]++; ls[mod]++ }) - } - _count_count(m, arg, func(file string) { - m.Cmdy(nfs.CAT, file, func(text string) { - if kit.Ext(file) == code.GO { - switch { - case strings.HasPrefix(text, "package "): - pkg = kit.Split(text)[1] - case strings.HasPrefix(text, "import ("): - block = true - case strings.HasPrefix(text, "import "): - add(kit.Select("", kit.Split(text), -1)) - case strings.HasPrefix(text, ")"): - block = false - default: - kit.If(block, func() { add(kit.Select("", kit.Split(text), -1)) }) - } - } - }) - }) - m.Appendv(ice.MSG_APPEND, []string{code.PACKAGE, mdb.COUNT}) - kit.For(ls, func(key string, value int) { - if !strings.Contains(key, "shylinux.com") { - return - } - count := 0 - m.Push(code.PACKAGE, key) - kit.For(kit.SortedKey(list), func(k string) { - if n := list[k][key]; n == 0 { - m.Push(k, "") - } else { - m.Push(k, n) - count++ - } - }) - m.Push(mdb.COUNT, count) - }) - m.SortIntR(mdb.COUNT) - }}, - nfs.TAGS: {Help: "索引", Hand: func(m *ice.Message, arg ...string) { - count := map[string]int{} - m.Cmd(nfs.CAT, path.Join(arg[0], nfs.TAGS), func(line string) { - if ls := strings.SplitN(line, lex.TB, 3); len(ls) < 3 { - return - } else if ls = strings.SplitN(ls[2], ";\"", 2); len(ls) < 2 { - return - } else { - count[kit.Split(ls[1])[0]]++ - } - }) - kit.For(count, func(k string, v int) { m.Push(mdb.TYPE, k).Push(mdb.COUNT, v) }) - m.SortIntR(mdb.COUNT) - }}, - }, Hand: func(m *ice.Message, arg ...string) { m.Cmdy(nfs.DIR, arg) }}, - }) -} diff --git a/misc/git/git.shy b/misc/git/git.shy index 2b0d3540..10f54138 100644 --- a/misc/git/git.shy +++ b/misc/git/git.shy @@ -45,21 +45,7 @@ field "状态机" web.code.git.status field "配置键" web.code.git.configs field "服务器" web.code.git.service field "代码源" web.code.git.search args `repos` -field "架构图" web.code.git.spide args `icebergs` -field "趋势图" web.code.git.trend args `icebergs` -return -field "代码行" web.code.git.count -field "统计量" web.code.git.total - -repos.go -status.go -configs.go -service.go -search.go -search.js -search.css - -spide.go -trend.go -count.go -total.go +field "趋势图" web.code.git.trends args `icebergs` +field "架构图" web.code.git.spides args `icebergs` +field "代码行" web.code.git.counts +field "统计量" web.code.git.totals \ No newline at end of file diff --git a/misc/git/repos.go b/misc/git/repos.go index 04f62dcb..7ff0266c 100644 --- a/misc/git/repos.go +++ b/misc/git/repos.go @@ -29,10 +29,11 @@ import ( func _repos_insert(m *ice.Message, p string) { if repos, err := git.PlainOpen(p); err == nil { args := []string{REPOS, path.Base(p), nfs.PATH, p} + args = append(args, ORIGIN, _repos_origin(m, repos)) if head, err := repos.Head(); err == nil { args = append(args, BRANCH, head.Name().Short()) if commit, err := repos.CommitObject(head.Hash()); err == nil { - args = append(args, mdb.TIME, commit.Author.When.Format(ice.MOD_TIME), MESSAGE, strings.TrimSuffix(commit.Message, lex.NL)) + args = append(args, mdb.TIME, _repos_when(m, commit), MESSAGE, strings.TrimSuffix(commit.Message, lex.NL)) } } if refer := _repos_recent(m, repos); refer != nil { @@ -42,7 +43,6 @@ func _repos_insert(m *ice.Message, p string) { args = append(args, VERSION, refer.Name().Short()) } } - args = append(args, ORIGIN, _repos_origin(m, repos)) mdb.HashCreate(m.Options(mdb.TARGET, repos), args) } } @@ -61,7 +61,11 @@ func _repos_remote(m *ice.Message, remote string) string { if remote == "" { return "" } else if insteadof := mdb.Config(m, INSTEADOF); insteadof != "" { - remote = insteadof + path.Base(remote) + if p := kit.ParseURL(insteadof); kit.IsIn(p.Path, "", nfs.PS) { + remote = kit.MergeURL2(insteadof, kit.ParseURL(remote).Path) + } else { + remote = kit.MergeURL2(insteadof, path.Base(remote)) + } } return remote } @@ -71,9 +75,9 @@ func _repos_recent(m *ice.Message, repos *git.Repository) (r *plumbing.Reference for { if refer, err := iter.Next(); err != nil { break - } else if ls := kit.Split(refer.Name().Short(), "v."); len(ls) < 2 { + } else if ls := kit.Split(refer.Name().Short(), "v."); len(ls) == 0 { continue - } else if n := kit.Int(ls[0])*1000000 + kit.Int(ls[1])*1000 + kit.Int(ls[2]); n > max { + } else if n := kit.Int(ls[0])*1000000 + kit.Int(kit.Select("0", ls, 1))*1000 + kit.Int(kit.Select("0", ls, 2)); n > max { max, r = n, refer } } @@ -98,23 +102,21 @@ func _repos_forword(m *ice.Message, repos *git.Repository, version string) int { } return 0 } +func _repos_when(m *ice.Message, commit *object.Commit) string { + return strings.TrimSuffix(commit.Author.When.Format(ice.MOD_TIME), ".000") +} func _repos_open(m *ice.Message, p string) *git.Repository { return mdb.HashSelectTarget(m, p, nil).(*git.Repository) } func _repos_each(m *ice.Message, title string, cb func(*git.Repository, ice.Maps) error) { msg := m.Cmd("") - if msg.Length() == 0 { - return - } - web.GoToast(m, kit.Select(m.CommandKey(), 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) + web.GoToast(m, title, func(toast func(string, int, int)) (list []string) { + msg.Table(func(index int, value ice.Maps) { + toast(value[REPOS], index, msg.Length()) if err := cb(_repos_open(m, value[REPOS]), value); err != nil && err != git.NoErrAlreadyUpToDate { web.ToastFailure(m, value[REPOS], err.Error()) list = append(list, value[REPOS]) } - count++ }) return }) @@ -122,23 +124,16 @@ func _repos_each(m *ice.Message, title string, cb func(*git.Repository, ice.Maps func _repos_each_origin(m *ice.Message, title string, cb func(*git.Repository, string, *http.BasicAuth, ice.Maps) error) { m.Option("repos.auth", _repos_credentials(m)) _repos_each(m, title, func(repos *git.Repository, value ice.Maps) error { - if value[ORIGIN] == "" { - return nil - } else if remote, err := repos.Remote(ORIGIN); err != nil { - return err - } else { - remoteURL := _repos_remote(m, remote.Config().URLs[0]) - auth := _repos_auth(m, remoteURL) - m.Info("%s: %s %s", m.ActionKey(), auth.Username, remoteURL) - return cb(repos, remoteURL, auth, value) - } + remote := _repos_remote(m, _repos_origin(m, repos)) + auth := _repos_auth(m, remote) + m.Info("%s: %s %s", m.ActionKey(), auth.Username, remote) + return cb(repos, remote, auth, value) }) } func _repos_credentials(m *ice.Message) map[string]*url.URL { list := map[string]*url.URL{} - m.Cmd(nfs.CAT, kit.HomePath(".git-credentials"), func(line string) { - u := kit.ParseURL(strings.ReplaceAll(line, "%3a", ":")) - list[u.Host] = u + nfs.Exists(m, kit.HomePath(_GITCREDENTIALS), func(p string) { + m.Cmd(nfs.CAT, p, func(text string) { u := kit.ParseURL(strings.ReplaceAll(text, "%3a", ":")); list[u.Host] = u }) }) return list } @@ -156,9 +151,9 @@ func _repos_auth(m *ice.Message, origin string) *http.BasicAuth { func _repos_path(m *ice.Message, p string, arg ...string) string { if p == path.Base(kit.Path("")) { return kit.Path("", arg...) - } else if nfs.Exists(m, path.Join(nfs.USR, p, ".git")) { + } else if nfs.Exists(m, path.Join(nfs.USR, p, _GIT)) { return path.Join(nfs.USR, p, path.Join(arg...)) - } else if nfs.Exists(m, path.Join(nfs.USR_LOCAL_WORK, p, ".git")) { + } else if nfs.Exists(m, path.Join(nfs.USR_LOCAL_WORK, p, _GIT)) { return path.Join(nfs.USR_LOCAL_WORK, p, path.Join(arg...)) } else { return p @@ -172,7 +167,7 @@ func _repos_branch(m *ice.Message, repos *git.Repository) error { } iter.ForEach(func(refer *plumbing.Reference) error { if commit, err := repos.CommitObject(refer.Hash()); err == nil { - m.Push(mdb.TIME, commit.Author.When.Format(ice.MOD_TIME)) + m.Push(mdb.TIME, _repos_when(m, commit)) m.Push(BRANCH, refer.Name().Short()) m.Push(aaa.USERNAME, commit.Author.Name) m.Push(mdb.TEXT, commit.Message) @@ -195,7 +190,7 @@ func _repos_log(m *ice.Message, hash plumbing.Hash, repos *git.Repository) error if m.Length() > limit { return nil } - m.Push(mdb.TIME, commit.Author.When) + m.Push(mdb.TIME, _repos_when(m, commit)) m.Push(COMMIT, commit.Hash.String()) m.Push(aaa.USERNAME, commit.Author.Name) m.Push(mdb.TEXT, commit.Message) @@ -390,6 +385,13 @@ const ( MESSAGE = "message" AUTHOR = "author" WHEN = "when" + + REMOTE_URL = "remoteURL" + _INSTEADOF = ".insteadof" + _GIT = ".git" + _GITCONFIG = ".gitconfig" + _GITIGNORE = ".gitignore" + _GITCREDENTIALS = ".git-credentials" ) const REPOS = "repos" @@ -429,25 +431,25 @@ func init() { m.Cmd(nfs.DIR, nfs.USR, func(value ice.Maps) { _repos_insert(m, value[nfs.PATH]) }) m.Cmd(nfs.DIR, nfs.USR_LOCAL_WORK, func(value ice.Maps) { _repos_insert(m, value[nfs.PATH]) }) m.Cmd(CONFIGS, func(value ice.Maps) { - if strings.HasSuffix(value[mdb.NAME], ".insteadof") && strings.HasPrefix(ice.Info.Make.Remote, value[mdb.VALUE]) { - mdb.Config(m, INSTEADOF, strings.TrimPrefix(strings.TrimSuffix(value[mdb.NAME], ".insteadof"), "url.")) + if strings.HasSuffix(value[mdb.NAME], _INSTEADOF) && strings.HasPrefix(ice.Info.Make.Remote, value[mdb.VALUE]) { + mdb.Config(m, INSTEADOF, strings.TrimPrefix(strings.TrimSuffix(value[mdb.NAME], _INSTEADOF), "url.")) } }) }}, INSTEADOF: {Name: "insteadof remote", Help: "代理", Icon: "bi bi-clouds", Hand: func(m *ice.Message, arg ...string) { m.Cmd(CONFIGS, func(value ice.Maps) { - if strings.HasSuffix(value[mdb.NAME], ".insteadof") && strings.HasPrefix(ice.Info.Make.Remote, value[mdb.VALUE]) { - _git_cmd(m, CONFIG, "--global", "--unset", value[mdb.NAME]) + if strings.HasSuffix(value[mdb.NAME], _INSTEADOF) && strings.HasPrefix(ice.Info.Make.Remote, value[mdb.VALUE]) { + _git_cmd(m, CONFIG, GLOBAL, UNSET, value[mdb.NAME]) } }) if mdb.Config(m, INSTEADOF, m.Option(REMOTE)); m.Option(REMOTE) != "" { - _git_cmd(m, CONFIG, "--global", "url."+m.Option(REMOTE)+".insteadof", strings.TrimSuffix(ice.Info.Make.Remote, path.Base(ice.Info.Make.Remote))) + _git_cmd(m, CONFIG, GLOBAL, "url."+m.Option(REMOTE)+_INSTEADOF, strings.TrimSuffix(ice.Info.Make.Remote, path.Base(ice.Info.Make.Remote))) } }}, INIT: {Name: "init origin* path", Hand: func(m *ice.Message, arg ...string) { m.OptionDefault(nfs.PATH, kit.Path("")) m.Cmd(nfs.DEFS, path.Join(m.Option(nfs.PATH), ".git/config"), kit.Format(nfs.Template(m, CONFIG), m.Option(ORIGIN))) - m.Cmd(nfs.DEFS, path.Join(m.Option(nfs.PATH), ".gitignore"), nfs.Template(m, IGNORE)) + m.Cmd(nfs.DEFS, path.Join(m.Option(nfs.PATH), _GITIGNORE), nfs.Template(m, IGNORE)) git.PlainInit(m.Option(nfs.PATH), false) _repos_insert(m, m.Option(nfs.PATH)) m.ProcessRefresh() @@ -467,24 +469,15 @@ func init() { if commit, err := repos.CommitObject(refer.Hash()); err == nil { m.Push(aaa.EMAIL, commit.Author.Email) m.Push(AUTHOR, commit.Author.Name) - m.Push(WHEN, strings.TrimSuffix(commit.Author.When.Format(ice.MOD_TIME), ".000")) + m.Push(WHEN, _repos_when(m, commit)) m.Push(MESSAGE, commit.Message) } } }}, - "remoteURL": {Hand: func(m *ice.Message, arg ...string) { + REMOTE_URL: {Hand: func(m *ice.Message, arg ...string) { m.Echo(_repos_remote(m, _repos_origin(m, _repos_open(m, path.Base(kit.Path("")))))) }}, mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) { - switch m.Option(ctx.ACTION) { - case CLONE: - switch arg[0] { - case ORIGIN: - m.Push(arg[0], "https://shylinux.com/x/icons") - m.Push(arg[0], "https://shylinux.com/x/geoarea") - m.Push(arg[0], "https://shylinux.com/x/node_modules") - } - } switch arg[0] { case MESSAGE: ls := kit.Split(m.Option(nfs.FILE), " /") @@ -506,13 +499,13 @@ func init() { m.OptionDefault(mdb.NAME, path.Base(m.Option(ORIGIN))) m.OptionDefault(nfs.PATH, path.Join(nfs.USR, m.Option(mdb.NAME))+nfs.PS) defer m.Cmdy(nfs.DIR, m.Option(nfs.PATH)) - if nfs.Exists(m, path.Join(m.Option(nfs.PATH), ".git")) { + if nfs.Exists(m, path.Join(m.Option(nfs.PATH), _GIT)) { return } defer web.ToastProcess(m)() for _, dev := range []string{ice.DEV, ice.SHY} { p := m.Option(ORIGIN) - kit.If(!kit.HasPrefix(p, nfs.PS, web.HTTP), func() { p = m.Cmdv("web.spide", dev, web.CLIENT_ORIGIN) + web.X(p) }) + kit.If(!kit.HasPrefix(p, nfs.PS, web.HTTP), func() { p = m.Cmdv(web.SPIDE, dev, web.CLIENT_ORIGIN) + web.X(p) }) m.Info("clone %s", p) if _, err := git.PlainClone(m.Option(nfs.PATH), false, &git.CloneOptions{URL: p, Auth: _repos_auth(m, p)}); !m.Warn(err) { _repos_insert(m, m.Option(nfs.PATH)) @@ -543,7 +536,7 @@ func init() { _repos_each(m, "", func(repos *git.Repository, value ice.Maps) error { if refer, err := repos.Head(); err == nil { if commit, err := repos.CommitObject(refer.Hash()); err == nil { - _last := commit.Author.When.Format(ice.MOD_TIME) + _last := _repos_when(m, commit) kit.If(_last > last, func() { last = _last }) } } @@ -585,7 +578,7 @@ func init() { } } } - m.Warn(kit.Lasterr(work.Commit(m.Option("actions")+lex.SP+m.Option(MESSAGE), opt))) + m.Warn(kit.Lasterr(work.Commit(kit.JoinWord(m.Option("actions"), m.Option(MESSAGE)), opt))) } }}, LOG: {Hand: func(m *ice.Message, arg ...string) { @@ -622,17 +615,16 @@ func init() { }, aaa.RoleAction(REMOTE), web.StatsAction("", "代码库总数"), web.DreamAction(), mdb.HashAction(mdb.SHORT, REPOS, mdb.FIELD, "time,repos,branch,version,message,origin"), mdb.ClearOnExitHashAction()), 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 { - _repos_branch(m, _repos_open(m, arg[0])) + } else if repos := _repos_open(m, arg[0]); len(arg) == 1 { + _repos_branch(m, repos) } else if len(arg) == 2 { - repos := _repos_open(m, arg[0]) if branch, err := repos.Branch(arg[1]); !m.Warn(err) { if refer, err := repos.Reference(branch.Merge, true); !m.Warn(err) { _repos_log(m, refer.Hash(), repos) } } } else if len(arg) == 3 { - if repos := _repos_open(m, arg[0]); arg[2] == INDEX { + if arg[2] == INDEX { _repos_status(m, arg[0], repos) } else { _repos_stats(m, repos, arg[2]) @@ -643,12 +635,13 @@ func init() { }}, }) } -func ReposList(m *ice.Message) *ice.Message { - return m.Cmdy(web.CODE_GIT_REPOS, ice.OptionFields("repos,path")) -} + func ReposClone(m *ice.Message, arg ...string) *ice.Message { return m.Cmdy(web.CODE_GIT_REPOS, CLONE, arg) } func ReposInit(m *ice.Message, arg ...string) *ice.Message { return m.Cmdy(web.CODE_GIT_REPOS, INIT, arg) } +func ReposList(m *ice.Message) *ice.Message { + return m.Cmdy(web.CODE_GIT_REPOS, ice.OptionFields("repos,path,origin")) +} diff --git a/misc/git/search.go b/misc/git/search.go index 7eda7c65..a543c31d 100644 --- a/misc/git/search.go +++ b/misc/git/search.go @@ -21,7 +21,6 @@ func init() { REPOS_SEARCH = "/api/v1/repos/search" ) const ( - WEB_SPIDE = "web.spide" DESCRIPTION = "description" UPDATED_AT = "updated_at" CLONE_URL = "clone_url" @@ -50,10 +49,10 @@ func init() { }}, }, web.DreamAction()), Hand: func(m *ice.Message, arg ...string) { if len(arg) == 0 { - m.Cmdy(WEB_SPIDE).RenameAppend(web.CLIENT_NAME, REPOS, web.CLIENT_URL, ORIGIN).Cut("time,repos,origin") + m.Cmdy(web.SPIDE).RenameAppend(web.CLIENT_NAME, REPOS, web.CLIENT_URL, ORIGIN).Cut("time,repos,origin") return } - kit.For(kit.Value(kit.UnMarshal(m.Cmdx(WEB_SPIDE, arg[0], web.SPIDE_RAW, http.MethodGet, REPOS_SEARCH, + kit.For(kit.Value(kit.UnMarshal(m.Cmdx(web.SPIDE, arg[0], web.SPIDE_RAW, http.MethodGet, REPOS_SEARCH, "q", kit.Select("", arg, 1), mdb.SORT, "updated", mdb.ORDER, "desc", mdb.PAGE, "1", mdb.LIMIT, "30")), mdb.DATA), func(value ice.Map) { value[nfs.SIZE] = kit.FmtSize(kit.Int(value[nfs.SIZE]) * 1000) if t, e := time.Parse(time.RFC3339, kit.Format(value[UPDATED_AT])); e == nil { diff --git a/misc/git/service.go b/misc/git/service.go index 787f29f3..c6ecbd1f 100644 --- a/misc/git/service.go +++ b/misc/git/service.go @@ -23,6 +23,7 @@ import ( "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" "shylinux.com/x/icebergs/base/web" + "shylinux.com/x/icebergs/base/web/html" "shylinux.com/x/icebergs/core/code" kit "shylinux.com/x/toolkits" ) @@ -31,7 +32,7 @@ func _service_path(m *ice.Message, p string, arg ...string) string { return kit.Path(ice.USR_LOCAL_REPOS, kit.TrimExt(p, GIT), path.Join(arg...)) } func _service_link(m *ice.Message, p string, arg ...string) string { - return kit.MergeURL2(web.UserHost(m), web.X(p)+".git") + return kit.MergeURL2(web.UserHost(m), web.X(p)+_GIT) } func _service_param(m *ice.Message, arg ...string) (string, string) { repos, service := arg[0], kit.Select(arg[len(arg)-1], m.Option(SERVICE)) @@ -54,9 +55,9 @@ func _service_repos(m *ice.Message, arg ...string) error { if mdb.Conf(m, web.CODE_GIT_SERVICE, kit.Keym(ice.CMD)) == GIT { return _service_repos0(m, arg...) } - if service == RECEIVE_PACK && m.R.Method == http.MethodPost { - return _service_repos0(m, arg...) - } + // if service == RECEIVE_PACK && m.R.Method == http.MethodPost { + // return _service_repos0(m, arg...) + // } reader, err := _service_reader(m) if err != nil { return err @@ -89,7 +90,7 @@ func _service_writer(m *ice.Message, cmd string, str ...string) { m.W.Write([]byte(s + cmd + "0000" + strings.Join(str, ""))) } func _service_reader(m *ice.Message) (io.ReadCloser, error) { - switch m.R.Header.Get("content-encoding") { + switch m.R.Header.Get(html.ContentEncoding) { case "deflate": return flate.NewReader(m.R.Body), nil case "gzip": @@ -108,7 +109,7 @@ const SERVICE = "service" func init() { web.Index.MergeCommands(ice.Commands{"/x/": {Actions: aaa.WhiteAction(), Hand: func(m *ice.Message, arg ...string) { if !m.IsCliUA() { - web.RenderCmd(m, "web.code.git.service", arg) + web.RenderCmd(m, web.CODE_GIT_SERVICE, arg) return } else if len(arg) == 0 { return @@ -154,14 +155,12 @@ func init() { mdb.HashRemove(m, m.Option(REPOS)) nfs.Trash(m, _service_path(m, m.Option(REPOS))) }}, - code.INNER: {Hand: func(m *ice.Message, arg ...string) { - _repos_inner(m, _service_path, arg...) - }}, + code.INNER: {Hand: func(m *ice.Message, arg ...string) { _repos_inner(m, _service_path, arg...) }}, web.DREAM_INPUTS: {Hand: func(m *ice.Message, arg ...string) { kit.If(arg[0] == REPOS, func() { mdb.HashSelect(m).Sort(REPOS).Cut("repos,version,time") - p := m.Cmdv("web.spide", ice.DEV, web.CLIENT_ORIGIN) - m.Spawn().SplitIndex(m.Cmdx("web.spide", ice.DEV, web.SPIDE_RAW, http.MethodGet, web.C(web.CODE_GIT_SERVICE))).Table(func(value ice.Maps) { + p := m.Cmdv(web.SPIDE, ice.DEV, web.CLIENT_ORIGIN) + m.Spawn().SplitIndex(m.Cmdx(web.SPIDE, ice.DEV, web.SPIDE_RAW, http.MethodGet, web.C(web.CODE_GIT_SERVICE))).Table(func(value ice.Maps) { value[nfs.REPOS] = p + web.X(value[nfs.REPOS]) m.Push("", value, kit.Split("repos,version,time")) }) @@ -173,9 +172,7 @@ func init() { m.Push(nfs.SIZE, kit.Split(m.Cmdx(cli.SYSTEM, "du", "-sh", path.Join(ice.USR_LOCAL_REPOS, value[REPOS])))[0]) m.PushScript(kit.Format("git clone %s", _service_link(m, value[REPOS]))) }).Sort(REPOS) - if !m.IsCliUA() { - m.Cmdy(web.CODE_PUBLISH, ice.CONTEXTS, ice.DEV) - } + kit.If(!m.IsCliUA(), func() { m.Cmdy(web.CODE_PUBLISH, ice.CONTEXTS, ice.DEV) }) kit.If(mdb.Config(m, aaa.AUTH) == aaa.PRIVATE, func() { m.StatusTimeCount(aaa.AUTH, aaa.PRIVATE) }) } else if repos := _repos_open(m, arg[0]); len(arg) == 1 { defer m.PushScript(kit.Format("git clone %s", _service_link(m, arg[0]))) diff --git a/misc/git/spide.go b/misc/git/spide.go deleted file mode 100644 index 750aa2c5..00000000 --- a/misc/git/spide.go +++ /dev/null @@ -1,22 +0,0 @@ -package git - -import ( - ice "shylinux.com/x/icebergs" - "shylinux.com/x/icebergs/base/ctx" - "shylinux.com/x/icebergs/base/nfs" -) - -const SPIDE = "spide" - -func init() { - Index.MergeCommands(ice.Commands{ - SPIDE: {Name: "spide repos auto", Help: "构架图", Hand: func(m *ice.Message, arg ...string) { - if len(arg) == 0 { - m.Cmdy(REPOS) - } else if p := _repos_path(m, arg[0]); len(arg) == 1 { - nfs.DirDeepAll(m, p, "", nil, nfs.PATH).Options(nfs.DIR_ROOT, p+nfs.PS) - ctx.DisplayStory(m, "") - } - }}, - }) -} diff --git a/misc/git/status.go b/misc/git/status.go index 8e5764e7..515ca64b 100644 --- a/misc/git/status.go +++ b/misc/git/status.go @@ -35,10 +35,10 @@ func init() { mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) { switch m.Option(ctx.ACTION) { case INIT: - m.Cmd("web.spide", ice.OptionFields(web.CLIENT_ORIGIN), func(value ice.Maps) { m.Push(arg[0], value[web.CLIENT_ORIGIN]+web.X(path.Base(kit.Path("")))) }) - m.Push(arg[0], kit.MergeURL2(web.UserHost(m), web.X())) - case INSTEADOF: - m.Cmd("web.spide", ice.OptionFields(web.CLIENT_ORIGIN), func(value ice.Maps) { m.Push(arg[0], value[web.CLIENT_ORIGIN]+web.X()) }) + m.Cmd(web.SPIDE, ice.OptionFields(web.CLIENT_ORIGIN), func(value ice.Maps) { m.Push(arg[0], value[web.CLIENT_ORIGIN]+web.X(path.Base(kit.Path("")))) }) + m.Push(arg[0], kit.MergeURL2(web.UserHost(m), web.X(path.Base(kit.Path(""))))) + case INSTEADOF, OAUTH: + m.Cmd(web.SPIDE, ice.OptionFields(web.CLIENT_ORIGIN), func(value ice.Maps) { m.Push(arg[0], value[web.CLIENT_ORIGIN]+web.X()) }) m.Push(arg[0], kit.MergeURL2(web.UserHost(m), web.X())) default: switch arg[0] { @@ -52,26 +52,23 @@ func init() { } }}, 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"), kit.Format(nfs.Template(m, "gitconfig"), m.Option(aaa.USERNAME), m.Option(aaa.EMAIL))) - kit.If(m.Option(web.TOKEN), func() { m.Cmd(web.TOKEN, "set") }) + CONFIGS: {Name: "configs email* username*", Help: "配置", Hand: func(m *ice.Message, arg ...string) { + m.Cmd(nfs.DEFS, kit.HomePath(_GITCONFIG), kit.Format(nfs.Template(m, "gitconfig"), m.Option(aaa.USERNAME), m.Option(aaa.EMAIL))) mdb.Config(m, aaa.USERNAME, m.Option(aaa.USERNAME)) mdb.Config(m, aaa.EMAIL, m.Option(aaa.EMAIL)) }}, INSTEADOF: {Name: "insteadof remote", Help: "代理", Icon: "bi bi-clouds", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(REPOS, INSTEADOF, arg) }}, - OAUTH: {Help: "授权", Icon: "bi bi-person-check", Hand: func(m *ice.Message, arg ...string) { - m.ProcessOpen(kit.MergeURL2(kit.Select(ice.Info.Make.Domain, m.Cmdx(REPOS, "remoteURL")), web.ChatCmdPath(m, web.TOKEN, "gen"), - mdb.TYPE, "web.code.git.status", tcp.HOST, m.Option(ice.MSG_USERWEB))) + OAUTH: {Name: "oauth remote", Help: "授权", Icon: "bi bi-person-check", Hand: func(m *ice.Message, arg ...string) { + m.ProcessOpen(kit.MergeURL2(kit.Select(ice.Info.Make.Domain, m.Cmdx(REPOS, REMOTE_URL), m.Option(REMOTE)), web.ChatCmdPath(m, web.TOKEN, "gen"), + mdb.TYPE, web.CODE_GIT_STATUS, tcp.HOST, m.Option(ice.MSG_USERWEB))) }}, web.DREAM_TABLES: {Hand: func(m *ice.Message, arg ...string) { - if !kit.IsIn(m.Option(mdb.TYPE), web.WORKER, web.SERVER) { - return - } else if !nfs.Exists(m, path.Join(ice.USR_LOCAL_WORK, m.Option(mdb.NAME), ".git")) { + if !nfs.Exists(m, path.Join(ice.USR_LOCAL_WORK, m.Option(mdb.NAME), _GIT)) { m.Push(mdb.TEXT, "") return } text := []string{} - for _, line := range kit.Split(m.Cmdx(web.SPACE, m.Option(mdb.NAME), cli.SYSTEM, GIT, DIFF, "--shortstat"), mdb.FS, mdb.FS) { + for _, line := range kit.Split(m.Cmdx(cli.SYSTEM, GIT, DIFF, "--shortstat", kit.Dict(cli.CMD_DIR, path.Join(ice.USR_LOCAL_WORK, m.Option(mdb.NAME)))), mdb.FS, mdb.FS) { if list := kit.Split(line); strings.Contains(line, nfs.FILE) { text = append(text, list[0]+" file") } else if strings.Contains(line, "ins") { @@ -83,13 +80,14 @@ func init() { m.Push(mdb.TEXT, strings.Join(text, ", ")) m.PushButton(kit.Dict(m.CommandKey(), "源码")) }}, - }, aaa.RoleAction(), web.DreamAction(), Prefix(REPOS)), Hand: func(m *ice.Message, arg ...string) { + web.DREAM_ACTION: {Hand: func(m *ice.Message, arg ...string) { web.DreamProcess(m, nil, arg...) }}, + }, aaa.RoleAction(), Prefix(REPOS)), Hand: func(m *ice.Message, arg ...string) { if len(arg) > 0 && arg[0] == ctx.ACTION { 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) + m.EchoInfoButton("please config email and name. ", CONFIGS) + } else if !nfs.Exists(m, _GIT) { + m.EchoInfoButton("please init repos. ", 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) diff --git a/misc/git/total.go b/misc/git/total.go deleted file mode 100644 index e7097650..00000000 --- a/misc/git/total.go +++ /dev/null @@ -1,138 +0,0 @@ -package git - -import ( - "path" - "strings" - "sync" - "time" - - 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" - "shylinux.com/x/icebergs/base/web" - kit "shylinux.com/x/toolkits" - "shylinux.com/x/toolkits/logs" - "shylinux.com/x/toolkits/task" -) - -const TOTAL = "total" - -func init() { - const ( - FROM = "from" - DAYS = "days" - COMMIT = "commit" - ADDS = "adds" - DELS = "dels" - REST = "rest" - ) - Index.MergeCommands(ice.Commands{ - TOTAL: {Name: "total repos auto pie", Help: "统计量", Actions: ice.Actions{ - "pie": {Help: "饼图", Hand: func(m *ice.Message, arg ...string) { - defer ctx.DisplayStory(m, "pie.js") - m.Cmd("", func(value ice.Maps) { - kit.If(value[REPOS] != mdb.TOTAL, func() { - m.Push(REPOS, value[REPOS]).Push(mdb.VALUE, value[REST]).Push("", value, []string{FROM, DAYS, COMMIT, ADDS, DELS}) - }) - }) - }}, - }, Hand: func(m *ice.Message, arg ...string) { - if len(arg) > 0 { - ReposList(m.Spawn()).Table(func(value ice.Maps) { - kit.If(value[REPOS] == arg[0], func() { m.Cmdy("_sum", value[nfs.PATH], arg[1:]) }) - }) - m.StatusTimeCount(m.AppendSimple(FROM)) - return - } - defer web.ToastProcess(m)() - from, days, commit, adds, dels, rest := "", 0, 0, 0, 0, 0 - TableGo(ReposList(m.Spawn()), func(value ice.Maps, lock *task.Lock) { - if kit.IsIn(value[REPOS], "websocket", "go-qrcode", "go-git", "icons", "geoarea", "program", "node_modules") { - return - } - msg := m.Cmd("_sum", value[nfs.PATH], mdb.TOTAL, "10000") - defer lock.Lock()() - msg.Table(func(value ice.Maps) { - kit.If(kit.Int(value[DAYS]) > days, func() { from, days = value[FROM], kit.Int(value[DAYS]) }) - commit += kit.Int(value[COMMIT]) - adds += kit.Int(value[ADDS]) - dels += kit.Int(value[DELS]) - rest += kit.Int(value[REST]) - }) - m.Push(REPOS, value[REPOS]).Copy(msg) - }) - m.Push(REPOS, mdb.TOTAL).Push(TAGS, "v3.0.0").Push(FROM, from).Push(DAYS, days).Push(COMMIT, commit).Push(ADDS, adds).Push(DELS, dels).Push(REST, rest) - m.SortIntR(REST) - }}, - "_sum": {Name: "_sum [path] [total] [count|date] args...", Help: "统计量", Hand: func(m *ice.Message, arg ...string) { - m.Options(nfs.DIR_ROOT, "", nfs.CAT_CONTENT, "") - if len(arg) > 0 { - if nfs.Exists(m, path.Join(arg[0], ".git")) || nfs.Exists(m, path.Join(arg[0], "refs/heads/")) { - m.Option(cli.CMD_DIR, arg[0]) - arg = arg[1:] - } - } - total := false - kit.If(len(arg) > 0 && arg[0] == mdb.TOTAL, func() { total, arg = true, arg[1:] }) - args := []string{LOG, "--shortstat", "--pretty=commit: %H %ad %n%s", "--date=iso", "--reverse"} - if len(arg) > 0 { - arg[0] += kit.Select("", " 00:00:00", strings.Contains(arg[0], "-") && !strings.Contains(arg[0], nfs.DF)) - args = append(args, kit.Select("-n", "--since", strings.Contains(arg[0], "-"))) - args = append(args, arg...) - } else { - args = append(args, "-n", "30") - } - from, days, commit, adds, dels := "", 0, 0, 0, 0 - kit.SplitKV(lex.NL, "commit:", _git_cmds(m, args...), func(text string, ls []string) { - add, del := "0", "0" - for _, v := range kit.Split(strings.TrimSpace(kit.Select("", ls, -1)), mdb.FS) { - switch { - case strings.Contains(v, "inser"): - add = kit.Split(v)[0] - case strings.Contains(v, "delet"): - del = kit.Split(v)[0] - } - } - hs := strings.Split(ls[0], lex.SP) - if total { - if commit++; from == "" { - if t, e := time.Parse("2006-01-02", hs[1]); e == nil { - from, days = hs[1], int(time.Now().Sub(t).Hours())/24 - } - } - adds += kit.Int(add) - dels += kit.Int(del) - return - } - m.Push(FROM, hs[1]).Push(ADDS, add).Push(DELS, del).Push(REST, kit.Int(add)-kit.Int(del)).Push(COMMIT, ls[1]).Push(mdb.HASH, hs[0]) - }) - if total { - m.Push(TAGS, _git_cmds(m, "describe", "--tags")) - m.Push(FROM, from).Push(DAYS, days).Push(COMMIT, commit) - m.Push(ADDS, adds).Push(DELS, dels).Push(REST, adds-dels) - } - }}, - }) -} -func TableGo(m *ice.Message, cb ice.Any) *ice.Message { - wg, lock := sync.WaitGroup{}, &task.Lock{} - defer wg.Wait() - m.Table(func(value ice.Maps) { - wg.Add(1) - task.Put(m.FormatTaskMeta(), logs.FileLine(cb), func(*task.Task) { - defer wg.Done() - switch cb := cb.(type) { - case func(ice.Maps, *task.Lock): - cb(value, lock) - case func(ice.Maps): - cb(value) - default: - m.ErrorNotImplement(cb) - } - }) - }) - return m -} diff --git a/misc/git/trend.go b/misc/git/trend.go deleted file mode 100644 index 26ba5dd0..00000000 --- a/misc/git/trend.go +++ /dev/null @@ -1,42 +0,0 @@ -package git - -import ( - ice "shylinux.com/x/icebergs" - "shylinux.com/x/icebergs/base/ctx" - "shylinux.com/x/icebergs/base/mdb" - "shylinux.com/x/icebergs/base/nfs" - "shylinux.com/x/icebergs/base/web/html" - "shylinux.com/x/icebergs/core/code" - kit "shylinux.com/x/toolkits" -) - -const TREND = "trend" - -func init() { - Index.MergeCommands(ice.Commands{ - TREND: {Name: "trend repos begin_time@date auto", Help: "趋势图", Meta: kit.Dict( - ice.CTX_TRANS, kit.Dict( - html.INPUT, kit.Dict( - "from", "起始", - "date", "日期", - "max", "最多", - "add", "添加", - "del", "删除", - ), - ), - ), Actions: ice.Actions{ - mdb.DETAIL: {Hand: func(m *ice.Message, arg ...string) { - m.Cmdy("", code.INNER, m.Option(REPOS), MASTER, m.Option(mdb.HASH), m.Cmdv(REPOS, m.Option(REPOS), MASTER, m.Option(mdb.HASH), nfs.FILE)) - }}, - code.INNER: {Hand: func(m *ice.Message, arg ...string) { - ctx.DisplayLocalInner(m.Cmdy(REPOS, code.INNER, arg), ctx.STYLE, html.FLOAT) - }}, - }, Hand: func(m *ice.Message, arg ...string) { - if len(arg) == 0 { - m.Cmdy(REPOS) - } else { - ctx.DisplayStory(m.Cmdy(TOTAL, kit.Slice(arg, 0, 2)), "") - } - }}, - }) -} diff --git a/misc/ssh/relay/relay.go b/misc/ssh/relay/relay.go index 494e4ca4..082023e6 100644 --- a/misc/ssh/relay/relay.go +++ b/misc/ssh/relay/relay.go @@ -239,7 +239,7 @@ func (s relay) List(m *ice.Message, arg ...string) *ice.Message { return } m.Push(web.LINK, web.HostPort(m.Message, value[tcp.HOST], value[web.PORTAL])) - m.PushButton(s.Admin, s.Dream, s.Xterm, s.Vimer, s.AdminCmd, s.Pushbin, s.Upgrade, s.Remove) + m.PushButton(s.Admin, s.Dream, s.Vimer, s.Xterm, s.AdminCmd, s.Pushbin, s.Upgrade, s.Remove) kit.If(len(arg) > 0, func() { m.PushQRCode(cli.QRCODE, m.Append(web.LINK)) }) }) _stats := kit.Dict(MEM, kit.FmtSize(stats[MEM_FREE], stats[MEM_TOTAL]), DISK, kit.FmtSize(stats[DISK_USED], stats[DISK_TOTAL])) diff --git a/render.go b/render.go index 9b0b9f9e..83c18944 100644 --- a/render.go +++ b/render.go @@ -5,6 +5,7 @@ import ( "path" "strings" + "shylinux.com/x/icebergs/base/web/html" kit "shylinux.com/x/toolkits" ) @@ -209,7 +210,8 @@ func (m *Message) EchoFields(cmd string, arg ...string) *Message { `, cmd, kit.Join(arg)) } func (m *Message) EchoInfoButton(info string, arg ...Any) *Message { - return m.Echo(info).EchoButton(arg...).Echo(NL).Action(arg...) + m.Display("/plugin/story/table.js", "style", "form") + return m.Echo(html.Format("div", info, "class", "info", "style", kit.JoinCSS())).EchoButton(arg...).Echo(NL).Action(arg...) } func (m *Message) EchoButton(arg ...Any) *Message { return m.Echo(Render(m, RENDER_BUTTON, arg...)) } func (m *Message) EchoAnchor(arg ...string) *Message { return m.Echo(Render(m, RENDER_ANCHOR, arg)) }