1
0
forked from x/icebergs
This commit is contained in:
IT 老营长 @云轩领航-创始人 2023-12-30 20:17:56 +08:00
parent 693ee73a82
commit 932002cf32
29 changed files with 147 additions and 513 deletions

View File

@ -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

View File

@ -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)

View File

@ -56,12 +56,10 @@ 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
}
}
for i := 0; i < 10; i++ {
if m.Cmd(SPACE, name).Length() > 0 {
m.Info("already exists %v", name)
@ -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
})

View File

@ -15,6 +15,7 @@ const (
Basic = "Basic"
Accept = "Accept"
AcceptLanguage = "Accept-Language"
ContentEncoding = "Content-Encoding"
ContentLength = "Content-Length"
ContentType = "Content-Type"
XForwardedFor = "X-Forwarded-For"

View File

@ -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

View File

@ -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"

View File

@ -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()

View File

@ -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]))
}
}},

View File

@ -247,6 +247,7 @@ const ( // MSG
TOAST_DURATION = "toast.duration"
TABLE_CHECKBOX = "table.checkbox"
TCP_DOMAIN = "tcp_domain"
)
const ( // RENDER
RENDER_BUTTON = "_button"

View File

@ -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())},
})
}

View File

@ -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

View File

@ -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")

View File

@ -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) {

View File

@ -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) {

View File

@ -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 {

View File

@ -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)

View File

@ -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")

View File

@ -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]))
}
}},
})
}

View File

@ -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) }},
})
}

View File

@ -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

View File

@ -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"))
}

View File

@ -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 {

View File

@ -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])))

View File

@ -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, "")
}
}},
})
}

View File

@ -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)

View File

@ -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
}

View File

@ -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)), "")
}
}},
})
}

View File

@ -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]))

View File

@ -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)) }