diff --git a/base/nfs/dir.go b/base/nfs/dir.go index 1448b734..8a4c67ea 100644 --- a/base/nfs/dir.go +++ b/base/nfs/dir.go @@ -158,12 +158,13 @@ func _dir_search(m *ice.Message, kind, name string) { }) } -func Dir(m *ice.Message, sort string) { +func Dir(m *ice.Message, sort string) *ice.Message { m.Option(DIR_TYPE, TYPE_DIR) m.Copy(m.Cmd(DIR, "./").Sort(sort)) m.Option(DIR_TYPE, TYPE_CAT) m.Copy(m.Cmd(DIR, "./").Sort(sort)) + return m } const ( @@ -207,7 +208,7 @@ func init() { }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Info("dir_root: %v", m.Option(DIR_ROOT)) - _dir_list(m, kit.Select("./", m.Option(DIR_ROOT)), kit.Select("", arg, 0), + _dir_list(m, kit.Select("./", m.Option(DIR_ROOT)), kit.Select("./", arg, 0), 0, m.Option(DIR_DEEP) == ice.TRUE, kit.Select(TYPE_BOTH, m.Option(DIR_TYPE)), kit.Regexp(m.Option(DIR_REG)), kit.Split(kit.Select(kit.Select("time,path,size,action", m.OptionFields()), kit.Join(kit.Slice(arg, 1))))) m.SortTimeR(kit.MDB_TIME) diff --git a/base/web/render.go b/base/web/render.go index f8243892..b85af82d 100644 --- a/base/web/render.go +++ b/base/web/render.go @@ -49,6 +49,8 @@ func Render(msg *ice.Message, cmd string, args ...interface{}) { case ice.RENDER_VOID: // no output + case ice.RENDER_RAW: + fallthrough default: for _, k := range []string{ "_option", "_handle", "_output", "", @@ -58,7 +60,7 @@ func Render(msg *ice.Message, cmd string, args ...interface{}) { msg.Set(k) } - if cmd != "" { // [str [arg...]] + if cmd != "" && cmd != ice.RENDER_RAW { // [str [arg...]] msg.Echo(kit.Format(cmd, args...)) } msg.W.Header().Set(ContentType, ContentJSON) diff --git a/base/web/serve.go b/base/web/serve.go index cbd5a728..4093ecd2 100644 --- a/base/web/serve.go +++ b/base/web/serve.go @@ -17,6 +17,12 @@ import ( kit "shylinux.com/x/toolkits" ) +var rewriteList = []func(w http.ResponseWriter, r *http.Request) bool{} + +func AddRewrite(cb func(w http.ResponseWriter, r *http.Request) bool) { + rewriteList = append(rewriteList, cb) +} + func _serve_main(m *ice.Message, w http.ResponseWriter, r *http.Request) bool { if r.Header.Get("index.module") == "" { r.Header.Set("index.module", m.Prefix()) @@ -51,15 +57,10 @@ func _serve_main(m *ice.Message, w http.ResponseWriter, r *http.Request) bool { }() } - // 代码管理 - if strings.HasPrefix(r.URL.Path, "/x/") { - r.URL.Path = strings.Replace(r.URL.Path, "/x/", "/code/git/repos/", -1) - return true - } - // 调试接口 - if strings.HasPrefix(r.URL.Path, "/debug") { - r.URL.Path = strings.Replace(r.URL.Path, "/debug", "/code", -1) - return true + for _, h := range rewriteList { + if h(w, r) { + return true + } } // 主页接口 diff --git a/conf.go b/conf.go index dffd0869..7f4e9d3c 100644 --- a/conf.go +++ b/conf.go @@ -10,6 +10,8 @@ const ( NL = "\n" OF = " of " + PWD = "./" + OK = "ok" TRUE = "true" FALSE = "false" @@ -65,6 +67,7 @@ const ( // REPOS REQUIRE = "require" INSTALL = "install" PUBLISH = "publish" + RELEASE = "release" ) const ( // DIR SRC = "src" diff --git a/core/code/install.go b/core/code/install.go index a0ca9075..773cfc5a 100644 --- a/core/code/install.go +++ b/core/code/install.go @@ -87,7 +87,10 @@ func _install_build(m *ice.Message, arg ...string) { m.ProcessHold() } func _install_order(m *ice.Message, arg ...string) { - m.Cmd(nfs.PUSH, ice.ETC_PATH, kit.Path(m.Config(kit.MDB_PATH), kit.TrimExt(m.Option(kit.MDB_LINK)), m.Option(kit.MDB_PATH)+ice.NL)) + p := kit.Path(m.Config(kit.MDB_PATH), kit.TrimExt(m.Option(kit.MDB_LINK)), m.Option(kit.MDB_PATH)+ice.NL) + if !strings.Contains(m.Cmdx(nfs.CAT, ice.ETC_PATH), p) { + m.Cmd(nfs.PUSH, ice.ETC_PATH, p) + } m.Cmdy(nfs.CAT, ice.ETC_PATH) } func _install_spawn(m *ice.Message, arg ...string) { @@ -169,6 +172,7 @@ func init() { }}, cli.SOURCE: {Name: "source link path", Help: "源码", Hand: func(m *ice.Message, arg ...string) { m.Option(nfs.DIR_ROOT, path.Join(m.Config(kit.MDB_PATH), kit.TrimExt(m.Option(kit.MDB_LINK)), "_install")) + defer m.StatusTime(nfs.PATH, m.Option(nfs.DIR_ROOT)) m.Cmdy(nfs.DIR, m.Option(kit.MDB_PATH)) }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { diff --git a/core/code/pprof.go b/core/code/pprof.go index 69d6662a..5faf9820 100644 --- a/core/code/pprof.go +++ b/core/code/pprof.go @@ -30,6 +30,16 @@ func init() { PPROF, kit.List(GO, "tool", PPROF), )}, }, Commands: map[string]*ice.Command{ + ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + web.AddRewrite(func(w http.ResponseWriter, r *http.Request) bool { + if p := r.URL.Path; strings.HasPrefix(p, "/debug") { + r.URL.Path = strings.Replace(r.URL.Path, "/debug", "/code", -1) + m.Debug("rewrite %v -> %v", p, r.URL.Path) + return true + } + return false + }) + }}, "/pprof/": {Name: "/pprof/", Help: "性能分析", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.R.URL.Path = strings.Replace("/code"+m.R.URL.Path, "code", "debug", 1) http.DefaultServeMux.ServeHTTP(m.W, m.R) diff --git a/core/team/plan.go b/core/team/plan.go index 2eb8b2ad..0f8095f7 100644 --- a/core/team/plan.go +++ b/core/team/plan.go @@ -69,6 +69,14 @@ func init() { PLAN: {Name: "plan scale=week,day,week,month,year,long begin_time@date place@province auto insert export import", Help: "计划", Meta: kit.Dict( ice.Display("/plugin/local/team/plan.js"), ), Action: ice.MergeAction(map[string]*ice.Action{ + mdb.INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) { + switch arg[0] { + case m.Conf(TASK, kit.Keym(kit.MDB_SHORT)): + m.Cmdy(mdb.INPUTS, m.Prefix(TASK), "", mdb.HASH, arg) + default: + m.Cmdy(mdb.INPUTS, m.Prefix(TASK), "", mdb.ZONE, m.Option(m.Conf(TASK, kit.Keym(kit.MDB_SHORT))), arg) + } + }}, mdb.PLUGIN: {Name: "plugin extra.ctx extra.cmd extra.arg", Help: "插件", Hand: func(m *ice.Message, arg ...string) { _task_modify(m, arg[0], arg[1], arg[2:]...) }}, diff --git a/exec.go b/exec.go index d0538581..5474102c 100644 --- a/exec.go +++ b/exec.go @@ -55,6 +55,9 @@ func (m *Message) Sleep(d string) *Message { time.Sleep(kit.Duration(d)) return m } +func (m *Message) Sleep30ms() *Message { return m.Sleep("30ms") } +func (m *Message) Sleep3s() *Message { return m.Sleep("3s") } +func (m *Message) Sleep30s() *Message { return m.Sleep("30s") } func (m *Message) Hold(n int) *Message { for ctx := m.target; ctx != nil; ctx = ctx.context { if ctx.wg != nil { diff --git a/go.sum b/go.sum index 4d3f862d..7042070d 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,6 @@ +github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0= github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M= shylinux.com/x/toolkits v0.3.9 h1:apRA1BljrzFCBcesOpeIWYWsoC0JN6tgVO8TM+wUrg8= shylinux.com/x/toolkits v0.3.9/go.mod h1:8LbYHe7oxBIqb6s4MSOD+4d28QvPdvkyCVtwB/JW7AA= diff --git a/misc/git/config.go b/misc/git/configs.go similarity index 53% rename from misc/git/config.go rename to misc/git/configs.go index b3667736..142787d7 100644 --- a/misc/git/config.go +++ b/misc/git/configs.go @@ -9,14 +9,14 @@ import ( kit "shylinux.com/x/toolkits" ) -func _config_set(m *ice.Message, key, value string) { - m.Cmd(cli.SYSTEM, GIT, CONFIG, "--global", key, value) +func _configs_set(m *ice.Message, key, value string) { + m.Cmd(cli.SYSTEM, GIT, "config", "--global", key, value) } -func _config_get(m *ice.Message, key string) string { - return m.Cmdx(cli.SYSTEM, GIT, CONFIG, "--global", key) +func _configs_get(m *ice.Message, key string) string { + return m.Cmdx(cli.SYSTEM, GIT, "config", "--global", key) } -func _config_list(m *ice.Message) { - for _, v := range strings.Split(_config_get(m, "--list"), ice.NL) { +func _configs_list(m *ice.Message) { + for _, v := range strings.Split(_configs_get(m, "--list"), ice.NL) { if ls := strings.Split(v, "="); len(ls) > 1 { m.Push(kit.MDB_NAME, ls[0]) m.Push(kit.MDB_VALUE, ls[1]) @@ -25,55 +25,50 @@ func _config_list(m *ice.Message) { } m.Sort(kit.MDB_NAME) - m.Cmd(mdb.SELECT, m.Prefix(CONFIG), "", mdb.HASH, ice.OptionFields("name,value")).Table(func(index int, value map[string]string, head []string) { - m.Push("", value, head) - m.PushButton(mdb.CREATE) + mdb.HashSelect(m.Spawn(ice.OptionFields("name,value"))).Table(func(index int, value map[string]string, head []string) { + m.Push("", value, head).PushButton(mdb.CREATE) }) } -const CONFIG = "config" +const CONFIGS = "configs" func init() { Index.Merge(&ice.Context{Configs: map[string]*ice.Config{ - CONFIG: {Name: CONFIG, Help: "配置键", Value: kit.Data( - kit.MDB_SHORT, kit.MDB_NAME, "init", kit.Dict( - "alias", kit.Dict("s", "status", "b", "branch"), + CONFIGS: {Name: CONFIGS, Help: "配置键", Value: kit.Data( + kit.MDB_SHORT, kit.MDB_NAME, ice.INIT, kit.Dict( + "alias", kit.Dict("s", "status", "b", "branch", "l", "log --oneline --decorate"), "credential", kit.Dict("helper", "store"), "core", kit.Dict("quotepath", "false"), "push", kit.Dict("default", "simple"), "color", kit.Dict("ui", "always"), ))}, }, Commands: map[string]*ice.Command{ - CONFIG: {Name: "server name auto create import", Help: "配置键", Action: map[string]*ice.Action{ + CONFIGS: {Name: "configs name auto create import", Help: "配置键", Action: map[string]*ice.Action{ mdb.IMPORT: {Name: "import", Help: "初始化", Hand: func(m *ice.Message, arg ...string) { - kit.Fetch(m.Configv("init"), func(conf string, value interface{}) { - kit.Fetch(value, func(key string, value string) { - _config_set(m, kit.Keys(conf, key), value) - }) + kit.Fetch(m.Configv(ice.INIT), func(conf string, value interface{}) { + kit.Fetch(value, func(key string, value string) { _configs_set(m, kit.Keys(conf, key), value) }) }) }}, mdb.CREATE: {Name: "create name value", Help: "添加", Hand: func(m *ice.Message, arg ...string) { m.Cmd(mdb.DELETE, m.PrefixKey(), "", mdb.HASH, m.OptionSimple(kit.MDB_NAME)) - _config_set(m, m.Option(kit.MDB_NAME), m.Option(kit.MDB_VALUE)) - m.ProcessRefresh30ms() + _configs_set(m, m.Option(kit.MDB_NAME), m.Option(kit.MDB_VALUE)) + }}, + mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) { + m.Cmd(mdb.INSERT, m.PrefixKey(), "", mdb.HASH, m.OptionSimple(kit.MDB_NAME, kit.MDB_VALUE)) + _configs_set(m, "--unset", m.Option(kit.MDB_NAME)) }}, mdb.MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) { if arg[0] == kit.MDB_VALUE { m.Cmd(mdb.DELETE, m.PrefixKey(), "", mdb.HASH, m.OptionSimple(kit.MDB_NAME)) - _config_set(m, m.Option(kit.MDB_NAME), arg[1]) - m.ProcessRefresh30ms() + _configs_set(m, m.Option(kit.MDB_NAME), arg[1]) } }}, - mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) { - m.Cmd(mdb.INSERT, m.PrefixKey(), "", mdb.HASH, m.OptionSimple(kit.MDB_NAME, kit.MDB_VALUE)) - _config_set(m, "--unset", m.Option(kit.MDB_NAME)) - }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if len(arg) == 0 { - _config_list(m) + _configs_list(m) return } - m.Echo(_config_get(m, arg[0])) + m.Echo(_configs_get(m, arg[0])) }}, }}) } diff --git a/misc/git/count.go b/misc/git/count.go index 64220d1d..da3ff0d7 100644 --- a/misc/git/count.go +++ b/misc/git/count.go @@ -5,6 +5,7 @@ import ( ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/nfs" + "shylinux.com/x/icebergs/core/code" kit "shylinux.com/x/toolkits" ) @@ -12,17 +13,21 @@ const COUNT = "count" func init() { Index.Merge(&ice.Context{Commands: map[string]*ice.Command{ - COUNT: {Name: "count path auto count", Help: "统计", Action: map[string]*ice.Action{ + COUNT: {Name: "count path auto count", Help: "代码行", Action: map[string]*ice.Action{ COUNT: {Name: "count", Help: "计数", Hand: func(m *ice.Message, arg ...string) { + if len(arg) == 0 || arg[0] == "usr/" { + m.Echo("to many file, please choice sub dir") + return + } files := map[string]int{} lines := map[string]int{} m.Option(nfs.DIR_DEEP, ice.TRUE) m.Option(nfs.DIR_TYPE, nfs.TYPE_CAT) m.Cmdy(nfs.DIR, arg, func(file string) { - if strings.Contains(file, "bin/") { + if !strings.Contains(file, ice.PT) { return } - if !strings.Contains(file, ".") { + if strings.Contains(file, "bin/") { return } switch kit.Ext(file) { @@ -30,10 +35,10 @@ func init() { return } - files["total"]++ + files[kit.MDB_TOTAL]++ files[kit.Ext(file)]++ m.Cmdy(nfs.CAT, file, func(text string, line int) { - if kit.Ext(file) == "go" { + if kit.Ext(file) == code.GO { switch { case strings.HasPrefix(text, "func"): lines["_func"]++ @@ -42,7 +47,7 @@ func init() { } } - lines["total"]++ + lines[kit.MDB_TOTAL]++ lines[kit.Ext(file)]++ }) }) diff --git a/misc/git/git.go b/misc/git/git.go index e8e43158..45637fd6 100644 --- a/misc/git/git.go +++ b/misc/git/git.go @@ -17,7 +17,7 @@ var Index = &ice.Context{Name: GIT, Help: "代码库", Configs: map[string]*ice. }, Commands: map[string]*ice.Command{ GIT: {Name: "git path auto order build download", Help: "代码库", Action: ice.MergeAction(map[string]*ice.Action{ cli.ORDER: {Name: "order", Help: "加载", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(code.INSTALL, cli.ORDER, m.Config(cli.SOURCE), "_install/bin") + m.Cmd(code.INSTALL, cli.ORDER, m.Config(cli.SOURCE), "_install/bin") m.Cmdy(code.INSTALL, cli.ORDER, m.Config(cli.SOURCE), "_install/libexec/git-core") }}, }, code.InstallAction()), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { diff --git a/misc/git/git.shy b/misc/git/git.shy index 7bae4c71..34084362 100644 --- a/misc/git/git.shy +++ b/misc/git/git.shy @@ -3,7 +3,6 @@ refer ` 官网 https://git-scm.com/ 文档 https://git-scm.com/docs 源码 https://github.com/git/git -私服 https://github.com/go-gitea/gitea ` chapter "源码" @@ -32,9 +31,10 @@ cd ./_install chapter "应用" field "代码库" web.code.git.repos field "统计量" web.code.git.total +field "代码行" web.code.git.count field "趋势图" web.code.git.trend args `icebergs` field "架构图" web.code.git.spide args `icebergs` -field "配置键" web.code.git.config +field "配置键" web.code.git.configs field "状态机" web.code.git.status field "服务器" web.code.git.server diff --git a/misc/git/repos.go b/misc/git/repos.go index d397140a..5595c9cf 100644 --- a/misc/git/repos.go +++ b/misc/git/repos.go @@ -12,17 +12,20 @@ import ( kit "shylinux.com/x/toolkits" ) +func _repos_cmd(m *ice.Message, name string, arg ...string) { + m.Cmdy(cli.SYSTEM, GIT, arg, ice.Option{cli.CMD_DIR, _repos_path(name)}) +} func _repos_path(name string) string { if strings.Contains(name, ":\\") { return name } - return kit.Select(path.Join(ice.USR, name), "./", name == path.Base(kit.Pwd())) + return kit.Select(path.Join(ice.USR, name)+ice.PS, ice.PWD, name == path.Base(kit.Pwd())) } func _repos_insert(m *ice.Message, name string, dir string) { if s, e := os.Stat(m.Option(cli.CMD_DIR, path.Join(dir, ".git"))); e == nil && s.IsDir() { - ls := strings.SplitN(strings.Trim(m.Cmdx(cli.SYSTEM, GIT, "log", "-n1", `--pretty=format:"%ad %s"`, "--date=iso"), `"`), " ", 4) + ls := strings.SplitN(strings.Trim(m.Cmdx(cli.SYSTEM, GIT, "log", "-n1", `--pretty=format:"%ad %s"`, "--date=iso"), `"`), ice.SP, 4) m.Rich(REPOS, nil, kit.Data(kit.MDB_NAME, name, kit.MDB_PATH, dir, - COMMIT, kit.Select("", ls, 3), kit.MDB_TIME, strings.Join(ls[:2], " "), + COMMIT, kit.Select("", ls, 3), kit.MDB_TIME, strings.Join(ls[:2], ice.SP), BRANCH, strings.TrimSpace(m.Cmdx(cli.SYSTEM, GIT, BRANCH)), REMOTE, strings.TrimSpace(m.Cmdx(cli.SYSTEM, GIT, REMOTE, "-v")), )) @@ -44,7 +47,7 @@ func init() { Index.Merge(&ice.Context{Configs: map[string]*ice.Config{ REPOS: {Name: REPOS, Help: "代码库", Value: kit.Data( kit.MDB_SHORT, kit.MDB_NAME, kit.MDB_FIELD, "time,name,branch,commit,remote", - kit.SSH_REPOS, "https://shylinux.com/x", + REPOS, "https://shylinux.com/x", nfs.PATH, ice.USR_LOCAL, )}, }, Commands: map[string]*ice.Command{ REPOS: {Name: "repos name path auto create", Help: "代码库", Action: ice.MergeAction(map[string]*ice.Action{ @@ -56,9 +59,9 @@ func init() { }) }}, mdb.CREATE: {Name: "create repos branch name path", Help: "添加", Hand: func(m *ice.Message, arg ...string) { - m.Option(kit.MDB_NAME, kit.Select(strings.TrimSuffix(path.Base(m.Option(kit.SSH_REPOS)), ".git"), m.Option(kit.MDB_NAME))) + m.Option(kit.MDB_NAME, kit.Select(strings.TrimSuffix(path.Base(m.Option(REPOS)), ".git"), m.Option(kit.MDB_NAME))) m.Option(kit.MDB_PATH, kit.Select(path.Join(ice.USR, m.Option(kit.MDB_NAME)), m.Option(kit.MDB_PATH))) - m.Option(kit.SSH_REPOS, kit.Select(m.Conf(REPOS, kit.Keym(kit.SSH_REPOS))+ice.PS+m.Option(kit.MDB_NAME), m.Option(kit.SSH_REPOS))) + m.Option(REPOS, kit.Select(m.Config(REPOS)+ice.PS+m.Option(kit.MDB_NAME), m.Option(REPOS))) if s, e := os.Stat(path.Join(m.Option(kit.MDB_PATH), ".git")); e == nil && s.IsDir() { return @@ -68,11 +71,11 @@ func init() { if s, e := os.Stat(m.Option(kit.MDB_PATH)); e == nil && s.IsDir() { m.Option(cli.CMD_DIR, m.Option(kit.MDB_PATH)) m.Cmd(cli.SYSTEM, GIT, INIT) - m.Cmd(cli.SYSTEM, GIT, REMOTE, ADD, ORIGIN, m.Option(kit.SSH_REPOS)) + m.Cmd(cli.SYSTEM, GIT, REMOTE, ADD, ORIGIN, m.Option(REPOS)) m.Cmd(cli.SYSTEM, GIT, PULL, ORIGIN, MASTER) } else { m.Cmd(cli.SYSTEM, GIT, CLONE, "-b", kit.Select(MASTER, m.Option(BRANCH)), - m.Option(kit.SSH_REPOS), m.Option(kit.MDB_PATH)) + m.Option(REPOS), m.Option(kit.MDB_PATH)) } _repos_insert(m, m.Option(kit.MDB_NAME), m.Option(kit.MDB_PATH)) @@ -85,7 +88,7 @@ func init() { } m.Option(nfs.DIR_ROOT, _repos_path(arg[0])) - m.Cmdy(nfs.CAT, kit.Select("./", arg, 1), "time,line,path") + m.Cmdy(nfs.DIR, kit.Select("", arg, 1), "time,line,path") }}, }}) } diff --git a/misc/git/server.go b/misc/git/server.go index 776e8275..fc423499 100644 --- a/misc/git/server.go +++ b/misc/git/server.go @@ -6,6 +6,7 @@ import ( "encoding/base64" "fmt" "io" + "net/http" "os" "path" "regexp" @@ -15,6 +16,7 @@ import ( ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/aaa" "shylinux.com/x/icebergs/base/cli" + "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" "shylinux.com/x/icebergs/base/web" @@ -38,8 +40,10 @@ func packetWrite(m *ice.Message, cmd string, str ...string) { m.W.Write([]byte(s + cmd + "0000" + strings.Join(str, ""))) } +var basicAuthRegex = regexp.MustCompile("^([^:]*):(.*)$") + func _server_login(m *ice.Message) error { - parts := strings.SplitN(m.R.Header.Get("Authorization"), " ", 2) + parts := strings.SplitN(m.R.Header.Get("Authorization"), ice.SP, 2) if len(parts) < 2 { return fmt.Errorf("Invalid authorization header, not enought parts") } @@ -76,15 +80,15 @@ func _server_param(m *ice.Message, arg ...string) (string, string) { default: repos = strings.TrimSuffix(repos, service) } - return kit.Path(ice.USR_LOCAL, REPOS, repos), strings.TrimPrefix(service, "git-") + return kit.Path(m.Config(nfs.PATH), REPOS, repos), strings.TrimPrefix(service, "git-") } func _server_repos(m *ice.Message, arg ...string) error { repos, service := _server_param(m, arg...) if m.Option(cli.CMD_DIR, repos); strings.HasSuffix(path.Join(arg...), "info/refs") { web.RenderType(m.W, "", kit.Format("application/x-git-%s-advertisement", service)) - msg := m.Cmd(cli.SYSTEM, GIT, service, "--stateless-rpc", "--advertise-refs", ".") - packetWrite(m, "# service=git-"+service+"\n", msg.Result()) + msg := m.Cmd(cli.SYSTEM, GIT, service, "--stateless-rpc", "--advertise-refs", ice.PT) + packetWrite(m, "# service=git-"+service+ice.NL, msg.Result()) return nil } @@ -97,22 +101,29 @@ func _server_repos(m *ice.Message, arg ...string) error { m.Option(cli.CMD_OUTPUT, m.W) m.Option(cli.CMD_INPUT, reader) web.RenderType(m.W, "", kit.Format("application/x-git-%s-result", service)) - m.Cmd(cli.SYSTEM, GIT, service, "--stateless-rpc", ".") + m.Cmd(cli.SYSTEM, GIT, service, "--stateless-rpc", ice.PT) return nil } -var basicAuthRegex = regexp.MustCompile("^([^:]*):(.*)$") - const SERVER = "server" func init() { - Index.Merge(&ice.Context{Configs: map[string]*ice.Config{ - SERVER: {Name: SERVER, Help: "服务器", Value: kit.Data(kit.MDB_PATH, ice.USR_LOCAL)}, - }, Commands: map[string]*ice.Command{ + Index.Merge(&ice.Context{Commands: map[string]*ice.Command{ web.WEB_LOGIN: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { m.Render(ice.RENDER_VOID) }}, - "/repos/": {Name: "/repos/", Help: "代码库", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + "/repos/": {Name: "/repos/", Help: "代码库", Action: ice.MergeAction(map[string]*ice.Action{ + ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { + web.AddRewrite(func(w http.ResponseWriter, r *http.Request) bool { + if p := r.URL.Path; strings.HasPrefix(p, "/x/") { + r.URL.Path = strings.Replace(r.URL.Path, "/x/", "/code/git/repos/", -1) + m.Info("rewrite %v -> %v", p, r.URL.Path) + return true + } + return false + }) + }}, + }, ctx.CmdAction()), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if m.Option("go-get") == "1" { // 下载地址 p := kit.Split(kit.MergeURL2(m.Option(ice.MSG_USERWEB), "/x/"+path.Join(arg...)), "?")[0] m.RenderResult(kit.Format(``, "go-import", kit.Format(`%s git %s`, strings.TrimPrefix(p, "https://"), p))) @@ -124,10 +135,11 @@ func init() { if err := _server_login(m); err != nil { web.RenderHeader(m, "WWW-Authenticate", `Basic realm="git server"`) web.RenderStatus(m, 401, err.Error()) - return + return // 没有权限 } if _, e := os.Stat(path.Join(repos)); os.IsNotExist(e) { m.Cmd(cli.SYSTEM, GIT, INIT, "--bare", repos) // 创建仓库 + m.Log_CREATE(REPOS, repos) } case "upload-pack": // 下载代码 } @@ -143,7 +155,9 @@ func init() { }}, }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if m.Option(nfs.DIR_ROOT, path.Join(ice.USR_LOCAL, REPOS)); len(arg) == 0 { - m.Cmdy(nfs.DIR, "./") + m.Cmdy(nfs.DIR, "").Table(func(index int, value map[string]string, head []string) { + m.PushScript("git clone " + kit.MergeURL2(m.Option(ice.MSG_USERWEB), "/x/"+value[nfs.PATH])) + }) return } m.Cmdy("_sum", path.Join(m.Option(nfs.DIR_ROOT), arg[0])) diff --git a/misc/git/spide.go b/misc/git/spide.go index d0868cb3..33144872 100644 --- a/misc/git/spide.go +++ b/misc/git/spide.go @@ -61,30 +61,28 @@ const SPIDE = "spide" func init() { Index.Merge(&ice.Context{Commands: map[string]*ice.Command{ - SPIDE: {Name: "spide name@key auto", Help: "构架图", Meta: kit.Dict( + SPIDE: {Name: "spide name auto", Help: "构架图", Meta: kit.Dict( ice.Display("/plugin/story/spide.js"), - ), Action: map[string]*ice.Action{ + ), Action: ice.MergeAction(map[string]*ice.Action{ mdb.INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(REPOS) - }}, ctx.COMMAND: {Name: "ctx.command"}, code.INNER: {Name: "web.code.inner"}, - }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + m.Cmdy(REPOS, ice.OptionFields("name,time")) + }}, code.INNER: {Name: "web.code.inner"}, + }, ctx.CmdAction()), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if len(arg) == 0 { // 仓库列表 m.Cmdy(REPOS) return } if arg[0] == path.Base(kit.Pwd()) { - m.Option(nfs.DIR_ROOT, path.Join(ice.SRC)) + m.Option(nfs.DIR_ROOT, path.Join(ice.SRC)+ice.PS) } else { m.Option(nfs.DIR_ROOT, path.Join(ice.USR, arg[0])+ice.PS) } if len(arg) == 1 { // 目录列表 m.Option(nfs.DIR_DEEP, ice.TRUE) - nfs.Dir(m, kit.MDB_PATH) - color := []string{cli.YELLOW, cli.BLUE, cli.CYAN, cli.RED} - m.Table(func(index int, value map[string]string, head []string) { + nfs.Dir(m, kit.MDB_PATH).Table(func(index int, value map[string]string, head []string) { m.Push(kit.MDB_COLOR, color[strings.Count(value[kit.MDB_PATH], ice.PS)%len(color)]) }) return diff --git a/misc/git/status.go b/misc/git/status.go index c05b4d9e..75e89921 100644 --- a/misc/git/status.go +++ b/misc/git/status.go @@ -9,11 +9,13 @@ import ( "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" + "shylinux.com/x/icebergs/base/web" + "shylinux.com/x/icebergs/core/code" kit "shylinux.com/x/toolkits" ) -func _status_tags(m *ice.Message, tags string) string { - ls := kit.Split(strings.TrimPrefix(kit.Split(tags, "-")[0], "v"), ".") +func _status_tag(m *ice.Message, tags string) string { + ls := kit.Split(strings.TrimPrefix(kit.Split(tags, "-")[0], "v"), ice.PT) if v := kit.Int(ls[2]); v < 9 { return kit.Format("v%v.%v.%v", ls[0], ls[1], v+1) } else if v := kit.Int(ls[1]); v < 9 { @@ -23,6 +25,64 @@ func _status_tags(m *ice.Message, tags string) string { } return "v0.0.1" } +func _status_tags(m *ice.Message) { + vs := map[string]string{} + m.Cmd(STATUS).Table(func(index int, value map[string]string, head []string) { + if value[kit.MDB_TYPE] == "##" { + if value[kit.MDB_NAME] == ice.RELEASE { + value[kit.MDB_NAME] = ice.ICE + } + vs[value[kit.MDB_NAME]] = strings.Split(value[TAGS], "-")[0] + } + }) + + m.GoToast(TAGS, func(toast func(string, int, int)) { + count, total := 0, len(vs) + toast(cli.BEGIN, count, total) + + for k := range vs { + count++ + toast(k, count, total) + + if k == ice.ICE { + k = ice.RELEASE + } + + change := false + m.Option(nfs.CAT_LOCAL, ice.TRUE) + m.Option(nfs.DIR_ROOT, _repos_path(k)) + mod := m.Cmdx(nfs.CAT, ice.GO_MOD, func(text string, line int) string { + ls := kit.Split(strings.TrimPrefix(text, ice.REQUIRE)) + if len(ls) < 2 || !strings.Contains(ls[0], ice.PS) || !strings.Contains(ls[1], ice.PT) { + return text + } + if v, ok := vs[kit.Slice(strings.Split(ls[0], ice.PT), -1)[0]]; ok && ls[1] != v { + m.Debug("upgrade to %v %v from %v", ls[0], ls[1], v) + text = ice.TB + ls[0] + ice.SP + v + change = true + } + return text + }) + + if !change || mod == "" { + continue + } + + m.Cmd(nfs.SAVE, ice.GO_SUM, "") + m.Cmd(nfs.SAVE, ice.GO_MOD, mod) + m.Option(cli.CMD_DIR, _repos_path(k)) + + switch k { + case ice.CONTEXTS: + defer m.Cmd(cli.SYSTEM, cli.MAKE) + case ice.ICEBERGS: + m.Cmd(cli.SYSTEM, code.GO, cli.BUILD) + default: + m.Cmd(cli.SYSTEM, cli.MAKE) + } + } + }) +} func _status_each(m *ice.Message, title string, cmds ...string) { m.GoToast(title, func(toast func(string, int, int)) { count, total := 0, len(m.Confm(REPOS, kit.MDB_HASH)) @@ -33,22 +93,22 @@ func _status_each(m *ice.Message, title string, cmds ...string) { toast(value[kit.MDB_NAME], count, total) if msg := m.Cmd(cmds, ice.Option{cli.CMD_DIR, value[kit.MDB_PATH]}); !cli.IsSuccess(msg) { - m.Toast(msg.Append(cli.CMD_ERR), "error: "+value[kit.MDB_NAME], "3s") + m.Toast3s(msg.Append(cli.CMD_ERR), "error: "+value[kit.MDB_NAME]) list = append(list, value[kit.MDB_NAME]) - m.Sleep("3s") + m.Sleep3s() } count++ }) if len(list) > 0 { - m.Toast(strings.Join(list, ice.NL), ice.FAILURE, "30s") + m.Toast30s(strings.Join(list, ice.NL), ice.FAILURE) } else { toast(ice.SUCCESS, count, total) } }) } func _status_stat(m *ice.Message, files, adds, dels int) (int, int, int) { - for _, v := range kit.Split(m.Cmdx(cli.SYSTEM, GIT, DIFF, "--shortstat"), ",", ",") { + for _, v := range kit.Split(m.Cmdx(cli.SYSTEM, GIT, DIFF, "--shortstat"), ice.FS, ice.FS) { n := kit.Int(kit.Split(strings.TrimSpace(v))[0]) switch { case strings.Contains(v, "file"): @@ -137,72 +197,18 @@ func init() { STATUS: {Name: "status name auto", Help: "状态机", Action: map[string]*ice.Action{ PULL: {Name: "pull", Help: "下载", Hand: func(m *ice.Message, arg ...string) { _status_each(m, PULL, cli.SYSTEM, GIT, PULL) - m.ProcessHold() + m.ProcessRefresh30ms() }}, MAKE: {Name: "make", Help: "编译", Hand: func(m *ice.Message, arg ...string) { - m.Toast(ice.PROCESS, MAKE, "30s") - defer m.Toast(ice.SUCCESS, MAKE, "3s") + web.PushStream(m) m.Cmdy(cli.SYSTEM, MAKE) + m.Toast(ice.SUCCESS) + m.ProcessHold() }}, TAGS: {Name: "tags", Help: "标签", Hand: func(m *ice.Message, arg ...string) { - vs := map[string]string{} - m.Cmd(STATUS).Table(func(index int, value map[string]string, head []string) { - if value[kit.MDB_TYPE] == "##" { - if value[kit.MDB_NAME] == "release" { - value[kit.MDB_NAME] = "ice" - } - - vs[value[kit.MDB_NAME]] = strings.Split(value[TAGS], "-")[0] - } - }) - + _status_tags(m) + m.Toast(ice.SUCCESS) m.ProcessHold() - m.GoToast(TAGS, func(toast func(string, int, int)) { - count, total := 0, len(vs) - toast(cli.BEGIN, count, total) - - for k := range vs { - count++ - toast(k, count, total) - - if k == "ice" { - k = "release" - } - - change := false - m.Option(nfs.CAT_LOCAL, ice.TRUE) - m.Option(nfs.DIR_ROOT, _repos_path(k)) - mod := m.Cmdx(nfs.CAT, ice.GO_MOD, func(text string, line int) string { - ls := kit.Split(strings.TrimPrefix(text, "require")) - if len(ls) < 2 || !strings.Contains(ls[0], "/") || !strings.Contains(ls[1], ".") { - return text - } - if v, ok := vs[kit.Slice(strings.Split(ls[0], "/"), -1)[0]]; ok && ls[1] != v { - m.Debug("upgrade to %v %v from %v", ls[0], ls[1], v) - text = ice.TB + ls[0] + ice.SP + v - change = true - } - return text - }) - - if !change || mod == "" { - continue - } - - m.Cmd(nfs.SAVE, ice.GO_SUM, "") - m.Cmd(nfs.SAVE, ice.GO_MOD, mod) - m.Option(cli.CMD_DIR, _repos_path(k)) - - switch k { - case ice.CONTEXTS: - case ice.ICEBERGS: - m.Cmd(cli.SYSTEM, "go", "build") - default: - m.Cmd(cli.SYSTEM, cli.MAKE) - } - } - toast(ice.SUCCESS, count, total) - }) }}, PUSH: {Name: "push", Help: "上传", Hand: func(m *ice.Message, arg ...string) { if m.Option(kit.MDB_NAME) == "" { @@ -211,20 +217,19 @@ func init() { return } - m.Cmdy(cli.SYSTEM, GIT, PUSH, ice.Option{cli.CMD_DIR, _repos_path(m.Option(kit.MDB_NAME))}) - m.Cmdy(cli.SYSTEM, GIT, PUSH, "--tags") + _repos_cmd(m, m.Option(kit.MDB_NAME), PUSH) + _repos_cmd(m, m.Option(kit.MDB_NAME), PUSH, "--tags") }}, TAG: {Name: "tag version@key", Help: "标签", Hand: func(m *ice.Message, arg ...string) { if m.Option(VERSION) == "" { - m.Option(VERSION, _status_tags(m, m.Option(TAGS))) + m.Option(VERSION, _status_tag(m, m.Option(TAGS))) } - m.Option(cli.CMD_DIR, _repos_path(m.Option(kit.MDB_NAME))) - m.Cmdy(cli.SYSTEM, GIT, TAG, m.Option(VERSION)) - m.Cmdy(cli.SYSTEM, GIT, PUSH, "--tags") + _repos_cmd(m, m.Option(kit.MDB_NAME), TAG, m.Option(VERSION)) + _repos_cmd(m, m.Option(kit.MDB_NAME), PUSH, "--tags") }}, ADD: {Name: "add", Help: "添加", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(cli.SYSTEM, GIT, ADD, m.Option(kit.MDB_FILE), ice.Option{cli.CMD_DIR, _repos_path(m.Option(kit.MDB_NAME))}) + _repos_cmd(m, m.Option(kit.MDB_NAME), ADD, m.Option(kit.MDB_FILE)) }}, OPT: {Name: "opt", Help: "优化"}, PRO: {Name: "pro", Help: "升级"}, COMMIT: {Name: "commit action=opt,add,pro comment=some@key", Help: "提交", Hand: func(m *ice.Message, arg ...string) { if arg[0] == ctx.ACTION { @@ -233,7 +238,7 @@ func init() { m.Option(kit.MDB_TEXT, kit.Select("opt some", strings.Join(arg, ice.SP))) } - m.Cmdy(cli.SYSTEM, GIT, COMMIT, "-am", m.Option(kit.MDB_TEXT), ice.Option{cli.CMD_DIR, _repos_path(m.Option(kit.MDB_NAME))}) + _repos_cmd(m, m.Option(kit.MDB_NAME), COMMIT, "-am", m.Option(kit.MDB_TEXT)) m.ProcessBack() }}, mdb.INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) { @@ -243,9 +248,9 @@ func init() { case TAGS, VERSION: if m.Option(TAGS) == ice.ErrWarn { - m.Push(VERSION, kit.Format("v0.0.%d", 1)) + m.Push(VERSION, "v0.0.1") } else { - m.Push(VERSION, _status_tags(m, m.Option(TAGS))) + m.Push(VERSION, _status_tag(m, m.Option(TAGS))) } case COMMENT: @@ -261,7 +266,7 @@ func init() { files, adds, dels, last := _status_list(m) m.Status("files", files, "adds", adds, "dels", dels, "last", last.Format(ice.MOD_TIME)) - m.Toast(kit.Format("files: %d, adds: %d, dels: %d", files, adds, dels), ice.CONTEXTS, "3s") + m.Toast3s(kit.Format("files: %d, adds: %d, dels: %d", files, adds, dels), ice.CONTEXTS) return } @@ -271,7 +276,7 @@ func init() { files, adds, dels := _status_stat(m, 0, 0, 0) m.Status("files", files, "adds", adds, "dels", dels) - m.Toast(kit.Format("files: %d, adds: %d, dels: %d", files, adds, dels), arg[0], "3s") + m.Toast3s(kit.Format("files: %d, adds: %d, dels: %d", files, adds, dels), arg[0]) }}, }}) } diff --git a/misc/git/total.go b/misc/git/total.go index 4677e7b0..aa91a187 100644 --- a/misc/git/total.go +++ b/misc/git/total.go @@ -2,12 +2,14 @@ package git import ( "os" + "path" "strings" "sync" "time" ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/cli" + "shylinux.com/x/icebergs/base/nfs" kit "shylinux.com/x/toolkits" ) @@ -21,8 +23,10 @@ func init() { }, Commands: map[string]*ice.Command{ TOTAL: {Name: "total name auto", Help: "统计量", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if len(arg) > 0 { // 提交详情 - m.Richs(REPOS, nil, arg[0], func(key string, value map[string]interface{}) { - m.Cmdy("_sum", kit.Value(value, kit.META_PATH), arg[1:]) + m.Cmd(REPOS, ice.OptionFields("name,path")).Table(func(index int, value map[string]string, head []string) { + if value[kit.MDB_NAME] == arg[0] { + m.Cmdy("_sum", value[nfs.PATH], arg[1:]) + } }) return } @@ -31,11 +35,11 @@ func init() { days, commit, adds, dels, rest := 0, 0, 0, 0, 0 m.Richs(REPOS, nil, kit.MDB_FOREACH, func(mu *sync.Mutex, key string, value map[string]interface{}) { value = kit.GetMeta(value) - if m.Conf(TOTAL, kit.Keym("skip", value[kit.MDB_NAME])) == ice.TRUE { + if m.Config(kit.Keys("skip", value[kit.MDB_NAME])) == ice.TRUE { return } - msg := m.Cmd("_sum", value[kit.MDB_PATH], "total", "10000") + msg := m.Cmd("_sum", value[kit.MDB_PATH], kit.MDB_TOTAL, "10000") mu.Lock() defer mu.Unlock() @@ -50,7 +54,7 @@ func init() { rest += kit.Int(value["rest"]) }) - m.Push("name", value[kit.MDB_NAME]) + m.Push(kit.MDB_NAME, value[kit.MDB_NAME]) m.Copy(msg) }) @@ -66,24 +70,21 @@ func init() { }}, "_sum": {Name: "_sum [path] [total] [count|date] args...", Help: "统计量", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if len(arg) > 0 { - if s, e := os.Stat(arg[0] + "/.git"); e == nil && s.IsDir() { + if s, e := os.Stat(path.Join(arg[0], ".git")); e == nil && s.IsDir() { m.Option(cli.CMD_DIR, arg[0]) arg = arg[1:] - } else if s, e := os.Stat(arg[0] + "/refs"); e == nil && s.IsDir() { + } else if s, e := os.Stat(path.Join(arg[0], "refs")); e == nil && s.IsDir() { m.Option(cli.CMD_DIR, arg[0]) arg = arg[1:] } } - total := false - if len(arg) > 0 && arg[0] == "total" { + total := false // 累积求和 + if len(arg) > 0 && arg[0] == kit.MDB_TOTAL { total, arg = true, arg[1:] } - args := []string{} - args = append(args, "log", - // kit.Format("--author=%s\\|shylinux", m.Option(ice.MSG_USERNAME)), - "--shortstat", "--pretty=commit: %ad %n%s", "--date=iso", "--reverse") + args := []string{"log", "--shortstat", "--pretty=commit: %ad %n%s", "--date=iso", "--reverse"} if len(arg) > 0 { if strings.Contains(arg[0], "-") && !strings.Contains(arg[0], ":") { arg[0] = arg[0] + " 00:00:00" @@ -97,8 +98,8 @@ func init() { var total_day time.Duration count, count_add, count_del := 0, 0, 0 for i, v := range strings.Split(m.Cmdx(cli.SYSTEM, GIT, args), "commit: ") { - l := strings.Split(v, "\n") - hs := strings.Split(l[0], " ") + l := strings.Split(v, ice.NL) + hs := strings.Split(l[0], ice.SP) if len(l) < 2 { continue } @@ -106,8 +107,8 @@ func init() { add, del := "0", "0" if len(l) > 3 { fs := strings.Split(strings.TrimSpace(l[3]), ", ") - if adds := strings.Split(fs[1], " "); len(fs) > 2 { - dels := strings.Split(fs[2], " ") + if adds := strings.Split(fs[1], ice.SP); len(fs) > 2 { + dels := strings.Split(fs[2], ice.SP) add = adds[0] del = dels[0] } else if strings.Contains(adds[1], "insertion") { @@ -117,7 +118,7 @@ func init() { } } - if total { + if total { // 累积求和 if count++; i == 1 { if t, e := time.Parse("2006-01-02", hs[0]); e == nil { total_day = time.Now().Sub(t) @@ -138,7 +139,7 @@ func init() { m.Push("time", hs[1]) } - if total { + if total { // 累积求和 m.Push("tags", m.Cmdx(cli.SYSTEM, GIT, "describe", "--tags")) m.Push("days", int(total_day.Hours())/24) m.Push("commit", count) @@ -147,6 +148,5 @@ func init() { m.Push("rest", count_add-count_del) } }}, - }, - }) + }}) } diff --git a/misc/git/trend.go b/misc/git/trend.go index 8eb0075a..527a5ea7 100644 --- a/misc/git/trend.go +++ b/misc/git/trend.go @@ -12,13 +12,13 @@ const TREND = "trend" func init() { Index.Merge(&ice.Context{Commands: map[string]*ice.Command{ - TREND: {Name: "trend name@key begin_time@date auto", Help: "趋势图", Meta: kit.Dict( + TREND: {Name: "trend name begin_time@date auto", Help: "趋势图", Meta: kit.Dict( ice.Display("/plugin/story/trend.js"), - ), Action: map[string]*ice.Action{ + ), Action: ice.MergeAction(map[string]*ice.Action{ mdb.INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(REPOS, ice.OptionFields("name,time")) - }}, ctx.COMMAND: {Name: "ctx.command"}, code.INNER: {Name: "web.code.inner"}, - }, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + }}, code.INNER: {Name: "web.code.inner"}, + }, ctx.CmdAction()), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { if len(arg) == 0 { // 仓库列表 m.Cmdy(REPOS) return diff --git a/misc/tmux/tmux.go b/misc/tmux/tmux.go index 2c78ddef..6795afc6 100644 --- a/misc/tmux/tmux.go +++ b/misc/tmux/tmux.go @@ -15,7 +15,7 @@ var Index = &ice.Context{Name: TMUX, Help: "工作台", Configs: map[string]*ice cli.SOURCE, "http://mirrors.tencent.com/macports/distfiles/tmux/tmux-3.2.tar.gz", )}, }, Commands: map[string]*ice.Command{ - TMUX: {Name: "tmux session window auto start order build download", Help: "服务", Action: ice.MergeAction(map[string]*ice.Action{ + TMUX: {Name: "tmux path auto start order build download", Help: "服务", Action: ice.MergeAction(map[string]*ice.Action{ cli.START: {Name: "start", Help: "启动", Hand: func(m *ice.Message, arg ...string) { m.Optionv(code.PREPARE, func(p string) []string { return []string{"-S", kit.Path(m.Option(cli.CMD_DIR, p), "tmux.socket"), "new-session", "-dn", "miss"} @@ -23,7 +23,7 @@ var Index = &ice.Context{Name: TMUX, Help: "工作台", Configs: map[string]*ice m.Cmdy(code.INSTALL, cli.START, m.Config(cli.SOURCE), "bin/tmux") }}, }, code.InstallAction()), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { - m.Cmdy(SESSION, arg) + m.Cmdy(code.INSTALL, cli.SOURCE, m.Config(cli.SOURCE), arg) }}, }} diff --git a/misc/vim/favor.go b/misc/vim/favor.go index df2ffa34..ad2ae93a 100644 --- a/misc/vim/favor.go +++ b/misc/vim/favor.go @@ -2,6 +2,7 @@ package vim import ( "path" + "unicode" ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/mdb" @@ -19,6 +20,37 @@ func init() { )}, }, Commands: map[string]*ice.Command{ + "/tags": {Name: "/tags", Help: "跳转", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { + pre := m.Option("pre") + for i := kit.Int(m.Option("col")); i > 0; i-- { + if i > 0 && (pre[i] == '_' || pre[i] == '.' || unicode.IsDigit(rune(pre[i])) || unicode.IsLetter(rune(pre[i]))) { + continue + } + m.Debug("what %v", pre[i+1:kit.Int(m.Option("col"))]) + pre = pre[i+1 : kit.Int(m.Option("col"))] + break + } + + switch file := kit.Slice(kit.Split(pre, ".", "."), -2)[0]; file { + case "kit", "ice", "ctx", "chat", "html", "lang": + m.Echo("4\n%s\n/%s: /\n", "usr/volcanos/proto.js", m.Option("pattern")) + case "msg": + m.Echo("4\nusr/volcanos/lib/%s.js\n/%s: \\(shy\\|func\\)/\n", "misc", m.Option("pattern")) + case "base", "core", "misc", "page", "user": + m.Echo("4\nusr/volcanos/lib/%s.js\n/%s: \\(shy\\|func\\)/\n", file, m.Option("pattern")) + case "onengine", "ondaemon", "onappend", "onlayout", "onmotion", "onkeypop": + m.Echo("4\n%s\n/%s: \\(shy\\|func\\)/\n", "usr/volcanos/frame.js", m.Option("pattern")) + case "onimport", "onaction", "onexport": + m.Echo("4\n%s\n/%s: \\(shy\\|func\\)/\n", m.Option("buf"), m.Option("pattern")) + default: + switch m.Option("pattern") { + case "require", "request", "get", "set": + m.Echo("4\n%s\n/%s: \\(shy\\|func\\)/\n", "usr/volcanos/proto.js", m.Option("pattern")) + default: + m.Echo("4\n%s\n/%s: \\(shy\\|func\\)/\n", "usr/volcanos/frame.js", m.Option("pattern")) + } + } + }}, "/favor": {Name: "/favor", Help: "收藏", Action: map[string]*ice.Action{ mdb.SELECT: {Name: "select", Help: "主题", Hand: func(m *ice.Message, arg ...string) { m.Cmd(FAVOR).Table(func(index int, value map[string]string, head []string) { diff --git a/misc/vim/input.go b/misc/vim/input.go index 8e96f559..fc0f79ab 100644 --- a/misc/vim/input.go +++ b/misc/vim/input.go @@ -6,6 +6,7 @@ import ( ice "shylinux.com/x/icebergs" "shylinux.com/x/icebergs/base/cli" "shylinux.com/x/icebergs/base/mdb" + "shylinux.com/x/icebergs/core/code" kit "shylinux.com/x/toolkits" ) @@ -43,6 +44,15 @@ func init() { return } } + switch kit.Ext(m.Option("buf")) { + case code.JS: + switch arg[0] { + case "core": + m.Echo(arg[0] + ".Timer()" + ice.NL) + m.Echo(arg[0] + ".Timer300ms()" + ice.NL) + return + } + } // 词汇列表 m.Cmd("web.code.input.wubi", "word", arg[0]).Table(func(index int, value map[string]string, head []string) { diff --git a/option.go b/option.go index 9e0e33aa..e3112a46 100644 --- a/option.go +++ b/option.go @@ -130,13 +130,19 @@ func (m *Message) Toast(text string, arg ...interface{}) { // [title [duration [ m.Option(MSG_TOAST, kit.Simple(text, arg)) } } +func (m *Message) Toast3s(text string, arg ...interface{}) { + m.Toast(text, kit.List(kit.Select("", arg, 0), kit.Select("3s", arg, 1))...) +} +func (m *Message) Toast30s(text string, arg ...interface{}) { + m.Toast(text, kit.List(kit.Select("", arg, 0), kit.Select("30s", arg, 1))...) +} func (m *Message) GoToast(title string, cb func(toast func(string, int, int))) { m.Go(func() { cb(func(name string, count, total int) { m.Toast( kit.Format("%s %s/%s", name, strings.TrimSuffix(kit.FmtSize(int64(count)), "B"), strings.TrimSuffix(kit.FmtSize(int64(total)), "B")), kit.Format("%s %d%%", title, count*100/total), - kit.Select("1000", "10000", count < total), + kit.Select("3000", "30000", count < total), count*100/total, ) }) diff --git a/type.go b/type.go index 894cdd21..868b85f5 100644 --- a/type.go +++ b/type.go @@ -302,6 +302,8 @@ func (m *Message) Spawn(arg ...interface{}) *Message { json.Unmarshal(val, &msg.meta) case *Context: msg.target = val + case Option: + msg.Option(val.Name, val.Value) } } return msg