1
0
forked from x/icebergs
This commit is contained in:
harveyshao 2021-11-05 07:49:52 +08:00
parent d0dd7c7e68
commit b41437274f
24 changed files with 291 additions and 187 deletions

View File

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

View File

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

View File

@ -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
}
}
// 主页接口

View File

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

View File

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

View File

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

View File

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

View File

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

2
go.sum
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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(`<meta name="%s" content="%s">`, "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]))

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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