1
0
forked from x/icebergs
This commit is contained in:
IT 老营长 @云轩领航-创始人 2023-10-09 20:21:37 +08:00
parent a908aaaa72
commit 2b4b3e16b2
23 changed files with 420 additions and 537 deletions

View File

@ -143,6 +143,7 @@ const (
USR_PORTAL = ice.USR_PORTAL USR_PORTAL = ice.USR_PORTAL
USR_PUBLISH = ice.USR_PUBLISH USR_PUBLISH = ice.USR_PUBLISH
USR_LOCAL_WORK = ice.USR_LOCAL_WORK USR_LOCAL_WORK = ice.USR_LOCAL_WORK
USR_ICEBERGS = ice.USR_ICEBERGS
SRC_DOCUMENT = ice.SRC_DOCUMENT SRC_DOCUMENT = ice.SRC_DOCUMENT
SRC_TEMPLATE = ice.SRC_TEMPLATE SRC_TEMPLATE = ice.SRC_TEMPLATE
REQUIRE = "/require/" REQUIRE = "/require/"

View File

@ -301,7 +301,7 @@ func init() {
func DreamAction() ice.Actions { func DreamAction() ice.Actions {
return ice.MergeActions(ice.Actions{ return ice.MergeActions(ice.Actions{
DREAM_ACTION: {Hand: func(m *ice.Message, arg ...string) { DreamProcess(m, []string{}, arg...) }}, DREAM_ACTION: {Hand: func(m *ice.Message, arg ...string) { DreamProcess(m, []string{}, arg...) }},
}, gdb.EventsAction(DREAM_OPEN, DREAM_CLOSE, DREAM_INPUTS, DREAM_CREATE, DREAM_TABLES, DREAM_ACTION)) }, gdb.EventsAction(DREAM_OPEN, DREAM_CLOSE, DREAM_INPUTS, DREAM_CREATE, DREAM_TRASH, DREAM_TABLES, DREAM_ACTION))
} }
func DreamProcess(m *ice.Message, args ice.Any, arg ...string) { func DreamProcess(m *ice.Message, args ice.Any, arg ...string) {
if kit.HasPrefixList(arg, ctx.RUN) { if kit.HasPrefixList(arg, ctx.RUN) {

View File

@ -160,6 +160,7 @@ const (
CODE_GIT_REPOS = "web.code.git.repos" CODE_GIT_REPOS = "web.code.git.repos"
CODE_COMPILE = "web.code.compile" CODE_COMPILE = "web.code.compile"
CODE_UPGRADE = "web.code.upgrade" CODE_UPGRADE = "web.code.upgrade"
CODE_PUBLISH = "web.code.publish"
CODE_VIMER = "web.code.vimer" CODE_VIMER = "web.code.vimer"
CODE_INNER = "web.code.inner" CODE_INNER = "web.code.inner"
CODE_XTERM = "web.code.xterm" CODE_XTERM = "web.code.xterm"

View File

@ -102,7 +102,7 @@ func init() {
}}, }},
}, aaa.RoleAction()), Hand: func(m *ice.Message, arg ...string) { }, aaa.RoleAction()), Hand: func(m *ice.Message, arg ...string) {
if kit.HasPrefix(arg[0], "/volcanos/", "/require/", ice.HTTP) { if kit.HasPrefix(arg[0], "/volcanos/", "/require/", ice.HTTP) {
m.Echo(m.Cmdx(web.SPIDE, ice.DEV, web.SPIDE_RAW, http.MethodGet, arg[0])) m.Echo(m.Cmdx(web.SPIDE, ice.OPS, web.SPIDE_RAW, http.MethodGet, arg[0]))
m.Options("mode", "simple", lex.PARSE, kit.Ext(kit.ParseURL(arg[0]).Path)) m.Options("mode", "simple", lex.PARSE, kit.Ext(kit.ParseURL(arg[0]).Path))
ctx.DisplayLocal(m, "") ctx.DisplayLocal(m, "")
} else if arg[0] = strings.Split(arg[0], mdb.FS)[0]; !strings.HasSuffix(arg[0], nfs.PS) && len(arg) == 1 { } else if arg[0] = strings.Split(arg[0], mdb.FS)[0]; !strings.HasSuffix(arg[0], nfs.PS) && len(arg) == 1 {
@ -117,7 +117,9 @@ func init() {
} else { } else {
arg[1] = strings.Split(arg[1], mdb.FS)[0] arg[1] = strings.Split(arg[1], mdb.FS)[0]
_inner_list(m, kit.Ext(arg[1]), arg[1], arg[0]) _inner_list(m, kit.Ext(arg[1]), arg[1], arg[0])
ctx.DisplayLocal(m, "").Option(REPOS, kit.Join(m.Cmd(REPOS, ice.OptionFields(nfs.PATH)).Sort(nfs.PATH).Appendv(nfs.PATH))) if ctx.DisplayLocal(m, ""); !strings.HasPrefix(arg[0], ice.USR_INSTALL) {
m.Option(REPOS, kit.Join(m.Cmd(REPOS, ice.OptionFields(nfs.PATH)).Sort(nfs.PATH).Appendv(nfs.PATH)))
}
m.Status(mdb.TIME, ice.Info.Make.Time, nfs.FILE, arg[1], nfs.LINE, kit.Select("1", arg, 2), cli.BACK, "0") m.Status(mdb.TIME, ice.Info.Make.Time, nfs.FILE, arg[1], nfs.LINE, kit.Select("1", arg, 2), cli.BACK, "0")
} }
}}, }},

View File

@ -30,7 +30,8 @@ func _install_path(m *ice.Message, link string) string {
func _install_download(m *ice.Message) { func _install_download(m *ice.Message) {
link := m.Option(web.LINK) link := m.Option(web.LINK)
name := path.Base(kit.ParseURL(link).Path) name := path.Base(kit.ParseURL(link).Path)
file := path.Join(kit.Select(ice.USR_INSTALL, m.Option(nfs.PATH)), name) // file := path.Join(kit.Select(ice.USR_INSTALL, m.Option(nfs.PATH)), name)
file := path.Join(ice.USR_INSTALL, name)
defer m.Cmdy(nfs.DIR, file) defer m.Cmdy(nfs.DIR, file)
if nfs.Exists(m, file) { if nfs.Exists(m, file) {
return return
@ -190,7 +191,7 @@ func init() {
if m.Option(nfs.DIR_ROOT, path.Join(_install_path(m, ""), _INSTALL)); !nfs.Exists(m, m.Option(nfs.DIR_ROOT)) { if m.Option(nfs.DIR_ROOT, path.Join(_install_path(m, ""), _INSTALL)); !nfs.Exists(m, m.Option(nfs.DIR_ROOT)) {
m.Option(nfs.DIR_ROOT, path.Join(_install_path(m, ""))) m.Option(nfs.DIR_ROOT, path.Join(_install_path(m, "")))
} }
m.Cmdy(nfs.DIR, m.Option(nfs.PATH)).StatusTimeCount(nfs.PATH, m.Option(nfs.DIR_ROOT)) m.Cmdy(nfs.DIR, m.Option(nfs.PATH))
}}, }},
mdb.REMOVE: {Hand: func(m *ice.Message, arg ...string) { nfs.Trash(mdb.HashRemove(m), m.Option(nfs.PATH)) }}, mdb.REMOVE: {Hand: func(m *ice.Message, arg ...string) { nfs.Trash(mdb.HashRemove(m), m.Option(nfs.PATH)) }},
}, mdb.HashAction(mdb.SHORT, mdb.NAME, mdb.FIELD, "time,count,total,name,path,link")), Hand: func(m *ice.Message, arg ...string) { }, mdb.HashAction(mdb.SHORT, mdb.NAME, mdb.FIELD, "time,count,total,name,path,link")), Hand: func(m *ice.Message, arg ...string) {
@ -208,11 +209,20 @@ func init() {
func InstallAction(args ...ice.Any) ice.Actions { func InstallAction(args ...ice.Any) ice.Actions {
return ice.Actions{ice.CTX_INIT: mdb.AutoConfig(args...), return ice.Actions{ice.CTX_INIT: mdb.AutoConfig(args...),
web.DOWNLOAD: {Help: "下载", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(INSTALL, web.DOWNLOAD, mdb.Config(m, nfs.SOURCE)) }}, web.DOWNLOAD: {Help: "下载", Hand: func(m *ice.Message, arg ...string) {
cli.BUILD: {Help: "构建", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(INSTALL, cli.BUILD, mdb.Config(m, nfs.SOURCE)) }}, m.Cmdy(INSTALL, web.DOWNLOAD, mdb.Config(m, nfs.SOURCE))
}},
cli.BUILD: {Help: "构建", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(INSTALL, cli.BUILD, mdb.Config(m, nfs.SOURCE))
}},
cli.ORDER: {Help: "加载", Hand: func(m *ice.Message, arg ...string) { cli.ORDER: {Help: "加载", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(INSTALL, cli.ORDER, mdb.Config(m, nfs.SOURCE), path.Join(_INSTALL, ice.BIN)) m.Cmdy(INSTALL, cli.ORDER, mdb.Config(m, nfs.SOURCE), path.Join(_INSTALL, ice.BIN))
}}, }},
nfs.TRASH: {Hand: func(m *ice.Message, arg ...string) { nfs.Trash(m, m.Option(nfs.PATH)) }}, nfs.TRASH: {Hand: func(m *ice.Message, arg ...string) {
nfs.Trash(m, m.Option(nfs.PATH))
}},
mdb.SELECT: {Name: "select path auto order build download", Hand: func(m *ice.Message, arg ...string) {
m.Options(nfs.PATH, "").Cmdy(INSTALL, ctx.ConfigSimple(m, nfs.SOURCE), arg)
}},
} }
} }

View File

@ -2,7 +2,6 @@ package wiki
import ( import (
"net/http" "net/http"
"path"
ice "shylinux.com/x/icebergs" ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/aaa" "shylinux.com/x/icebergs/base/aaa"
@ -11,7 +10,6 @@ import (
"shylinux.com/x/icebergs/base/ssh" "shylinux.com/x/icebergs/base/ssh"
"shylinux.com/x/icebergs/base/web" "shylinux.com/x/icebergs/base/web"
"shylinux.com/x/icebergs/core/code" "shylinux.com/x/icebergs/core/code"
"shylinux.com/x/icebergs/misc/git"
kit "shylinux.com/x/toolkits" kit "shylinux.com/x/toolkits"
) )
@ -38,13 +36,9 @@ func init() {
WordAlias(m, SEQUENCE, CHART, SEQUENCE) WordAlias(m, SEQUENCE, CHART, SEQUENCE)
}}, }},
mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) { mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) {
m.Cmd(git.REPOS, ice.OptionFields(nfs.PATH)).Table(func(value ice.Maps) { m.Option(nfs.DIR_DEEP, ice.TRUE)
if m.Option(nfs.DIR_DEEP, ice.TRUE); kit.Path(value[nfs.PATH]) == kit.Path("") {
_wiki_list(m, nfs.SRC) _wiki_list(m, nfs.SRC)
} else { _wiki_list(m, nfs.USR_ICEBERGS)
_wiki_list(m, path.Join(value[nfs.PATH], nfs.SRC))
}
})
m.Cut("path,size,time") m.Cut("path,size,time")
}}, }},
code.COMPLETE: {Hand: func(m *ice.Message, arg ...string) { code.COMPLETE: {Hand: func(m *ice.Message, arg ...string) {

View File

@ -132,7 +132,7 @@ func MergeActions(arg ...Any) Actions {
h.Hand = MergeHand(v.Hand, h.Hand) h.Hand = MergeHand(v.Hand, h.Hand)
} else if k == CTX_EXIT { } else if k == CTX_EXIT {
h.Hand = MergeHand(h.Hand, v.Hand) h.Hand = MergeHand(h.Hand, v.Hand)
} else if h.Name = kit.Select(v.Name, h.Name); h.Hand == nil { } else if h.Name, h.Help = kit.Select(v.Name, h.Name), kit.Select(v.Help, h.Help); h.Hand == nil {
h.Hand = v.Hand h.Hand = v.Hand
} }
} }

22
misc/git/client.go Normal file
View File

@ -0,0 +1,22 @@
package git
import (
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/cli"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
"shylinux.com/x/icebergs/core/code"
)
const CLIENT = "client"
func init() {
Index.MergeCommands(ice.Commands{
CLIENT: {Help: "代码库", Actions: ice.MergeActions(ice.Actions{
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")
}},
}, code.InstallAction(nfs.SOURCE, "http://mirrors.tencent.com/macports/distfiles/git-cinnabar/git-2.31.1.tar.gz"))},
})
}

View File

@ -1,12 +1,9 @@
package git package git
import ( import (
"strings"
ice "shylinux.com/x/icebergs" ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/lex" "shylinux.com/x/icebergs/base/lex"
"shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
kit "shylinux.com/x/toolkits" kit "shylinux.com/x/toolkits"
) )
@ -16,31 +13,20 @@ func _configs_list(m *ice.Message) *ice.Message {
kit.SplitKV(mdb.EQ, lex.NL, _configs_get(m, "--list"), func(text string, ls []string) { kit.SplitKV(mdb.EQ, lex.NL, _configs_get(m, "--list"), func(text string, ls []string) {
m.Push(mdb.NAME, ls[0]).Push(mdb.VALUE, ls[1]).PushButton(mdb.REMOVE) m.Push(mdb.NAME, ls[0]).Push(mdb.VALUE, ls[1]).PushButton(mdb.REMOVE)
}) })
return mdb.HashSelectValue(m, func(value ice.Maps) { m.Push("", value, kit.Split("name,value")).PushButton(mdb.CREATE) }) return mdb.HashSelectValue(m, func(value ice.Maps) {
} m.Push("", value, kit.Split("name,value")).PushButton(mdb.CREATE)
func _configs_read(m *ice.Message, p string) ice.Maps {
res, block := ice.Maps{}, ""
m.Cmd(nfs.CAT, p, func(text string) {
if strings.HasPrefix(text, "[") {
block = kit.Join(kit.Split(text, " []"), nfs.PT)
return
}
ls := kit.Split(text, " =")
res[kit.Keys(block, ls[0])] = ls[1]
}) })
return res
} }
const ( const (
CONFIG = "config"
USER_NAME = "user.name"
USER_EMAIL = "user.email" USER_EMAIL = "user.email"
USER_NAME = "user.name"
) )
const CONFIGS = "configs" const CONFIGS = "configs"
func init() { func init() {
Index.MergeCommands(ice.Commands{ Index.MergeCommands(ice.Commands{
CONFIGS: {Name: "configs name value auto create init", Help: "配置键", Actions: ice.MergeActions(ice.Actions{ CONFIGS: {Name: "configs name value auto", Help: "配置键", Actions: ice.MergeActions(ice.Actions{
ice.INIT: {Help: "初始化", Hand: func(m *ice.Message, arg ...string) { ice.INIT: {Help: "初始化", Hand: func(m *ice.Message, arg ...string) {
kit.For(mdb.Configv(m, ice.INIT), func(p string, v ice.Any) { kit.For(mdb.Configv(m, ice.INIT), func(p string, v ice.Any) {
kit.For(v, func(k string, v string) { _configs_set(m, kit.Keys(p, k), v) }) kit.For(v, func(k string, v string) { _configs_set(m, kit.Keys(p, k), v) })
@ -56,22 +42,22 @@ func init() {
}}, }},
mdb.MODIFY: {Hand: func(m *ice.Message, arg ...string) { mdb.MODIFY: {Hand: func(m *ice.Message, arg ...string) {
if arg[0] == mdb.VALUE { if arg[0] == mdb.VALUE {
mdb.HashRemove(m, m.Option(mdb.NAME))
_configs_set(m, m.Option(mdb.NAME), arg[1]) _configs_set(m, m.Option(mdb.NAME), arg[1])
mdb.HashRemove(m, m.Option(mdb.NAME))
} }
}}, }},
}, mdb.HashAction(mdb.SHORT, mdb.NAME, mdb.FIELD, "time,name,value", ice.INIT, kit.Dict( }, mdb.HashAction(mdb.SHORT, mdb.NAME, mdb.FIELD, "time,name,value", ice.INIT, kit.Dict(
"alias", kit.Dict("s", "status", "b", "branch", "l", "log --oneline --decorate"), "alias", kit.Dict("s", STATUS, "b", BRANCH, "l", "log --oneline --decorate"),
"push", kit.Dict("default", "simple"), "credential", kit.Dict("helper", "store"), "push", kit.Dict("default", "simple"), "credential", kit.Dict("helper", "store"),
"core", kit.Dict("quotepath", "false"), "color", kit.Dict("ui", "always"), "core", kit.Dict("quotepath", "false"), "color", kit.Dict("ui", "always"),
))), Hand: func(m *ice.Message, arg ...string) { ))), Hand: func(m *ice.Message, arg ...string) {
if len(arg) == 0 { if len(arg) == 0 {
_configs_list(m).StatusTimeCount() _configs_list(m).Action(mdb.CREATE, ice.INIT).StatusTimeCount()
} else if len(arg) == 1 { return
m.Echo(_configs_get(m, arg[0])) } else if len(arg) > 1 {
} else {
m.Echo(_configs_set(m, arg[0], arg[1])) m.Echo(_configs_set(m, arg[0], arg[1]))
} }
m.Echo(_configs_get(m, arg[0]))
}}, }},
}) })
} }

View File

@ -5,40 +5,24 @@ import (
ice "shylinux.com/x/icebergs" ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/cli" "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/nfs"
"shylinux.com/x/icebergs/base/web" "shylinux.com/x/icebergs/base/web"
"shylinux.com/x/icebergs/core/code" "shylinux.com/x/icebergs/core/code"
kit "shylinux.com/x/toolkits" kit "shylinux.com/x/toolkits"
) )
func _git_url(m *ice.Message, repos string) string {
return kit.MergeURL2(web.UserHost(m), "/x/"+path.Join(repos)+".git")
}
func _git_dir(arg ...string) string { return path.Join(path.Join(arg...), ".git") } func _git_dir(arg ...string) string { return path.Join(path.Join(arg...), ".git") }
func _git_cmd(m *ice.Message, arg ...string) *ice.Message { return m.Cmd(cli.SYSTEM, GIT, arg) } func _git_cmd(m *ice.Message, arg ...string) *ice.Message { return m.Cmd(cli.SYSTEM, GIT, arg) }
func _git_cmds(m *ice.Message, arg ...string) string { return _git_cmd(m, arg...).Results() } func _git_cmds(m *ice.Message, arg ...string) string { return _git_cmd(m, arg...).Results() }
func _git_tags(m *ice.Message) string { return _git_cmds(m, "describe", "--tags") } func _git_tags(m *ice.Message) string { return _git_cmds(m, "describe", "--tags") }
func _git_diff(m *ice.Message) string { return _git_cmds(m, DIFF, "--shortstat") } func _git_diff(m *ice.Message) string { return _git_cmds(m, DIFF, "--shortstat") }
func _git_status(m *ice.Message) string { return _git_cmds(m, STATUS, "-sb") } func _git_status(m *ice.Message) string { return _git_cmds(m, STATUS, "-sb") }
func _git_remote(m *ice.Message) string { func _git_remote(m *ice.Message) string { return _git_cmds(m, nfs.REMOTE, "get-url", nfs.ORIGIN) }
return _git_cmds(m, nfs.REMOTE, "get-url", nfs.ORIGIN)
}
const GIT = "git" const GIT = "git"
var Index = &ice.Context{Name: GIT, Help: "代码库", Commands: ice.Commands{ var Index = &ice.Context{Name: GIT, Help: "代码库"}
GIT: {Name: "git path auto order build download", Help: "代码库", Actions: ice.MergeActions(ice.Actions{
cli.ORDER: {Help: "加载", Hand: func(m *ice.Message, arg ...string) {
m.Cmd(code.INSTALL, cli.ORDER, mdb.Config(m, nfs.SOURCE), "_install/libexec/git-core")
m.Cmdy(code.INSTALL, cli.ORDER, mdb.Config(m, nfs.SOURCE), "_install/bin")
}},
}, code.InstallAction(nfs.SOURCE, "http://mirrors.tencent.com/macports/distfiles/git-cinnabar/git-2.31.1.tar.gz")), Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(code.INSTALL, ctx.ConfigSimple(m, nfs.SOURCE), arg)
}},
}}
func init() { code.Index.Register(Index, &web.Frame{}, REPOS) } func init() { code.Index.Register(Index, &web.Frame{}) }
func Prefix(arg ...string) string { return code.Prefix(GIT, kit.Keys(arg)) } func Prefix(arg ...string) string { return code.Prefix(GIT, kit.Keys(arg)) }

View File

@ -6,11 +6,11 @@ refer `
` `
chapter "源码" chapter "源码"
field "安装" web.code.git.git field "命令" web.code.git.client
field "源码" web.code.inner args `usr/install/git-2.31.1/ shell.c 145` field "源码" web.code.inner args `usr/install/git-2.31.1/ shell.c 145`
section "构建" section "构建"
shell ` shell centos `
yum install -y wget make gcc yum install -y wget make gcc
yum install -y libcurl-devel.x86_64 openssl-devel.x86_64 yum install -y libcurl-devel.x86_64 openssl-devel.x86_64
yum install -y perl-ExtUtils-CBuilder perl-ExtUtils-MakeMaker yum install -y perl-ExtUtils-CBuilder perl-ExtUtils-MakeMaker
@ -20,7 +20,13 @@ tar xvf git-2.31.1.tar.gz && cd git-2.31.1
./configure --prefix=$PWD/_install ./configure --prefix=$PWD/_install
make -j8 && make install make -j8 && make install
` ` macos `
curl -O http://mirrors.tencent.com/macports/distfiles/git-cinnabar/git-2.31.1.tar.gz
tar xvf git-2.31.1.tar.gz && cd git-2.31.1
./configure --prefix=$PWD/_install
make -j8 && make install
` windows ``
section "启动" section "启动"
shell ` shell `
@ -28,18 +34,33 @@ cd ./_install
./bin/git ./bin/git
` `
section `配置` section "配置"
shell ` shell `
git config --global user.email shylinux@163.com git config --global user.email shy@shylinux.com
git config --global user.name shylinux git config --global user.name shy
` `
chapter "应用" chapter "应用"
field "代码库" web.code.git.repos 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.configs
field "状态机" web.code.git.status field "状态机" web.code.git.status
field "服务器" web.code.git.server field "配置键" web.code.git.configs
field "服务器" web.code.git.service
field "代码源" web.code.git.search args `repos`
return
field "架构图" web.code.git.spide args `icebergs`
field "趋势图" web.code.git.trend args `icebergs`
field "代码行" web.code.git.count
field "统计量" web.code.git.total
repos.go
status.go
configs.go
service.go
search.go
search.js
search.css
search.shy
spide.go
trend.go
count.go
total.go

View File

@ -17,7 +17,6 @@ import (
"shylinux.com/x/icebergs/base/aaa" "shylinux.com/x/icebergs/base/aaa"
"shylinux.com/x/icebergs/base/cli" "shylinux.com/x/icebergs/base/cli"
"shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/ctx"
"shylinux.com/x/icebergs/base/gdb"
"shylinux.com/x/icebergs/base/lex" "shylinux.com/x/icebergs/base/lex"
"shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs" "shylinux.com/x/icebergs/base/nfs"
@ -26,47 +25,6 @@ import (
kit "shylinux.com/x/toolkits" kit "shylinux.com/x/toolkits"
) )
func _repos_cmd(m *ice.Message, p string, arg ...string) *ice.Message {
return m.Copy(_git_cmd(m.Options(cli.CMD_DIR, _repos_path(m, p)), arg...))
}
func _repos_init(m *ice.Message, p string) { git.PlainInit(p, true) }
func _repos_recent(m *ice.Message, repos *git.Repository) (r *plumbing.Reference) {
max := 0
if iter, err := repos.Tags(); err == nil {
for {
refer, err := iter.Next()
if err != nil {
break
}
ls := kit.Split(refer.Name().Short(), "v.")
if len(ls) < 2 {
continue
}
if n := kit.Int(ls[0])*1000000 + kit.Int(ls[1])*1000 + kit.Int(ls[2]); n > max {
max, r = n, refer
}
}
}
return
}
func _repos_forword(m *ice.Message, repos *git.Repository, version string) int {
if refer, err := repos.Head(); err == nil {
if commit, err := repos.CommitObject(refer.Hash()); err == nil {
n := 0
for {
if commit.Hash.String() == version {
break
}
if commit, err = commit.Parent(0); err != nil || commit == nil {
break
}
n++
}
return n
}
}
return 0
}
func _repos_insert(m *ice.Message, p string) { func _repos_insert(m *ice.Message, p string) {
if repos, err := git.PlainOpen(p); err == nil { if repos, err := git.PlainOpen(p); err == nil {
args := []string{REPOS, path.Base(p), nfs.PATH, p} args := []string{REPOS, path.Base(p), nfs.PATH, p}
@ -88,24 +46,48 @@ func _repos_insert(m *ice.Message, p string) {
} }
} }
func _repos_origin(m *ice.Message, repos *git.Repository) string { func _repos_origin(m *ice.Message, repos *git.Repository) string {
if remote, err := repos.Remote(ORIGIN); err == nil { if repos == nil {
return ""
} else if remote, err := repos.Remote(ORIGIN); err == nil {
return remote.Config().URLs[0] return remote.Config().URLs[0]
} else if remote, err := repos.Remotes(); err == nil && len(remote) > 0 { } else if remote, err := repos.Remotes(); err == nil && len(remote) > 0 {
return remote[0].Config().URLs[0] return remote[0].Config().URLs[0]
} } else {
return "" return ""
}
} }
func _repos_path(m *ice.Message, p string, arg ...string) string { func _repos_recent(m *ice.Message, repos *git.Repository) (r *plumbing.Reference) {
if p == path.Base(kit.Path("")) { max := 0
return kit.Path("", arg...) if iter, err := repos.Tags(); err == nil {
for {
if refer, err := iter.Next(); err != nil {
break
} else if ls := kit.Split(refer.Name().Short(), "v."); len(ls) < 2 {
continue
} else if n := kit.Int(ls[0])*1000000 + kit.Int(ls[1])*1000 + kit.Int(ls[2]); n > max {
max, r = n, refer
} }
if nfs.Exists(m, path.Join(nfs.USR, p, ".git")) {
return path.Join(nfs.USR, p, path.Join(arg...))
} }
if nfs.Exists(m, path.Join(nfs.USR_LOCAL_WORK, p, ".git")) {
return path.Join(nfs.USR_LOCAL_WORK, p, path.Join(arg...))
} }
return p return
}
func _repos_forword(m *ice.Message, repos *git.Repository, version string) int {
if refer, err := repos.Head(); err == nil {
if commit, err := repos.CommitObject(refer.Hash()); err == nil {
n := 0
for {
if commit.Hash.String() == version {
break
} else if commit, err = commit.Parent(0); err != nil || commit == nil {
break
} else {
n++
}
}
return n
}
}
return 0
} }
func _repos_open(m *ice.Message, p string) *git.Repository { func _repos_open(m *ice.Message, p string) *git.Repository {
return mdb.HashSelectTarget(m, p, nil).(*git.Repository) return mdb.HashSelectTarget(m, p, nil).(*git.Repository)
@ -130,11 +112,29 @@ 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) {
_repos_each(m, "", 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])
return cb(repos, remoteURL, _repos_auth(m, remoteURL), 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
})
return list
}
func _repos_auth(m *ice.Message, origin string) *http.BasicAuth { func _repos_auth(m *ice.Message, origin string) *http.BasicAuth {
list := _repos_credentials(m) list := _repos_credentials(m)
if insteadof := mdb.Config(m, INSTEADOF); insteadof != "" { origin = _repos_remote(m, origin)
origin = insteadof + path.Base(origin)
}
if u, ok := list[kit.ParseURL(origin).Host]; !ok { if u, ok := list[kit.ParseURL(origin).Host]; !ok {
return nil return nil
} else if password, ok := u.User.Password(); !ok { } else if password, ok := u.User.Password(); !ok {
@ -144,20 +144,17 @@ func _repos_auth(m *ice.Message, origin string) *http.BasicAuth {
return &http.BasicAuth{Username: u.User.Username(), Password: password} return &http.BasicAuth{Username: u.User.Username(), Password: password}
} }
} }
func _repos_each_origin(m *ice.Message, title string, cb func(*git.Repository, string, *http.BasicAuth, ice.Maps) error) {
_repos_each(m, "", func(repos *git.Repository, value ice.Maps) error { func _repos_path(m *ice.Message, p string, arg ...string) string {
if value[ORIGIN] == "" { if p == path.Base(kit.Path("")) {
return nil return kit.Path("", arg...)
} else if remote, err := repos.Remote(ORIGIN); err != nil { } else if nfs.Exists(m, path.Join(nfs.USR, p, ".git")) {
return err return path.Join(nfs.USR, p, path.Join(arg...))
} 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 { } else {
remoteURL := remote.Config().URLs[0] return p
if insteadof := mdb.Config(m, INSTEADOF); insteadof != "" {
remoteURL = insteadof + path.Base(remoteURL)
} }
return cb(repos, remoteURL, _repos_auth(m, remote.Config().URLs[0]), value)
}
})
} }
func _repos_branch(m *ice.Message, repos *git.Repository) error { func _repos_branch(m *ice.Message, repos *git.Repository) error {
iter, err := repos.Branches() iter, err := repos.Branches()
@ -176,6 +173,14 @@ func _repos_branch(m *ice.Message, repos *git.Repository) error {
}) })
return nil return nil
} }
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)
}
return remote
}
func _repos_log(m *ice.Message, hash plumbing.Hash, repos *git.Repository) error { func _repos_log(m *ice.Message, hash plumbing.Hash, repos *git.Repository) error {
iter, err := repos.Log(&git.LogOptions{From: hash}) iter, err := repos.Log(&git.LogOptions{From: hash})
if err != nil { if err != nil {
@ -205,24 +210,6 @@ func _repos_log(m *ice.Message, hash plumbing.Hash, repos *git.Repository) error
return nil return nil
}) })
} }
func _repos_stats(m *ice.Message, repos *git.Repository, h string) error {
commit, err := repos.CommitObject(plumbing.NewHash(h))
if err != nil {
return err
}
stats, err := commit.Stats()
if err != nil {
return err
}
adds, dels := 0, 0
for _, stat := range stats {
m.Push(nfs.FILE, stat.Name).Push("add", stat.Addition).Push("del", stat.Deletion)
adds += stat.Addition
dels += stat.Deletion
}
m.StatusTimeCount("adds", adds, "dels", dels)
return nil
}
func _repos_status(m *ice.Message, p string, repos *git.Repository) error { func _repos_status(m *ice.Message, p string, repos *git.Repository) error {
work, err := repos.Worktree() work, err := repos.Worktree()
if err != nil { if err != nil {
@ -275,32 +262,22 @@ func _repos_status(m *ice.Message, p string, repos *git.Repository) error {
} }
return nil return nil
} }
func _repos_total(m *ice.Message, p string, repos *git.Repository, stats map[string]int) *time.Time { func _repos_stats(m *ice.Message, repos *git.Repository, h string) error {
iter, err := repos.Log(&git.LogOptions{}) commit, err := repos.CommitObject(plumbing.NewHash(h))
if err != nil { if err != nil {
return nil return err
} }
from, cmts, adds, dels := time.Now(), 0, 0, 0 stats, err := commit.Stats()
iter.ForEach(func(commit *object.Commit) error { if err != nil {
from, cmts = commit.Author.When, cmts+1 return err
if stats, err := commit.Stats(); err == nil { }
adds, dels := 0, 0
for _, stat := range stats { for _, stat := range stats {
adds, dels = adds+stat.Addition, dels+stat.Deletion m.Push(nfs.FILE, stat.Name).Push("add", stat.Addition).Push("del", stat.Deletion)
} adds += stat.Addition
} dels += stat.Deletion
return nil
})
days := kit.Int(time.Now().Sub(from) / time.Hour / 24)
m.Push(REPOS, p).Push("from", from.Format(ice.MOD_TIME)).Push("days", days)
m.Push("commits", cmts).Push("adds", adds).Push("dels", dels).Push("rest", adds-dels)
stats["cmts"] += cmts
stats["adds"] += adds
stats["dels"] += dels
stats["rest"] += adds - dels
if days > stats["days"] {
stats["days"] = days
return &from
} }
m.StatusTimeCount("adds", adds, "dels", dels)
return nil return nil
} }
func _repos_inner(m *ice.Message, _repos_path func(m *ice.Message, p string, arg ...string) string, arg ...string) { func _repos_inner(m *ice.Message, _repos_path func(m *ice.Message, p string, arg ...string) string, arg ...string) {
@ -384,13 +361,51 @@ func _repos_inner(m *ice.Message, _repos_path func(m *ice.Message, p string, arg
} }
ctx.ProcessField(m, "", arg, arg...) ctx.ProcessField(m, "", arg, arg...)
} }
func _repos_credentials(m *ice.Message) map[string]*url.URL { func _repos_total(m *ice.Message, p string, repos *git.Repository, stats map[string]int) *time.Time {
list := map[string]*url.URL{} iter, err := repos.Log(&git.LogOptions{})
m.Cmd(nfs.CAT, kit.HomePath(".git-credentials"), func(line string) { if err != nil {
u := kit.ParseURL(strings.ReplaceAll(line, "%3a", ":")) return nil
list[u.Host] = u }
from, cmts, adds, dels := time.Now(), 0, 0, 0
iter.ForEach(func(commit *object.Commit) error {
from, cmts = commit.Author.When, cmts+1
if stats, err := commit.Stats(); err == nil {
for _, stat := range stats {
adds, dels = adds+stat.Addition, dels+stat.Deletion
}
}
return nil
}) })
return list days := kit.Int(time.Now().Sub(from) / time.Hour / 24)
m.Push(REPOS, p).Push("from", from.Format(ice.MOD_TIME)).Push("days", days)
m.Push("commits", cmts).Push("adds", adds).Push("dels", dels).Push("rest", adds-dels)
stats["cmts"] += cmts
stats["adds"] += adds
stats["dels"] += dels
stats["rest"] += adds - dels
if days > stats["days"] {
stats["days"] = days
return &from
}
return nil
}
func _repos_cmd(m *ice.Message, p string, arg ...string) *ice.Message {
return m.Copy(_git_cmd(m.Options(cli.CMD_DIR, _repos_path(m, p)), arg...))
}
func _status_tag(m *ice.Message, tags string) string {
if tags == "" {
return "v0.0.1"
}
ls := kit.Split(strings.TrimPrefix(kit.Split(tags, "-")[0], "v"), nfs.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 {
return kit.Format("v%v.%v.0", ls[0], v+1)
} else if v := kit.Int(ls[0]); v < 9 {
return kit.Format("v%v.0.0", v+1)
} else {
return "v0.0.1"
}
} }
const ( const (
@ -402,6 +417,7 @@ const (
TAG = "tag" TAG = "tag"
ADD = "add" ADD = "add"
STASH = "stash" STASH = "stash"
CONFIG = "config"
COMMIT = "commit" COMMIT = "commit"
BRANCH = "branch" BRANCH = "branch"
CHECKOUT = "checkout" CHECKOUT = "checkout"
@ -412,6 +428,17 @@ const (
INDEX = "index" INDEX = "index"
INSTEADOF = "insteadof" INSTEADOF = "insteadof"
) )
const (
GITEA = "gitea"
OAUTH = "oauth"
DIFF = "diff"
OPT = "opt"
FIX = "fix"
TAGS = "tags"
VERSION = "version"
COMMENT = "comment"
)
const REPOS = "repos" const REPOS = "repos"
func init() { func init() {
@ -433,9 +460,11 @@ func init() {
if p = path.Join(ice.USR_REQUIRE, path.Join(arg...)); !nfs.Exists(m, p) { if p = path.Join(ice.USR_REQUIRE, path.Join(arg...)); !nfs.Exists(m, p) {
ls := strings.SplitN(path.Join(arg[:3]...), mdb.AT, 2) ls := strings.SplitN(path.Join(arg[:3]...), mdb.AT, 2)
_, err := git.PlainClone(path.Join(ice.USR_REQUIRE, path.Join(arg[:3]...)), false, &git.CloneOptions{ _, err := git.PlainClone(path.Join(ice.USR_REQUIRE, path.Join(arg[:3]...)), false, &git.CloneOptions{
URL: "http://" + ls[0], Depth: 1, ReferenceName: plumbing.NewTagReferenceName(kit.Select(ice.Info.Gomod[ls[0]], ls, 1)), URL: "https://" + ls[0], Depth: 1, ReferenceName: plumbing.NewTagReferenceName(kit.Select(ice.Info.Gomod[ls[0]], ls, 1)),
}) })
m.Warn(err) if m.Warn(err) {
return
}
} }
} }
m.RenderDownload(p) m.RenderDownload(p)
@ -445,15 +474,25 @@ func init() {
Index.MergeCommands(ice.Commands{ Index.MergeCommands(ice.Commands{
REPOS: {Name: "repos repos branch:text commit:text file:text auto", Help: "代码库", Actions: ice.MergeActions(ice.Actions{ REPOS: {Name: "repos repos branch:text commit:text file:text auto", Help: "代码库", Actions: ice.MergeActions(ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
m.Cmd(nfs.DIR, nfs.USR_LOCAL_WORK, func(value ice.Maps) { _repos_insert(m, value[nfs.PATH]) })
m.Cmd(nfs.DIR, nfs.USR, func(value ice.Maps) { _repos_insert(m, value[nfs.PATH]) })
_repos_insert(m, kit.Path("")) _repos_insert(m, kit.Path(""))
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) { m.Cmd(CONFIGS, func(value ice.Maps) {
if strings.HasSuffix(value[mdb.NAME], ".insteadof") && strings.HasPrefix(ice.Info.Make.Remote, value[mdb.VALUE]) { 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.")) mdb.Config(m, INSTEADOF, strings.TrimPrefix(strings.TrimSuffix(value[mdb.NAME], ".insteadof"), "url."))
} }
}) })
}}, }},
INSTEADOF: {Name: "insteadof remote", Help: "代理", 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 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)))
}
}},
mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) { mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) {
switch arg[0] { switch arg[0] {
case COMMENT: case COMMENT:
@ -462,14 +501,14 @@ func init() {
m.Push(arg[0], kit.Join(kit.Slice(ls, -2), nfs.PS)) m.Push(arg[0], kit.Join(kit.Slice(ls, -2), nfs.PS))
m.Push(arg[0], m.Option(nfs.FILE)) m.Push(arg[0], m.Option(nfs.FILE))
case VERSION: case VERSION:
m.Push(VERSION, _status_tag(m, m.Option(TAGS))) m.Push(arg[0], _status_tag(m, m.Option(TAGS)))
} }
}}, }},
CLONE: {Name: "clone origin* branch name path", Help: "克隆", Hand: func(m *ice.Message, arg ...string) { CLONE: {Name: "clone origin* branch name path", Help: "克隆", Hand: func(m *ice.Message, arg ...string) {
m.OptionDefault(mdb.NAME, path.Base(m.Option(ORIGIN))) m.OptionDefault(mdb.NAME, path.Base(m.Option(ORIGIN)))
m.OptionDefault(nfs.PATH, path.Join(path.Join(nfs.USR, m.Option(mdb.NAME)))) m.OptionDefault(nfs.PATH, path.Join(nfs.USR, m.Option(mdb.NAME)))
defer m.Cmdy(nfs.DIR, m.Option(nfs.PATH)) defer m.Cmdy(nfs.DIR, m.Option(nfs.PATH))
if nfs.Exists(m, m.Option(nfs.PATH)) { if nfs.Exists(m, _git_dir(m.Option(nfs.PATH))) {
return return
} }
defer web.ToastProcess(m)() defer web.ToastProcess(m)()
@ -477,7 +516,7 @@ func init() {
_repos_insert(m, m.Option(nfs.PATH)) _repos_insert(m, m.Option(nfs.PATH))
} }
}}, }},
INIT: {Name: "clone origin* branch name path", Hand: func(m *ice.Message, arg ...string) { INIT: {Name: "clone origin* path", Hand: func(m *ice.Message, arg ...string) {
m.Cmd(nfs.DEFS, kit.Path(".git/config"), kit.Format(nfs.Template(m, "config"), m.Option(ORIGIN))) m.Cmd(nfs.DEFS, kit.Path(".git/config"), kit.Format(nfs.Template(m, "config"), m.Option(ORIGIN)))
git.PlainInit(m.Option(nfs.PATH), false) git.PlainInit(m.Option(nfs.PATH), false)
_repos_insert(m, kit.Path("")) _repos_insert(m, kit.Path(""))
@ -485,16 +524,16 @@ func init() {
}}, }},
PULL: {Help: "下载", Hand: func(m *ice.Message, arg ...string) { PULL: {Help: "下载", Hand: func(m *ice.Message, arg ...string) {
_repos_each_origin(m, "", func(repos *git.Repository, remoteURL string, auth *http.BasicAuth, value ice.Maps) error { _repos_each_origin(m, "", func(repos *git.Repository, remoteURL string, auth *http.BasicAuth, value ice.Maps) error {
work, err := repos.Worktree() if work, err := repos.Worktree(); err != nil {
if err != nil {
return err return err
} } else {
return work.Pull(&git.PullOptions{RemoteURL: remoteURL, Auth: auth}) return work.Pull(&git.PullOptions{RemoteURL: remoteURL, Auth: auth})
}
}) })
}}, }},
PUSH: {Help: "上传", Hand: func(m *ice.Message, arg ...string) { PUSH: {Help: "上传", Hand: func(m *ice.Message, arg ...string) {
_repos_each_origin(m, "", func(repos *git.Repository, remoteURL string, auth *http.BasicAuth, value ice.Maps) error { _repos_each_origin(m, "", func(repos *git.Repository, remoteURL string, auth *http.BasicAuth, value ice.Maps) error {
m.Cmd(cli.SYSTEM, GIT, PUSH, "--tags", kit.Dict(cli.CMD_DIR, path.Join(ice.USR_LOCAL_REPOS, value[REPOS]))) _git_cmd(m.Spawn(kit.Dict(cli.CMD_DIR, value[nfs.PATH])), PUSH, "--tags")
return repos.Push(&git.PushOptions{RemoteURL: remoteURL, Auth: auth, FollowTags: true}) return repos.Push(&git.PushOptions{RemoteURL: remoteURL, Auth: auth, FollowTags: true})
}) })
}}, }},
@ -507,9 +546,9 @@ func init() {
} }
}}, }},
TAG: {Name: "tag version", Hand: func(m *ice.Message, arg ...string) { TAG: {Name: "tag version", Hand: func(m *ice.Message, arg ...string) {
kit.If(m.Option(VERSION) == "", func() { m.Option(VERSION, _status_tag(m, m.Option(TAGS))) })
repos := _repos_open(m, m.Option(REPOS)) repos := _repos_open(m, m.Option(REPOS))
if refer, err := repos.Head(); !m.Warn(err) { if refer, err := repos.Head(); !m.Warn(err) {
kit.If(m.Option(VERSION) == "", func() { m.Option(VERSION, _status_tag(m, m.Option(TAGS))) })
_, err := repos.CreateTag(m.Option(VERSION), refer.Hash(), &git.CreateTagOptions{}) _, err := repos.CreateTag(m.Option(VERSION), refer.Hash(), &git.CreateTagOptions{})
m.Warn(err) m.Warn(err)
} }
@ -520,7 +559,9 @@ func init() {
m.Warn(err) m.Warn(err)
} }
}}, }},
STASH: {Hand: func(m *ice.Message, arg ...string) { _repos_cmd(m, kit.Select(m.Option(REPOS), arg, 0), STASH) }}, STASH: {Hand: func(m *ice.Message, arg ...string) {
_repos_cmd(m, kit.Select(m.Option(REPOS), arg, 0), STASH)
}},
CHECKOUT: {Help: "恢复", Hand: func(m *ice.Message, arg ...string) { CHECKOUT: {Help: "恢复", Hand: func(m *ice.Message, arg ...string) {
_git_cmd(m.Options(nfs.DIR_ROOT, mdb.HashSelectField(m, m.Option(REPOS), nfs.PATH)), CHECKOUT, m.Option(nfs.FILE)) _git_cmd(m.Options(nfs.DIR_ROOT, mdb.HashSelectField(m, m.Option(REPOS), nfs.PATH)), CHECKOUT, m.Option(nfs.FILE))
}}, }},
@ -529,10 +570,9 @@ func init() {
opt := &git.CommitOptions{All: true} opt := &git.CommitOptions{All: true}
if cfg, err := config.LoadConfig(config.GlobalScope); err == nil { if cfg, err := config.LoadConfig(config.GlobalScope); err == nil {
if cfg.Author.Email == "" || cfg.Author.Name == "" { if cfg.Author.Email == "" || cfg.Author.Name == "" {
opt.Author = &object.Signature{ opt.Author = &object.Signature{When: time.Now(),
Email: kit.Select(m.Option(ice.MSG_USERNAME)+"@shylinux.com", mdb.Config(m, aaa.EMAIL)),
Name: kit.Select(m.Option(ice.MSG_USERNAME), mdb.Config(m, aaa.USERNAME)), Name: kit.Select(m.Option(ice.MSG_USERNAME), mdb.Config(m, aaa.USERNAME)),
When: time.Now(), Email: kit.Select(m.Option(ice.MSG_USERNAME)+"@shylinux.com", mdb.Config(m, aaa.EMAIL)),
} }
} }
} }
@ -558,18 +598,14 @@ func init() {
if repos, ok := mdb.HashSelectTarget(m, path.Base(kit.Path("")), nil).(*git.Repository); ok { if repos, ok := mdb.HashSelectTarget(m, path.Base(kit.Path("")), nil).(*git.Repository); ok {
remote = kit.Select(remote, _repos_origin(m, repos)) remote = kit.Select(remote, _repos_origin(m, repos))
} }
if insteadof := mdb.Config(m, INSTEADOF); insteadof != "" { remote = _repos_remote(m, remote)
remote = insteadof + path.Base(remote)
}
if u, ok := list[kit.ParseURL(remote).Host]; ok { if u, ok := list[kit.ParseURL(remote).Host]; ok {
password, _ = u.User.Password() password, _ = u.User.Password()
} }
m.Sort("repos,status,file").Status( m.Sort("repos,status,file").Status(mdb.TIME, last,
mdb.TIME, last,
REMOTE, remote, VERSION, ice.Info.Make.Versions(), REMOTE, remote, VERSION, ice.Info.Make.Versions(),
kit.Select(aaa.TECH, aaa.VOID, password == ""), m.Option(aaa.EMAIL), kit.Select(aaa.TECH, aaa.VOID, password == ""), m.Option(aaa.EMAIL),
kit.MDB_COUNT, kit.Split(m.FormatSize())[0], kit.MDB_COUNT, kit.Split(m.FormatSize())[0], kit.MDB_COST, m.FormatCost(),
kit.MDB_COST, m.FormatCost(),
) )
} }
}}, }},
@ -598,25 +634,8 @@ func init() {
} }
m.StatusTimeCount() m.StatusTimeCount()
}}, }},
INSTEADOF: {Name: "insteadof remote", Help: "代理", 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 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)))
}
}},
"remoteURL": {Hand: func(m *ice.Message, arg ...string) { "remoteURL": {Hand: func(m *ice.Message, arg ...string) {
remoteURL := "" m.Echo(_repos_remote(m, _repos_origin(m, _repos_open(m, path.Base(kit.Path(""))))))
if repos, ok := mdb.HashSelectTarget(m, path.Base(kit.Path("")), nil).(*git.Repository); ok {
remoteURL = kit.Select(remoteURL, _repos_origin(m, repos))
}
if insteadof := mdb.Config(m, INSTEADOF); insteadof != "" {
remoteURL = insteadof + path.Base(remoteURL)
}
m.Echo(remoteURL)
}}, }},
REMOTE: {Hand: func(m *ice.Message, arg ...string) { REMOTE: {Hand: func(m *ice.Message, arg ...string) {
repos := _repos_open(m, kit.Select(path.Base(kit.Path("")), kit.Select(m.Option(REPOS), arg, 0))) repos := _repos_open(m, kit.Select(path.Base(kit.Path("")), kit.Select(m.Option(REPOS), arg, 0)))
@ -671,9 +690,9 @@ func init() {
}}, }},
web.DREAM_ACTION: {Hand: func(m *ice.Message, arg ...string) { web.DreamProcess(m, []string{}, arg...) }}, web.DREAM_ACTION: {Hand: func(m *ice.Message, arg ...string) { web.DreamProcess(m, []string{}, arg...) }},
code.INNER: {Hand: func(m *ice.Message, arg ...string) { _repos_inner(m, _repos_path, arg...) }}, code.INNER: {Hand: func(m *ice.Message, arg ...string) { _repos_inner(m, _repos_path, arg...) }},
}, aaa.RoleAction(REMOTE), gdb.EventsAction(web.DREAM_CREATE, web.DREAM_TRASH), mdb.ClearOnExitHashAction(), mdb.HashAction(mdb.SHORT, REPOS, mdb.FIELD, "time,repos,branch,version,comment,origin")), Hand: func(m *ice.Message, arg ...string) { }, aaa.RoleAction(REMOTE), web.DreamAction(), mdb.HashAction(mdb.SHORT, REPOS, mdb.FIELD, "time,repos,branch,version,comment,origin"), mdb.ClearOnExitHashAction()), Hand: func(m *ice.Message, arg ...string) {
if len(arg) == 0 { if len(arg) == 0 {
mdb.HashSelect(m, arg...).Sort(REPOS).PushAction(STATUS, mdb.REMOVE).Action(CLONE, PULL, PUSH, STATUS) mdb.HashSelect(m, arg...).Sort(REPOS).PushAction(STATUS, mdb.REMOVE).Action(STATUS, PULL, PUSH, CLONE)
} else if len(arg) == 1 { } else if len(arg) == 1 {
_repos_branch(m, _repos_open(m, arg[0])) _repos_branch(m, _repos_open(m, arg[0]))
} else if len(arg) == 2 { } else if len(arg) == 2 {
@ -695,7 +714,9 @@ func init() {
}}, }},
}) })
} }
func ReposList(m *ice.Message) *ice.Message { return m.Cmd(REPOS, ice.OptionFields("repos,path")) } func ReposList(m *ice.Message) *ice.Message {
func ReposClone(m *ice.Message, arg ...string) *ice.Message { return m.Cmdy(web.CODE_GIT_REPOS, ice.OptionFields("repos,path"))
return m.Cmdy("web.code.git.repos", "clone", arg) }
func ReposClone(m *ice.Message, arg ...string) *ice.Message {
return m.Cmdy(web.CODE_GIT_REPOS, CLONE, arg)
} }

View File

@ -17,8 +17,8 @@ import (
func init() { func init() {
const ( const (
EXPLORE_REPOS = "/explore/repos"
REPOS_SEARCH = "/api/v1/repos/search" REPOS_SEARCH = "/api/v1/repos/search"
EXPLORE_REPOS = "/explore/repos"
) )
const ( const (
WEB_SPIDE = "web.spide" WEB_SPIDE = "web.spide"
@ -30,9 +30,9 @@ func init() {
) )
const SEARCH = "search" const SEARCH = "search"
Index.MergeCommands(ice.Commands{ Index.MergeCommands(ice.Commands{
SEARCH: {Name: "search repos@key keyword auto", Help: "代码源", Actions: ice.Actions{ SEARCH: {Name: "search repos@key keyword auto", Help: "代码源", Actions: ice.MergeActions(ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) { ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
macos.AppInstall(m, "usr/icons/App Store.png", m.PrefixKey(), ctx.ARGS, kit.Format([]string{REPOS})) macos.AppInstall(m, "App Store.png", m.PrefixKey(), ctx.ARGS, kit.Format([]string{REPOS}))
}}, }},
cli.START: {Name: "start name*", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(web.DREAM, mdb.CREATE); m.Cmdy(web.DREAM, cli.START) }}, cli.START: {Name: "start name*", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(web.DREAM, mdb.CREATE); m.Cmdy(web.DREAM, cli.START) }},
CLONE: {Name: "clone name*", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(REPOS, CLONE, m.Option(REPOS)) }}, CLONE: {Name: "clone name*", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(REPOS, CLONE, m.Option(REPOS)) }},
@ -41,13 +41,19 @@ func init() {
ORIGIN: {Help: "平台", Hand: func(m *ice.Message, arg ...string) { ORIGIN: {Help: "平台", Hand: func(m *ice.Message, arg ...string) {
m.ProcessOpen(m.Cmdv(WEB_SPIDE, kit.Select(m.Option(REPOS), arg, 0), web.CLIENT_ORIGIN) + EXPLORE_REPOS) m.ProcessOpen(m.Cmdv(WEB_SPIDE, kit.Select(m.Option(REPOS), arg, 0), web.CLIENT_ORIGIN) + EXPLORE_REPOS)
}}, }},
}, Hand: func(m *ice.Message, arg ...string) { web.DREAM_INPUTS: {Hand: func(m *ice.Message, arg ...string) {
kit.If(arg[0] == REPOS, func() {
m.Cmds("", nfs.REPOS).Table(func(value ice.Maps) {
m.Push(nfs.REPOS, value["html_url"]).Push(nfs.VERSION, "").Push(mdb.TIME, value["updated_at"])
})
})
}},
}, web.DreamAction()), Hand: func(m *ice.Message, arg ...string) {
if len(arg) == 0 { 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 return
} }
res := kit.UnMarshal(m.Cmdx(WEB_SPIDE, arg[0], web.SPIDE_RAW, http.MethodGet, REPOS_SEARCH, "q", kit.Select("", arg, 1), "sort", "updated", "order", "desc", "page", "1", "limit", "30")) kit.For(kit.Value(kit.UnMarshal(m.Cmdx(WEB_SPIDE, arg[0], web.SPIDE_RAW, http.MethodGet, REPOS_SEARCH, "q", kit.Select("", arg, 1), "sort", "updated", "order", "desc", "page", "1", "limit", "30")), mdb.DATA), func(value ice.Map) {
kit.For(kit.Value(res, mdb.DATA), func(value ice.Map) {
value[nfs.SIZE] = kit.FmtSize(kit.Int(value[nfs.SIZE]) * 1000) 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 { if t, e := time.Parse(time.RFC3339, kit.Format(value[UPDATED_AT])); e == nil {
value[UPDATED_AT] = t.Format("01-02 15:04") value[UPDATED_AT] = t.Format("01-02 15:04")
@ -64,7 +70,6 @@ func init() {
kit.For([]string{HTML_URL, WEBSITE}, func(key string) { kit.If(kit.Format(value[key]), func() { button = append(button, key) }) }) kit.For([]string{HTML_URL, WEBSITE}, func(key string) { kit.If(kit.Format(value[key]), func() { button = append(button, key) }) })
m.PushButton(button...) m.PushButton(button...)
}) })
// m.Echo("%v", kit.Formats(res))
m.RenameAppend(CLONE_URL, REPOS).StatusTimeCount().Display("").Action(ORIGIN) m.RenameAppend(CLONE_URL, REPOS).StatusTimeCount().Display("").Action(ORIGIN)
}}, }},
}) })

View File

@ -2,8 +2,7 @@ Volcanos(chat.ONIMPORT, {
_init: function(can, msg) { if (!can.Option(nfs.REPOS)) { return can.onappend.table(can, msg) } _init: function(can, msg) { if (!can.Option(nfs.REPOS)) { return can.onappend.table(can, msg) }
if (can.isZoneMode()) { return can.onimport._vimer_zone(can, msg, can._output) } if (can.isZoneMode()) { return can.onimport._vimer_zone(can, msg, can._output) }
can.onappend.style(can, "card", can._output) can.onappend.style(can, "card", can._output)
can.page.Appends(can, can._output, msg.Table(function(value) { can.page.Appends(can, can._output, msg.Table(function(value) { value.language == "JavaScript" && (value.language = "JS")
value.language == "JavaScript" && (value.language = "JS")
return {view: [[html.ITEM, value.status]], list: [ return {view: [[html.ITEM, value.status]], list: [
{view: [wiki.TITLE, html.DIV], list: [{img: value.avatar_url}, {view: mdb.NAME, list: [ {view: [wiki.TITLE, html.DIV], list: [{img: value.avatar_url}, {view: mdb.NAME, list: [
{view: mdb.NAME, list: [{text: [value.name, "", mdb.NAME]}]}, {view: mdb.NAME, list: [{text: [value.name, "", mdb.NAME]}]},
@ -17,10 +16,7 @@ Volcanos(chat.ONIMPORT, {
]}]}, {view: [wiki.CONTENT, html.DIV, value.description]}, ]}]}, {view: [wiki.CONTENT, html.DIV, value.description]},
{view: html.ACTION, inner: value.action, _init: function(target) { can.onappend.mores(can, target, value, 5) }}, {view: html.ACTION, inner: value.action, _init: function(target) { can.onappend.mores(can, target, value, 5) }},
]} ]}
})), can.onappend.board(can, msg), can.onimport.layout(can) })), can.onappend.board(can, msg), can.onimport.layout(can), can.user.isWindows && can.onappend.scroll(can, can._output)
can.user.isWindows && can.onappend.scroll(can, can._output)
},
layout: function(can) {
can.onlayout.expand(can, can._output, can.user.isMobile && !can.user.isLandscape()? can.ConfWidth(): 380)
}, },
layout: function(can) { can.onlayout.expand(can, can._output, can.user.isMobile && !can.user.isLandscape()? can.ConfWidth(): 380) },
}, [""]) }, [""])

View File

@ -1,3 +0,0 @@
title "web.code.git.search"
spark `search 命令,代码平台。`

View File

@ -4,28 +4,24 @@ import (
"compress/flate" "compress/flate"
"compress/gzip" "compress/gzip"
"context" "context"
"fmt"
"io" "io"
"os" "net/http"
"path" "path"
"strconv" "strconv"
"strings" "strings"
git "shylinux.com/x/go-git/v5"
"shylinux.com/x/go-git/v5/plumbing" "shylinux.com/x/go-git/v5/plumbing"
"shylinux.com/x/go-git/v5/plumbing/protocol/packp" "shylinux.com/x/go-git/v5/plumbing/protocol/packp"
"shylinux.com/x/go-git/v5/plumbing/transport" "shylinux.com/x/go-git/v5/plumbing/transport"
"shylinux.com/x/go-git/v5/plumbing/transport/file"
"shylinux.com/x/go-git/v5/plumbing/transport/server" "shylinux.com/x/go-git/v5/plumbing/transport/server"
"shylinux.com/x/go-git/v5/utils/ioutil"
ice "shylinux.com/x/icebergs" ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/aaa" "shylinux.com/x/icebergs/base/aaa"
"shylinux.com/x/icebergs/base/cli" "shylinux.com/x/icebergs/base/cli"
"shylinux.com/x/icebergs/base/gdb"
"shylinux.com/x/icebergs/base/lex" "shylinux.com/x/icebergs/base/lex"
"shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs" "shylinux.com/x/icebergs/base/nfs"
"shylinux.com/x/icebergs/base/tcp"
"shylinux.com/x/icebergs/base/web" "shylinux.com/x/icebergs/base/web"
"shylinux.com/x/icebergs/core/code" "shylinux.com/x/icebergs/core/code"
kit "shylinux.com/x/toolkits" kit "shylinux.com/x/toolkits"
@ -34,36 +30,40 @@ import (
func _service_path(m *ice.Message, p string, arg ...string) string { 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...)) 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), path.Join("/x/", p)+".git")
}
func _service_param(m *ice.Message, arg ...string) (string, string) { func _service_param(m *ice.Message, arg ...string) (string, string) {
repos, service := arg[0], kit.Select(arg[len(arg)-1], m.Option(SERVICE)) repos, service := arg[0], kit.Select(arg[len(arg)-1], m.Option(SERVICE))
return _service_path(m, repos), strings.TrimPrefix(service, "git-") return _service_path(m, repos), strings.TrimPrefix(service, "git-")
} }
func _service_repos(m *ice.Message, arg ...string) error { func _service_repos(m *ice.Message, arg ...string) error {
repos, service := _service_param(m, arg...) repos, service := _service_param(m, arg...)
m.Cmd(web.COUNT, mdb.CREATE, service, strings.TrimPrefix(repos, kit.Path(ice.USR_LOCAL_REPOS)+nfs.PS), m.Option(ice.MSG_USERUA))
if mdb.Conf(m, "web.code.git.service", "meta.cmd") == "git" {
return _service_repos0(m, arg...)
}
m.Logs(m.R.Method, service, repos) m.Logs(m.R.Method, service, repos)
if service == RECEIVE_PACK && m.R.Method == http.MethodPost {
defer m.Cmd(Prefix(SERVICE), mdb.CREATE, mdb.NAME, path.Base(repos))
}
info := false info := false
if m.Option(cli.CMD_DIR, repos); strings.HasSuffix(path.Join(arg...), INFO_REFS) { if strings.HasSuffix(path.Join(arg...), INFO_REFS) {
web.RenderType(m.W, "", kit.Format("application/x-git-%s-advertisement", service)) web.RenderType(m.W, "", kit.Format("application/x-git-%s-advertisement", service))
_service_writer(m, "# service=git-"+service+lex.NL) _service_writer(m, "# service=git-"+service+lex.NL)
info = true info = true
} else { } else {
web.RenderType(m.W, "", kit.Format("application/x-git-%s-result", service)) web.RenderType(m.W, "", kit.Format("application/x-git-%s-result", service))
} }
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...)
}
reader, err := _service_reader(m) reader, err := _service_reader(m)
if err != nil { if err != nil {
return err return err
} }
defer reader.Close() defer reader.Close()
out := nfs.NewWriteCloser(func(buf []byte) (int, error) { return m.W.Write(buf) }, func() error { return nil }) stream := ServerCommand{Stdin: reader, Stdout: m.W, Stderr: m.W}
stream := ServerCommand{Stdin: reader, Stdout: out, Stderr: out}
if service == RECEIVE_PACK { if service == RECEIVE_PACK {
defer m.Cmd(Prefix(SERVICE), mdb.CREATE, mdb.NAME, path.Base(repos))
return ServeReceivePack(info, stream, repos) return ServeReceivePack(info, stream, repos)
} else { } else {
return ServeUploadPack(info, stream, repos) return ServeUploadPack(info, stream, repos)
@ -71,23 +71,16 @@ func _service_repos(m *ice.Message, arg ...string) error {
} }
func _service_repos0(m *ice.Message, arg ...string) error { func _service_repos0(m *ice.Message, arg ...string) error {
repos, service := _service_param(m, arg...) repos, service := _service_param(m, arg...)
m.Logs(m.R.Method, service, repos) if m.Options(cli.CMD_DIR, repos, cli.CMD_OUTPUT, m.W); strings.HasSuffix(path.Join(arg...), INFO_REFS) {
if m.Option(cli.CMD_DIR, repos); strings.HasSuffix(path.Join(arg...), INFO_REFS) { _git_cmd(m, service, "--stateless-rpc", "--advertise-refs", nfs.PT)
m.Option(ice.MSG_USERROLE, aaa.TECH)
web.RenderType(m.W, "", kit.Format("application/x-git-%s-advertisement", service))
_service_writer(m, "# service=git-"+service+lex.NL, _git_cmds(m, service, "--stateless-rpc", "--advertise-refs", nfs.PT))
return nil return nil
} }
if service == RECEIVE_PACK {
defer m.Cmd(Prefix(SERVICE), mdb.CREATE, mdb.NAME, path.Base(repos))
}
reader, err := _service_reader(m) reader, err := _service_reader(m)
if err != nil { if err != nil {
return err return err
} }
defer reader.Close() defer reader.Close()
web.RenderType(m.W, "", kit.Format("application/x-git-%s-result", service)) _git_cmd(m.Options(cli.CMD_INPUT, reader), service, "--stateless-rpc", nfs.PT)
_git_cmd(m.Options(cli.CMD_INPUT, reader, cli.CMD_OUTPUT, m.W), service, "--stateless-rpc", nfs.PT)
return nil return nil
} }
func _service_writer(m *ice.Message, cmd string, str ...string) { func _service_writer(m *ice.Message, cmd string, str ...string) {
@ -107,25 +100,21 @@ func _service_reader(m *ice.Message) (io.ReadCloser, error) {
const ( const (
INFO_REFS = "info/refs" INFO_REFS = "info/refs"
RECEIVE_PACK = "receive-pack"
UPLOAD_PACK = "upload-pack" UPLOAD_PACK = "upload-pack"
RECEIVE_PACK = "receive-pack"
) )
const SERVICE = "service" const SERVICE = "service"
func init() { func init() {
web.Index.MergeCommands(ice.Commands{"/info/refs": {Actions: aaa.WhiteAction(), Hand: func(m *ice.Message, arg ...string) {
m.RenderRedirect(kit.MergeURL(ice.Info.Make.Remote+"/info/refs", m.OptionSimple(SERVICE)))
}}})
web.Index.MergeCommands(ice.Commands{"/x/": {Actions: aaa.WhiteAction(), Hand: func(m *ice.Message, arg ...string) { web.Index.MergeCommands(ice.Commands{"/x/": {Actions: aaa.WhiteAction(), Hand: func(m *ice.Message, arg ...string) {
if len(arg) == 0 { if len(arg) == 0 {
return return
} } else if arg[0] == ice.LIST {
if arg[0] == ice.LIST {
m.Cmd(Prefix(SERVICE), func(value ice.Maps) { m.Push(nfs.REPOS, web.MergeLink(m, "/x/"+kit.Keys(value[nfs.REPOS], GIT))) }) m.Cmd(Prefix(SERVICE), func(value ice.Maps) { m.Push(nfs.REPOS, web.MergeLink(m, "/x/"+kit.Keys(value[nfs.REPOS], GIT))) })
m.Sort(nfs.REPOS) m.Sort(nfs.REPOS)
return return
} else if m.RenderVoid(); m.Option("go-get") == "1" { } else if m.RenderVoid(); m.Option("go-get") == "1" {
p := _git_url(m, path.Join(arg...)) p := _service_link(m, path.Join(arg...))
m.RenderResult(kit.Format(`<meta name="go-import" content="%s">`, kit.Format(`%s git %s`, strings.TrimSuffix(strings.Split(p, "://")[1], nfs.PT+GIT), p))) m.RenderResult(kit.Format(`<meta name="go-import" content="%s">`, kit.Format(`%s git %s`, strings.TrimSuffix(strings.Split(p, "://")[1], nfs.PT+GIT), p)))
return return
} }
@ -133,11 +122,9 @@ func init() {
case RECEIVE_PACK: case RECEIVE_PACK:
if !web.BasicCheck(m, "git server") { if !web.BasicCheck(m, "git server") {
return return
} } else if !nfs.Exists(m, repos) {
if !nfs.Exists(m, repos) {
m.Cmd(Prefix(SERVICE), mdb.CREATE, mdb.NAME, path.Base(repos)) m.Cmd(Prefix(SERVICE), mdb.CREATE, mdb.NAME, path.Base(repos))
} }
case UPLOAD_PACK: case UPLOAD_PACK:
if mdb.Conf(m, Prefix(SERVICE), kit.Keym(aaa.AUTH)) == aaa.PRIVATE { if mdb.Conf(m, Prefix(SERVICE), kit.Keym(aaa.AUTH)) == aaa.PRIVATE {
if !web.BasicCheck(m, "git server") { if !web.BasicCheck(m, "git server") {
@ -156,7 +143,7 @@ func init() {
m.Cmd(nfs.DIR, ice.USR_LOCAL_REPOS, func(value ice.Maps) { _repos_insert(m, value[nfs.PATH]) }) m.Cmd(nfs.DIR, ice.USR_LOCAL_REPOS, func(value ice.Maps) { _repos_insert(m, value[nfs.PATH]) })
}}, }},
mdb.CREATE: {Name: "create name*=demo", Hand: func(m *ice.Message, arg ...string) { mdb.CREATE: {Name: "create name*=demo", Hand: func(m *ice.Message, arg ...string) {
_repos_init(m, _service_path(m, m.Option(mdb.NAME))) git.PlainInit(_service_path(m, m.Option(mdb.NAME)), true)
_repos_insert(m, _service_path(m, m.Option(mdb.NAME))) _repos_insert(m, _service_path(m, m.Option(mdb.NAME)))
}}, }},
mdb.REMOVE: {Hand: func(m *ice.Message, arg ...string) { mdb.REMOVE: {Hand: func(m *ice.Message, arg ...string) {
@ -164,51 +151,31 @@ func init() {
mdb.HashRemove(m, m.Option(REPOS)) mdb.HashRemove(m, m.Option(REPOS))
nfs.Trash(m, _service_path(m, m.Option(REPOS))) nfs.Trash(m, _service_path(m, m.Option(REPOS)))
}}, }},
RECEIVE_PACK: {Hand: func(m *ice.Message, arg ...string) { code.INNER: {Hand: func(m *ice.Message, arg ...string) {
if err := file.ServeReceivePack(arg[0]); err != nil { _repos_inner(m, _service_path, arg...)
fmt.Fprintln(os.Stderr, "ERR:", err)
os.Exit(128)
}
}}, }},
UPLOAD_PACK: {Hand: func(m *ice.Message, arg ...string) {
if err := file.ServeUploadPack(arg[0]); err != nil {
fmt.Fprintln(os.Stderr, "ERR:", err)
os.Exit(128)
}
}},
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) { web.DREAM_INPUTS: {Hand: func(m *ice.Message, arg ...string) {
kit.If(arg[0] == REPOS, func() { kit.If(arg[0] == REPOS, func() { mdb.HashSelect(m).Sort(REPOS).Cut("repos,version,time") })
mdb.HashSelect(m).Sort(REPOS).Cut("repos,version,time")
m.Cmd(mdb.SEARCH, nfs.REPOS).Table(func(value ice.Maps) {
m.Push(nfs.REPOS, value["html_url"])
m.Push(nfs.VERSION, "")
m.Push(mdb.TIME, value["updated_at"])
})
})
}}, }},
}, gdb.EventsAction(web.DREAM_INPUTS), mdb.HashAction(mdb.SHORT, REPOS, mdb.FIELD, "time,repos,branch,version,comment"), mdb.ClearOnExitHashAction()), Hand: func(m *ice.Message, arg ...string) { }, web.DreamAction(), mdb.HashAction(mdb.SHORT, REPOS, mdb.FIELD, "time,repos,branch,version,comment"), mdb.ClearOnExitHashAction()), Hand: func(m *ice.Message, arg ...string) {
if len(arg) == 0 { if len(arg) == 0 {
mdb.HashSelect(m, arg...).Table(func(value ice.Maps) { mdb.HashSelect(m, arg...).Table(func(value ice.Maps) {
m.Push(nfs.SIZE, kit.Split(m.Cmdx(cli.SYSTEM, "du", "-sh", path.Join(ice.USR_LOCAL_REPOS, value[REPOS])))[0]) 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", tcp.PublishLocalhost(m, kit.Split(web.MergeURL2(m, "/x/"+value[REPOS]+".git"), mdb.QS)[0]))) m.PushScript(kit.Format("git clone %s", _service_link(m, value[REPOS])))
}).Sort(REPOS).Cmdy("web.code.publish", ice.CONTEXTS, ice.DEV) }).Sort(REPOS).Cmdy(web.CODE_PUBLISH, ice.CONTEXTS, ice.DEV)
kit.If(mdb.Config(m, aaa.AUTH) == aaa.PRIVATE, func() { m.StatusTimeCount(aaa.AUTH, aaa.PRIVATE) }) kit.If(mdb.Config(m, aaa.AUTH) == aaa.PRIVATE, func() { m.StatusTimeCount(aaa.AUTH, aaa.PRIVATE) })
} else if len(arg) == 1 { } else if repos := _repos_open(m, arg[0]); len(arg) == 1 {
_repos_branch(m, _repos_open(m, arg[0])) defer m.PushScript(kit.Format("git clone %s", _service_link(m, arg[0])))
m.EchoScript(tcp.PublishLocalhost(m, kit.Split(web.MergeURL2(m, "/x/"+arg[0]), mdb.QS)[0])) _repos_branch(m, repos)
} else if len(arg) == 2 { } else if len(arg) == 2 {
repos := _repos_open(m, arg[0])
if iter, err := repos.Branches(); err == nil { if iter, err := repos.Branches(); err == nil {
iter.ForEach(func(refer *plumbing.Reference) error { iter.ForEach(func(refer *plumbing.Reference) error {
if refer.Name().Short() == arg[1] { kit.If(refer.Name().Short() == arg[1], func() { _repos_log(m, refer.Hash(), repos) })
_repos_log(m, refer.Hash(), repos)
}
return nil return nil
}) })
} }
} else if len(arg) == 3 { } 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) _repos_status(m, arg[0], repos)
} else { } else {
_repos_stats(m, repos, arg[2]) _repos_stats(m, repos, arg[2])
@ -220,80 +187,60 @@ func init() {
}) })
} }
func ServeReceivePack(info bool, srvCmd ServerCommand, path string) error {
ep, err := transport.NewEndpoint(path)
if err != nil {
return err
}
s, err := server.DefaultServer.NewReceivePackSession(ep, nil)
if err != nil {
return fmt.Errorf("error creating session: %s", err)
}
return serveReceivePack(info, srvCmd, s)
}
func ServeUploadPack(info bool, srvCmd ServerCommand, path string) error {
ep, err := transport.NewEndpoint(path)
if err != nil {
return err
}
s, err := server.DefaultServer.NewUploadPackSession(ep, nil)
if err != nil {
return fmt.Errorf("error creating session: %s", err)
}
return serveUploadPack(info, srvCmd, s)
}
type ServerCommand struct { type ServerCommand struct {
Stdout io.Writer
Stderr io.Writer Stderr io.Writer
Stdout io.WriteCloser
Stdin io.Reader Stdin io.Reader
} }
func ServeReceivePack(info bool, srvCmd ServerCommand, path string) error {
if ep, err := transport.NewEndpoint(path); err != nil {
return err
} else if s, err := server.DefaultServer.NewReceivePackSession(ep, nil); err != nil {
return err
} else {
return serveReceivePack(info, srvCmd, s)
}
}
func ServeUploadPack(info bool, srvCmd ServerCommand, path string) error {
if ep, err := transport.NewEndpoint(path); err != nil {
return err
} else if s, err := server.DefaultServer.NewUploadPackSession(ep, nil); err != nil {
return err
} else {
return serveUploadPack(info, srvCmd, s)
}
}
func serveReceivePack(info bool, cmd ServerCommand, s transport.ReceivePackSession) error { func serveReceivePack(info bool, cmd ServerCommand, s transport.ReceivePackSession) error {
if info { if info {
ar, err := s.AdvertisedReferences() return serveAdvertisedRefer(cmd, s)
if err != nil {
return fmt.Errorf("internal error in advertised references: %s", err)
}
if err := ar.Encode(cmd.Stdout); err != nil {
return fmt.Errorf("error in advertised references encoding: %s", err)
}
return nil
} }
req := packp.NewReferenceUpdateRequest() req := packp.NewReferenceUpdateRequest()
if err := req.Decode(cmd.Stdin); err != nil { if err := req.Decode(cmd.Stdin); err != nil {
return fmt.Errorf("error decoding: %s", err) return err
} else if resp, err := s.ReceivePack(context.TODO(), req); err != nil {
return err
} else {
return resp.Encode(cmd.Stdout)
} }
rs, err := s.ReceivePack(context.TODO(), req)
if rs != nil {
if err := rs.Encode(cmd.Stdout); err != nil {
return fmt.Errorf("error in encoding report status %s", err)
}
}
if err != nil {
return fmt.Errorf("error in receive pack: %s", err)
}
return nil
} }
func serveUploadPack(info bool, cmd ServerCommand, s transport.UploadPackSession) (err error) { func serveUploadPack(info bool, cmd ServerCommand, s transport.UploadPackSession) (err error) {
ioutil.CheckClose(cmd.Stdout, &err)
if info { if info {
ar, err := s.AdvertisedReferences() return serveAdvertisedRefer(cmd, s)
if err != nil {
return err
}
if err := ar.Encode(cmd.Stdout); err != nil {
return err
}
return nil
} }
req := packp.NewUploadPackRequest() req := packp.NewUploadPackRequest()
if err := req.Decode(cmd.Stdin); err != nil { if err := req.Decode(cmd.Stdin); err != nil {
return err return err
} } else if resp, err := s.UploadPack(context.TODO(), req); err != nil {
resp, err := s.UploadPack(context.TODO(), req)
if err != nil {
return err return err
} } else {
return resp.Encode(cmd.Stdout) return resp.Encode(cmd.Stdout)
}
}
func serveAdvertisedRefer(cmd ServerCommand, s transport.Session) (err error) {
if resp, err := s.AdvertisedReferences(); err != nil {
return err
} else {
return resp.Encode(cmd.Stdout)
}
} }

View File

@ -9,7 +9,6 @@ import (
"shylinux.com/x/icebergs/base/aaa" "shylinux.com/x/icebergs/base/aaa"
"shylinux.com/x/icebergs/base/cli" "shylinux.com/x/icebergs/base/cli"
"shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/ctx"
"shylinux.com/x/icebergs/base/lex"
"shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs" "shylinux.com/x/icebergs/base/nfs"
"shylinux.com/x/icebergs/base/tcp" "shylinux.com/x/icebergs/base/tcp"
@ -18,87 +17,6 @@ import (
kit "shylinux.com/x/toolkits" kit "shylinux.com/x/toolkits"
) )
func _status_tag(m *ice.Message, tags string) string {
if tags == "" {
return "v0.0.1"
}
ls := kit.Split(strings.TrimPrefix(kit.Split(tags, "-")[0], "v"), nfs.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 {
return kit.Format("v%v.%v.0", ls[0], v+1)
} else if v := kit.Int(ls[0]); v < 9 {
return kit.Format("v%v.0.0", v+1)
} else {
return "v0.0.1"
}
}
func _status_stat(m *ice.Message, files, adds, dels int) (int, int, int) {
kit.SplitKV(lex.SP, mdb.FS, _git_diff(m), func(text string, ls []string) {
n := kit.Int(ls[0])
switch {
case strings.Contains(text, "file"):
files += n
case strings.Contains(text, "inser"):
adds += n
case strings.Contains(text, "delet"):
dels += n
}
})
return files, adds, dels
}
func _status_list(m *ice.Message) (files, adds, dels int, last string) {
onlychange := m.Option(ice.MSG_MODE) == mdb.ZONE
defer m.Option(cli.CMD_DIR, "")
ReposList(m).Table(func(value ice.Maps) {
m.Option(cli.CMD_DIR, value[nfs.PATH])
files, adds, dels = _status_stat(m, files, adds, dels)
_last := m.Cmdv(REPOS, path.Base(value[nfs.PATH]), mdb.TIME)
kit.If(_last > last, func() { last = _last })
tags := _git_tags(m)
kit.SplitKV(lex.SP, lex.NL, _git_status(m), func(text string, ls []string) {
switch kit.Ext(ls[1]) {
case "swp", "swo", ice.BIN, ice.VAR:
return
}
if onlychange && ls[0] == "##" {
return
}
if m.Push(REPOS, value[REPOS]).Push(mdb.TYPE, ls[0]).Push(nfs.FILE, ls[1]); onlychange {
m.Push(nfs.PATH, value[nfs.PATH]).Push(mdb.VIEW, kit.Format("%s %s", ls[0]+strings.Repeat(lex.SP, len(ls[0])-9), kit.Select("", nfs.USR+value[REPOS]+nfs.PS, value[REPOS] != ice.CONTEXTS)+ls[1]))
}
switch ls[0] {
case "##":
if m.Push(TAGS, tags); strings.Contains(ls[1], "ahead") || !strings.Contains(ls[1], "...") {
m.PushButton(PUSH)
} else if tags == "" || strings.Contains(tags, "-") {
m.PushButton(TAG)
} else {
m.PushButton("")
}
default:
if m.Push(TAGS, ""); strings.Contains(ls[0], "??") {
m.PushButton(ADD, nfs.TRASH)
} else {
m.PushButton(COMMIT)
}
}
})
})
return
}
const (
GITEA = "gitea"
OAUTH = "oauth"
DIFF = "diff"
OPT = "opt"
FIX = "fix"
TAGS = "tags"
VERSION = "version"
COMMENT = "comment"
)
const STATUS = "status" const STATUS = "status"
func init() { func init() {
@ -107,23 +25,10 @@ func init() {
mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) { mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) {
switch m.Option(ctx.ACTION) { switch m.Option(ctx.ACTION) {
case INIT: case INIT:
switch arg[0] { m.Cmd("web.spide", ice.OptionFields(web.CLIENT_ORIGIN), func(value ice.Maps) { m.Push(arg[0], value[web.CLIENT_ORIGIN]+"/x/"+path.Base(kit.Path(""))) })
case ORIGIN:
m.Cmd("web.spide", func(value ice.Maps) {
m.Push(arg[0], kit.ParseURLMap(value[web.CLIENT_URL])[ORIGIN]+"/x/"+path.Base(kit.Path("")))
})
}
case INSTEADOF: case INSTEADOF:
switch arg[0] { m.Cmd("web.spide", ice.OptionFields(web.CLIENT_ORIGIN), func(value ice.Maps) { m.Push(arg[0], value[web.CLIENT_ORIGIN]+"/x/") })
case nfs.FROM: default:
m.Push(arg[0], kit.MergeURL2(ice.Info.Make.Remote, nfs.PS))
case nfs.TO:
m.Cmd(web.BROAD, func(value ice.Maps) { m.Push(arg[0], kit.Format("http://%s:%s/", value[tcp.HOST], value[tcp.PORT])) })
case REMOTE:
m.Cmd("web.spide", func(value ice.Maps) { m.Push(arg[0], kit.ParseURLMap(value[web.CLIENT_URL])[ORIGIN]+"/x/") })
}
return
}
switch arg[0] { switch arg[0] {
case aaa.EMAIL: case aaa.EMAIL:
m.Push(arg[0], _configs_get(m, USER_EMAIL), ice.Info.Make.Email) m.Push(arg[0], _configs_get(m, USER_EMAIL), ice.Info.Make.Email)
@ -132,21 +37,25 @@ func init() {
default: default:
m.Cmdy(REPOS, mdb.INPUTS, arg) m.Cmdy(REPOS, mdb.INPUTS, arg)
} }
}
}},
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") })
mdb.Config(m, aaa.USERNAME, m.Option(aaa.USERNAME))
mdb.Config(m, aaa.EMAIL, m.Option(aaa.EMAIL))
}}, }},
INIT: {Name: "init origin", Help: "初始化", Hand: func(m *ice.Message, arg ...string) { INIT: {Name: "init origin", Help: "初始化", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(REPOS, INIT) m.Cmdy(REPOS, INIT)
}}, }},
CONFIGS: {Name: "configs email* username* token", Help: "配置", Hand: func(m *ice.Message, arg ...string) { INSTEADOF: {Name: "insteadof remote", 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))) m.Cmdy(REPOS, INSTEADOF, arg)
mdb.Config(m, aaa.USERNAME, m.Option(aaa.USERNAME))
mdb.Config(m, aaa.EMAIL, m.Option(aaa.EMAIL))
kit.If(m.Option(web.TOKEN), func() { m.Cmd(web.TOKEN, "set") })
}}, }},
OAUTH: {Help: "授权", Hand: func(m *ice.Message, arg ...string) { OAUTH: {Help: "授权", 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"), tcp.HOST, m.Option(ice.MSG_USERWEB))) m.ProcessOpen(kit.MergeURL2(kit.Select(ice.Info.Make.Domain, m.Cmdx(REPOS, "remoteURL")), web.ChatCmdPath(m, web.TOKEN, "gen"), tcp.HOST, m.Option(ice.MSG_USERWEB)))
}}, }},
INSTEADOF: {Name: "insteadof remote", Help: "代理", Hand: func(m *ice.Message, arg ...string) { GITEA: {Help: "资源", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(REPOS, INSTEADOF, arg) m.ProcessOpen(m.Cmdv("web.spide", ice.HUB, web.CLIENT_URL))
}}, }},
web.DREAM_TABLES: {Hand: func(m *ice.Message, arg ...string) { web.DREAM_TABLES: {Hand: func(m *ice.Message, arg ...string) {
if !kit.IsIn(m.Option(mdb.TYPE), web.WORKER, web.SERVER) { if !kit.IsIn(m.Option(mdb.TYPE), web.WORKER, web.SERVER) {
@ -167,8 +76,7 @@ func init() {
} }
m.Push(mdb.TEXT, strings.Join(text, ", ")) m.Push(mdb.TEXT, strings.Join(text, ", "))
}}, }},
GITEA: {Help: "资源", Hand: func(m *ice.Message, arg ...string) { m.ProcessOpen(m.Cmdv("web.spide", ice.HUB, web.CLIENT_URL)) }}, }, aaa.RoleAction(), web.DreamAction(), Prefix(REPOS)), Hand: func(m *ice.Message, arg ...string) {
}, aaa.RoleAction(), web.DreamAction(), Prefix(REPOS), mdb.ImportantHashAction()), Hand: func(m *ice.Message, arg ...string) {
if len(arg) > 0 && arg[0] == ctx.ACTION { if len(arg) > 0 && arg[0] == ctx.ACTION {
m.Cmdy(REPOS, arg) m.Cmdy(REPOS, arg)
} else if config, err := config.LoadConfig(config.GlobalScope); err == nil && config.User.Email == "" && mdb.Config(m, aaa.EMAIL) == "" { } else if config, err := config.LoadConfig(config.GlobalScope); err == nil && config.User.Email == "" && mdb.Config(m, aaa.EMAIL) == "" {
@ -180,7 +88,7 @@ func init() {
m.Cmdy(REPOS, STATUS).Action(PULL, PUSH, INSTEADOF, OAUTH, CONFIGS, GITEA) m.Cmdy(REPOS, STATUS).Action(PULL, PUSH, INSTEADOF, OAUTH, CONFIGS, GITEA)
m.Cmdy(code.PUBLISH, ice.CONTEXTS, ice.DEV) m.Cmdy(code.PUBLISH, ice.CONTEXTS, ice.DEV)
} else { } else {
m.Cmdy(REPOS, arg[0], MASTER, INDEX, m.Cmdv(REPOS, arg[0], MASTER, INDEX, nfs.FILE)) _repos_cmd(m, arg[0], DIFF)
} }
}}, }},
}) })

View File

@ -1 +0,0 @@
package git

View File

@ -1,18 +1,26 @@
ssh misc.shy
misc.go
websocket
webview
qrcode
xterm
git git
alpha ssh
input vim
bash bash
tmux tmux
vim alpha
input
yac
lex
webview
chrome
coder
java java
node node
coder
chrome
github
wework wework
lark lark
wx
mp mp
wx

View File

@ -1 +0,0 @@
package misc

View File

@ -1,13 +1,9 @@
package node package node
import ( import (
"path"
"shylinux.com/x/ice" "shylinux.com/x/ice"
"shylinux.com/x/icebergs/base/cli" "shylinux.com/x/icebergs/base/cli"
"shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
kit "shylinux.com/x/toolkits"
) )
const NODE = "node" const NODE = "node"
@ -17,19 +13,15 @@ type node struct {
regexp string `data:"js"` regexp string `data:"js"`
darwin string `data:"https://mirrors.tencent.com/nodejs-release/v16.15.1/node-v16.15.1-darwin-x64.tar.gz"` darwin string `data:"https://mirrors.tencent.com/nodejs-release/v16.15.1/node-v16.15.1-darwin-x64.tar.gz"`
linux string `data:"https://mirrors.tencent.com/nodejs-release/v16.15.1/node-v16.15.1-linux-x64.tar.xz"` linux string `data:"https://mirrors.tencent.com/nodejs-release/v16.15.1/node-v16.15.1-linux-x64.tar.xz"`
list string `name:"list path auto listScript xterm order install" help:"运行时"` list string `name:"list path auto xterm order install" help:"运行时"`
} }
func (s node) Init(m *ice.Message) { func (s node) Init(m *ice.Message) {
cli.IsAlpine(m.Message, NODE, "nodejs") cli.IsAlpine(m.Message, NODE, "nodejs")
cli.IsCentos(m.Message, NODE, "nodejs") cli.IsCentos(m.Message, NODE, "nodejs")
} }
func (s node) Install(m *ice.Message, arg ...string) {
s.Code.Install(m, arg...)
s.Code.System(m, ice.USR_INSTALL, nfs.TAR, "xf", path.Base(s.Code.Link(m)))
}
func (s node) List(m *ice.Message, arg ...string) { func (s node) List(m *ice.Message, arg ...string) {
s.Code.Source(m, path.Join(ice.USR_INSTALL, kit.TrimExt(s.Code.Link(m), "tar.xz")), arg...) s.Code.Source(m, "", arg...)
} }
func (s node) Xterm(m *ice.Message, arg ...string) { func (s node) Xterm(m *ice.Message, arg ...string) {
s.Code.Xterm(m, []string{mdb.TYPE, NODE}, arg...) s.Code.Xterm(m, []string{mdb.TYPE, NODE}, arg...)

View File

@ -26,12 +26,14 @@ type WebView struct {
func (w WebView) Menu() bool { func (w WebView) Menu() bool {
link, list := "", []string{} link, list := "", []string{}
w.Cmd(nfs.CAT, w.Source, func(ls []string, line string) { w.Cmd(nfs.CAT, w.Source, func(ls []string, line string) {
if strings.HasPrefix(line, "# ") { if len(ls) == 0 || strings.HasPrefix(line, "# ") {
return return
} else if len(ls) > 1 { } else if len(ls) == 1 {
link, list = ls[1], append(list, kit.Format(`<button onclick=%s()>%s</button>`, ls[0], ls[0])) u := kit.ParseURL(ls[0])
w.WebView.Bind(ls[0], func() { w.navigate(ls[1]) }) ls = []string{strings.ReplaceAll(u.Hostname(), ".", "_"), ls[0]}
} }
w.WebView.Bind(ls[0], func() { w.navigate(ls[1]) })
link, list = ls[1], append(list, kit.Format(`<button onclick=%s()>%s</button>`, ls[0], ls[0]))
}) })
if len(list) == 0 { if len(list) == 0 {
return false return false
@ -52,18 +54,9 @@ func (w WebView) Menu() bool {
} }
func (w WebView) Title(text string) { w.WebView.SetTitle(text) } func (w WebView) Title(text string) { w.WebView.SetTitle(text) }
func (w WebView) Webview(url string) { w.WebView.Navigate(url) } func (w WebView) Webview(url string) { w.WebView.Navigate(url) }
func (w WebView) Open(url string) { func (w WebView) Open(url string) { w.WebView.Navigate(url) }
w.Message.Debug("open %v", url) func (w WebView) OpenUrl(url string) { cli.Opens(w.Message, url) }
w.WebView.Navigate(url) func (w WebView) OpenApp(app string) { cli.Opens(w.Message, app) }
}
func (w WebView) OpenUrl(url string) {
w.Message.Debug("open %v", url)
cli.Opens(w.Message, url)
}
func (w WebView) OpenApp(app string) {
w.Message.Debug("open %v", app)
cli.Opens(w.Message, app)
}
func (w WebView) OpenCmd(cmd string) { func (w WebView) OpenCmd(cmd string) {
w.Cmd(nfs.SAVE, kit.HomePath(".bash_temp"), cmd) w.Cmd(nfs.SAVE, kit.HomePath(".bash_temp"), cmd)
cli.Opens(w.Message, "Terminal.app", "-n") cli.Opens(w.Message, "Terminal.app", "-n")
@ -81,10 +74,7 @@ func (w WebView) Power() string {
return "" return ""
} }
func (w WebView) Close() { kit.If(!w.Menu(), func() { w.WebView.Terminate() }) } func (w WebView) Close() { kit.If(!w.Menu(), func() { w.WebView.Terminate() }) }
func (w WebView) Terminate() { func (w WebView) Terminate() { w.WebView.Terminate() }
w.WebView.Eval("window.onbeforeunload()")
w.WebView.Terminate()
}
func (w WebView) navigate(url string) { func (w WebView) navigate(url string) {
w.WebView.SetSize(1200, 800, webview.HintNone) w.WebView.SetSize(1200, 800, webview.HintNone)
w.WebView.Navigate(url) w.WebView.Navigate(url)

View File

@ -99,12 +99,12 @@ func (c *Context) Register(s *Context, x Server, cmd ...string) *Context {
return s return s
} }
func (c *Context) MergeCommands(Commands Commands) *Context { func (c *Context) MergeCommands(Commands Commands) *Context {
// for key, cmd := range Commands { for key, cmd := range Commands {
for _, cmd := range Commands { // for _, cmd := range Commands {
if cmd.Hand == nil && cmd.RawHand == nil { if cmd.Hand == nil && cmd.RawHand == nil {
if cmd.RawHand = logs.FileLines(2); cmd.Actions != nil { if cmd.RawHand = logs.FileLines(2); cmd.Actions != nil {
if action, ok := cmd.Actions[SELECT]; ok { if action, ok := cmd.Actions[SELECT]; ok {
// cmd.Name = kit.Select(strings.Replace(action.Name, SELECT, key, 1), cmd.Name) cmd.Name = kit.Select(strings.Replace(action.Name, SELECT, key, 1), cmd.Name)
cmd.Help = kit.Select(action.Help, cmd.Help) cmd.Help = kit.Select(action.Help, cmd.Help)
} }
} }