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_PUBLISH = ice.USR_PUBLISH
USR_LOCAL_WORK = ice.USR_LOCAL_WORK
USR_ICEBERGS = ice.USR_ICEBERGS
SRC_DOCUMENT = ice.SRC_DOCUMENT
SRC_TEMPLATE = ice.SRC_TEMPLATE
REQUIRE = "/require/"

View File

@ -301,7 +301,7 @@ func init() {
func DreamAction() ice.Actions {
return ice.MergeActions(ice.Actions{
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) {
if kit.HasPrefixList(arg, ctx.RUN) {

View File

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

View File

@ -102,7 +102,7 @@ func init() {
}},
}, aaa.RoleAction()), Hand: func(m *ice.Message, arg ...string) {
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))
ctx.DisplayLocal(m, "")
} 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 {
arg[1] = strings.Split(arg[1], mdb.FS)[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")
}
}},

View File

@ -30,7 +30,8 @@ func _install_path(m *ice.Message, link string) string {
func _install_download(m *ice.Message) {
link := m.Option(web.LINK)
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)
if nfs.Exists(m, file) {
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)) {
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.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 {
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)) }},
cli.BUILD: {Help: "构建", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(INSTALL, cli.BUILD, mdb.Config(m, nfs.SOURCE)) }},
web.DOWNLOAD: {Help: "下载", Hand: func(m *ice.Message, arg ...string) {
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) {
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 (
"net/http"
"path"
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/aaa"
@ -11,7 +10,6 @@ import (
"shylinux.com/x/icebergs/base/ssh"
"shylinux.com/x/icebergs/base/web"
"shylinux.com/x/icebergs/core/code"
"shylinux.com/x/icebergs/misc/git"
kit "shylinux.com/x/toolkits"
)
@ -38,13 +36,9 @@ func init() {
WordAlias(m, SEQUENCE, CHART, SEQUENCE)
}},
mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) {
m.Cmd(git.REPOS, ice.OptionFields(nfs.PATH)).Table(func(value ice.Maps) {
if m.Option(nfs.DIR_DEEP, ice.TRUE); kit.Path(value[nfs.PATH]) == kit.Path("") {
_wiki_list(m, nfs.SRC)
} else {
_wiki_list(m, path.Join(value[nfs.PATH], nfs.SRC))
}
})
m.Option(nfs.DIR_DEEP, ice.TRUE)
_wiki_list(m, nfs.SRC)
_wiki_list(m, nfs.USR_ICEBERGS)
m.Cut("path,size,time")
}},
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)
} else if k == CTX_EXIT {
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
}
}

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
import (
"strings"
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/lex"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
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) {
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) })
}
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 mdb.HashSelectValue(m, func(value ice.Maps) {
m.Push("", value, kit.Split("name,value")).PushButton(mdb.CREATE)
})
return res
}
const (
CONFIG = "config"
USER_NAME = "user.name"
USER_EMAIL = "user.email"
USER_NAME = "user.name"
)
const CONFIGS = "configs"
func init() {
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) {
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) })
@ -56,22 +42,22 @@ func init() {
}},
mdb.MODIFY: {Hand: func(m *ice.Message, arg ...string) {
if arg[0] == mdb.VALUE {
mdb.HashRemove(m, m.Option(mdb.NAME))
_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(
"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"),
"core", kit.Dict("quotepath", "false"), "color", kit.Dict("ui", "always"),
))), Hand: func(m *ice.Message, arg ...string) {
if len(arg) == 0 {
_configs_list(m).StatusTimeCount()
} else if len(arg) == 1 {
m.Echo(_configs_get(m, arg[0]))
} else {
_configs_list(m).Action(mdb.CREATE, ice.INIT).StatusTimeCount()
return
} else if len(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"
"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"
"shylinux.com/x/icebergs/core/code"
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_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_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_status(m *ice.Message) string { return _git_cmds(m, STATUS, "-sb") }
func _git_remote(m *ice.Message) string {
return _git_cmds(m, nfs.REMOTE, "get-url", nfs.ORIGIN)
}
func _git_remote(m *ice.Message) string { return _git_cmds(m, nfs.REMOTE, "get-url", nfs.ORIGIN) }
const GIT = "git"
var Index = &ice.Context{Name: GIT, Help: "代码库", Commands: ice.Commands{
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)
}},
}}
var Index = &ice.Context{Name: GIT, Help: "代码库"}
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)) }

View File

@ -6,11 +6,11 @@ refer `
`
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`
section "构建"
shell `
shell centos `
yum install -y wget make gcc
yum install -y libcurl-devel.x86_64 openssl-devel.x86_64
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
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 "启动"
shell `
@ -28,18 +34,33 @@ cd ./_install
./bin/git
`
section `配置`
section "配置"
shell `
git config --global user.email shylinux@163.com
git config --global user.name shylinux
git config --global user.email shy@shylinux.com
git config --global user.name shy
`
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.configs
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/cli"
"shylinux.com/x/icebergs/base/ctx"
"shylinux.com/x/icebergs/base/gdb"
"shylinux.com/x/icebergs/base/lex"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
@ -26,47 +25,6 @@ import (
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) {
if repos, err := git.PlainOpen(p); err == nil {
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 {
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]
} else if remote, err := repos.Remotes(); err == nil && len(remote) > 0 {
return remote[0].Config().URLs[0]
} else {
return ""
}
return ""
}
func _repos_path(m *ice.Message, p string, arg ...string) string {
if p == path.Base(kit.Path("")) {
return kit.Path("", arg...)
func _repos_recent(m *ice.Message, repos *git.Repository) (r *plumbing.Reference) {
max := 0
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...))
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
}
}
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 0
}
func _repos_open(m *ice.Message, p string) *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 {
list := _repos_credentials(m)
if insteadof := mdb.Config(m, INSTEADOF); insteadof != "" {
origin = insteadof + path.Base(origin)
}
origin = _repos_remote(m, origin)
if u, ok := list[kit.ParseURL(origin).Host]; !ok {
return nil
} 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}
}
}
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 := remote.Config().URLs[0]
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_path(m *ice.Message, p string, arg ...string) string {
if p == path.Base(kit.Path("")) {
return kit.Path("", arg...)
} else if nfs.Exists(m, path.Join(nfs.USR, p, ".git")) {
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 {
return p
}
}
func _repos_branch(m *ice.Message, repos *git.Repository) error {
iter, err := repos.Branches()
@ -176,6 +173,14 @@ func _repos_branch(m *ice.Message, repos *git.Repository) error {
})
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 {
iter, err := repos.Log(&git.LogOptions{From: hash})
if err != nil {
@ -205,24 +210,6 @@ func _repos_log(m *ice.Message, hash plumbing.Hash, repos *git.Repository) error
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 {
work, err := repos.Worktree()
if err != nil {
@ -275,32 +262,22 @@ func _repos_status(m *ice.Message, p string, repos *git.Repository) error {
}
return nil
}
func _repos_total(m *ice.Message, p string, repos *git.Repository, stats map[string]int) *time.Time {
iter, err := repos.Log(&git.LogOptions{})
func _repos_stats(m *ice.Message, repos *git.Repository, h string) error {
commit, err := repos.CommitObject(plumbing.NewHash(h))
if err != nil {
return nil
return err
}
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
})
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
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_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...)
}
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
func _repos_total(m *ice.Message, p string, repos *git.Repository, stats map[string]int) *time.Time {
iter, err := repos.Log(&git.LogOptions{})
if err != nil {
return nil
}
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 (
@ -402,6 +417,7 @@ const (
TAG = "tag"
ADD = "add"
STASH = "stash"
CONFIG = "config"
COMMIT = "commit"
BRANCH = "branch"
CHECKOUT = "checkout"
@ -412,6 +428,17 @@ const (
INDEX = "index"
INSTEADOF = "insteadof"
)
const (
GITEA = "gitea"
OAUTH = "oauth"
DIFF = "diff"
OPT = "opt"
FIX = "fix"
TAGS = "tags"
VERSION = "version"
COMMENT = "comment"
)
const REPOS = "repos"
func init() {
@ -433,9 +460,11 @@ func init() {
if p = path.Join(ice.USR_REQUIRE, path.Join(arg...)); !nfs.Exists(m, p) {
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{
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)
@ -445,15 +474,25 @@ func init() {
Index.MergeCommands(ice.Commands{
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) {
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(""))
m.Cmd(nfs.DIR, nfs.USR, func(value ice.Maps) { _repos_insert(m, value[nfs.PATH]) })
m.Cmd(nfs.DIR, nfs.USR_LOCAL_WORK, func(value ice.Maps) { _repos_insert(m, value[nfs.PATH]) })
m.Cmd(CONFIGS, func(value ice.Maps) {
if strings.HasSuffix(value[mdb.NAME], ".insteadof") && strings.HasPrefix(ice.Info.Make.Remote, value[mdb.VALUE]) {
mdb.Config(m, INSTEADOF, strings.TrimPrefix(strings.TrimSuffix(value[mdb.NAME], ".insteadof"), "url."))
}
})
}},
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) {
switch arg[0] {
case COMMENT:
@ -462,14 +501,14 @@ func init() {
m.Push(arg[0], kit.Join(kit.Slice(ls, -2), nfs.PS))
m.Push(arg[0], m.Option(nfs.FILE))
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) {
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))
if nfs.Exists(m, m.Option(nfs.PATH)) {
if nfs.Exists(m, _git_dir(m.Option(nfs.PATH))) {
return
}
defer web.ToastProcess(m)()
@ -477,7 +516,7 @@ func init() {
_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)))
git.PlainInit(m.Option(nfs.PATH), false)
_repos_insert(m, kit.Path(""))
@ -485,16 +524,16 @@ func init() {
}},
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 {
work, err := repos.Worktree()
if err != nil {
if work, err := repos.Worktree(); err != nil {
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) {
_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})
})
}},
@ -507,9 +546,9 @@ func init() {
}
}},
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))
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{})
m.Warn(err)
}
@ -520,7 +559,9 @@ func init() {
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) {
_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}
if cfg, err := config.LoadConfig(config.GlobalScope); err == nil {
if cfg.Author.Email == "" || cfg.Author.Name == "" {
opt.Author = &object.Signature{
Email: kit.Select(m.Option(ice.MSG_USERNAME)+"@shylinux.com", mdb.Config(m, aaa.EMAIL)),
opt.Author = &object.Signature{When: time.Now(),
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 {
remote = kit.Select(remote, _repos_origin(m, repos))
}
if insteadof := mdb.Config(m, INSTEADOF); insteadof != "" {
remote = insteadof + path.Base(remote)
}
remote = _repos_remote(m, remote)
if u, ok := list[kit.ParseURL(remote).Host]; ok {
password, _ = u.User.Password()
}
m.Sort("repos,status,file").Status(
mdb.TIME, last,
m.Sort("repos,status,file").Status(mdb.TIME, last,
REMOTE, remote, VERSION, ice.Info.Make.Versions(),
kit.Select(aaa.TECH, aaa.VOID, password == ""), m.Option(aaa.EMAIL),
kit.MDB_COUNT, kit.Split(m.FormatSize())[0],
kit.MDB_COST, m.FormatCost(),
kit.MDB_COUNT, kit.Split(m.FormatSize())[0], kit.MDB_COST, m.FormatCost(),
)
}
}},
@ -598,25 +634,8 @@ func init() {
}
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 := ""
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)
m.Echo(_repos_remote(m, _repos_origin(m, _repos_open(m, path.Base(kit.Path(""))))))
}},
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)))
@ -671,9 +690,9 @@ func init() {
}},
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...) }},
}, 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 {
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 {
_repos_branch(m, _repos_open(m, arg[0]))
} 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 ReposClone(m *ice.Message, arg ...string) *ice.Message {
return m.Cmdy("web.code.git.repos", "clone", arg)
func ReposList(m *ice.Message) *ice.Message {
return m.Cmdy(web.CODE_GIT_REPOS, ice.OptionFields("repos,path"))
}
func ReposClone(m *ice.Message, arg ...string) *ice.Message {
return m.Cmdy(web.CODE_GIT_REPOS, CLONE, arg)
}

View File

@ -17,8 +17,8 @@ import (
func init() {
const (
EXPLORE_REPOS = "/explore/repos"
REPOS_SEARCH = "/api/v1/repos/search"
EXPLORE_REPOS = "/explore/repos"
)
const (
WEB_SPIDE = "web.spide"
@ -30,9 +30,9 @@ func init() {
)
const SEARCH = "search"
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) {
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) }},
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) {
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 {
m.Cmdy(WEB_SPIDE).RenameAppend(web.CLIENT_NAME, REPOS, web.CLIENT_URL, ORIGIN).Cut("time,repos,origin")
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(res, mdb.DATA), func(value ice.Map) {
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) {
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 {
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) }) })
m.PushButton(button...)
})
// m.Echo("%v", kit.Formats(res))
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) }
if (can.isZoneMode()) { return can.onimport._vimer_zone(can, msg, can._output) }
can.onappend.style(can, "card", can._output)
can.page.Appends(can, can._output, msg.Table(function(value) {
value.language == "JavaScript" && (value.language = "JS")
can.page.Appends(can, can._output, msg.Table(function(value) { value.language == "JavaScript" && (value.language = "JS")
return {view: [[html.ITEM, value.status]], list: [
{view: [wiki.TITLE, html.DIV], list: [{img: value.avatar_url}, {view: mdb.NAME, list: [
{view: mdb.NAME, list: [{text: [value.name, "", mdb.NAME]}]},
@ -17,10 +16,7 @@ Volcanos(chat.ONIMPORT, {
]}]}, {view: [wiki.CONTENT, html.DIV, value.description]},
{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.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)
})), can.onappend.board(can, msg), can.onimport.layout(can), 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) },
}, [""])

View File

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

View File

@ -4,28 +4,24 @@ import (
"compress/flate"
"compress/gzip"
"context"
"fmt"
"io"
"os"
"net/http"
"path"
"strconv"
"strings"
git "shylinux.com/x/go-git/v5"
"shylinux.com/x/go-git/v5/plumbing"
"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/file"
"shylinux.com/x/go-git/v5/plumbing/transport/server"
"shylinux.com/x/go-git/v5/utils/ioutil"
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/aaa"
"shylinux.com/x/icebergs/base/cli"
"shylinux.com/x/icebergs/base/gdb"
"shylinux.com/x/icebergs/base/lex"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
"shylinux.com/x/icebergs/base/tcp"
"shylinux.com/x/icebergs/base/web"
"shylinux.com/x/icebergs/core/code"
kit "shylinux.com/x/toolkits"
@ -34,36 +30,40 @@ import (
func _service_path(m *ice.Message, p string, arg ...string) string {
return kit.Path(ice.USR_LOCAL_REPOS, kit.TrimExt(p, GIT), path.Join(arg...))
}
func _service_link(m *ice.Message, p string, arg ...string) string {
return kit.MergeURL2(web.UserHost(m), path.Join("/x/", p)+".git")
}
func _service_param(m *ice.Message, arg ...string) (string, string) {
repos, service := arg[0], kit.Select(arg[len(arg)-1], m.Option(SERVICE))
return _service_path(m, repos), strings.TrimPrefix(service, "git-")
}
func _service_repos(m *ice.Message, arg ...string) error {
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)
if service == RECEIVE_PACK && m.R.Method == http.MethodPost {
defer m.Cmd(Prefix(SERVICE), mdb.CREATE, mdb.NAME, path.Base(repos))
}
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))
_service_writer(m, "# service=git-"+service+lex.NL)
info = true
} else {
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)
if err != nil {
return err
}
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: out, Stderr: out}
stream := ServerCommand{Stdin: reader, Stdout: m.W, Stderr: m.W}
if service == RECEIVE_PACK {
defer m.Cmd(Prefix(SERVICE), mdb.CREATE, mdb.NAME, path.Base(repos))
return ServeReceivePack(info, stream, repos)
} else {
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 {
repos, service := _service_param(m, arg...)
m.Logs(m.R.Method, service, repos)
if m.Option(cli.CMD_DIR, repos); strings.HasSuffix(path.Join(arg...), INFO_REFS) {
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))
if m.Options(cli.CMD_DIR, repos, cli.CMD_OUTPUT, m.W); strings.HasSuffix(path.Join(arg...), INFO_REFS) {
_git_cmd(m, service, "--stateless-rpc", "--advertise-refs", nfs.PT)
return nil
}
if service == RECEIVE_PACK {
defer m.Cmd(Prefix(SERVICE), mdb.CREATE, mdb.NAME, path.Base(repos))
}
reader, err := _service_reader(m)
if err != nil {
return err
}
defer reader.Close()
web.RenderType(m.W, "", kit.Format("application/x-git-%s-result", service))
_git_cmd(m.Options(cli.CMD_INPUT, reader, cli.CMD_OUTPUT, m.W), service, "--stateless-rpc", nfs.PT)
_git_cmd(m.Options(cli.CMD_INPUT, reader), service, "--stateless-rpc", nfs.PT)
return nil
}
func _service_writer(m *ice.Message, cmd string, str ...string) {
@ -107,25 +100,21 @@ func _service_reader(m *ice.Message) (io.ReadCloser, error) {
const (
INFO_REFS = "info/refs"
RECEIVE_PACK = "receive-pack"
UPLOAD_PACK = "upload-pack"
RECEIVE_PACK = "receive-pack"
)
const SERVICE = "service"
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) {
if len(arg) == 0 {
return
}
if arg[0] == ice.LIST {
} else 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.Sort(nfs.REPOS)
return
} 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)))
return
}
@ -133,11 +122,9 @@ func init() {
case RECEIVE_PACK:
if !web.BasicCheck(m, "git server") {
return
}
if !nfs.Exists(m, repos) {
} else if !nfs.Exists(m, repos) {
m.Cmd(Prefix(SERVICE), mdb.CREATE, mdb.NAME, path.Base(repos))
}
case UPLOAD_PACK:
if mdb.Conf(m, Prefix(SERVICE), kit.Keym(aaa.AUTH)) == aaa.PRIVATE {
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]) })
}},
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)))
}},
mdb.REMOVE: {Hand: func(m *ice.Message, arg ...string) {
@ -164,51 +151,31 @@ func init() {
mdb.HashRemove(m, m.Option(REPOS))
nfs.Trash(m, _service_path(m, m.Option(REPOS)))
}},
RECEIVE_PACK: {Hand: func(m *ice.Message, arg ...string) {
if err := file.ServeReceivePack(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...)
}},
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) {
kit.If(arg[0] == REPOS, func() {
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"])
})
})
kit.If(arg[0] == REPOS, func() { mdb.HashSelect(m).Sort(REPOS).Cut("repos,version,time") })
}},
}, 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 {
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.PushScript(kit.Format("git clone %s", tcp.PublishLocalhost(m, kit.Split(web.MergeURL2(m, "/x/"+value[REPOS]+".git"), mdb.QS)[0])))
}).Sort(REPOS).Cmdy("web.code.publish", ice.CONTEXTS, ice.DEV)
m.PushScript(kit.Format("git clone %s", _service_link(m, value[REPOS])))
}).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) })
} else if len(arg) == 1 {
_repos_branch(m, _repos_open(m, arg[0]))
m.EchoScript(tcp.PublishLocalhost(m, kit.Split(web.MergeURL2(m, "/x/"+arg[0]), mdb.QS)[0]))
} else if repos := _repos_open(m, arg[0]); len(arg) == 1 {
defer m.PushScript(kit.Format("git clone %s", _service_link(m, arg[0])))
_repos_branch(m, repos)
} else if len(arg) == 2 {
repos := _repos_open(m, arg[0])
if iter, err := repos.Branches(); err == nil {
iter.ForEach(func(refer *plumbing.Reference) error {
if refer.Name().Short() == arg[1] {
_repos_log(m, refer.Hash(), repos)
}
kit.If(refer.Name().Short() == arg[1], func() { _repos_log(m, refer.Hash(), repos) })
return nil
})
}
} else if len(arg) == 3 {
if repos := _repos_open(m, arg[0]); arg[2] == INDEX {
if arg[2] == INDEX {
_repos_status(m, arg[0], repos)
} else {
_repos_stats(m, repos, arg[2])
@ -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 {
Stdout io.Writer
Stderr io.Writer
Stdout io.WriteCloser
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 {
if info {
ar, err := s.AdvertisedReferences()
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
return serveAdvertisedRefer(cmd, s)
}
req := packp.NewReferenceUpdateRequest()
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) {
ioutil.CheckClose(cmd.Stdout, &err)
if info {
ar, err := s.AdvertisedReferences()
if err != nil {
return err
}
if err := ar.Encode(cmd.Stdout); err != nil {
return err
}
return nil
return serveAdvertisedRefer(cmd, s)
}
req := packp.NewUploadPackRequest()
if err := req.Decode(cmd.Stdin); err != nil {
return err
}
resp, err := s.UploadPack(context.TODO(), req)
if err != nil {
} else if resp, err := s.UploadPack(context.TODO(), req); err != nil {
return err
} else {
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)
}
return resp.Encode(cmd.Stdout)
}

View File

@ -9,7 +9,6 @@ import (
"shylinux.com/x/icebergs/base/aaa"
"shylinux.com/x/icebergs/base/cli"
"shylinux.com/x/icebergs/base/ctx"
"shylinux.com/x/icebergs/base/lex"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
"shylinux.com/x/icebergs/base/tcp"
@ -18,87 +17,6 @@ import (
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"
func init() {
@ -107,46 +25,37 @@ func init() {
mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) {
switch m.Option(ctx.ACTION) {
case INIT:
switch arg[0] {
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("")))
})
}
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 INSTEADOF:
switch arg[0] {
case nfs.FROM:
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] {
case aaa.EMAIL:
m.Push(arg[0], _configs_get(m, USER_EMAIL), ice.Info.Make.Email)
case aaa.USERNAME:
m.Push(arg[0], kit.Select(m.Option(ice.MSG_USERNAME), _configs_get(m, USER_NAME)), ice.Info.Make.Username)
m.Cmd("web.spide", ice.OptionFields(web.CLIENT_ORIGIN), func(value ice.Maps) { m.Push(arg[0], value[web.CLIENT_ORIGIN]+"/x/") })
default:
m.Cmdy(REPOS, mdb.INPUTS, arg)
switch arg[0] {
case aaa.EMAIL:
m.Push(arg[0], _configs_get(m, USER_EMAIL), ice.Info.Make.Email)
case aaa.USERNAME:
m.Push(arg[0], kit.Select(m.Option(ice.MSG_USERNAME), _configs_get(m, USER_NAME)), ice.Info.Make.Username)
default:
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) {
m.Cmdy(REPOS, INIT)
}},
CONFIGS: {Name: "configs email* username* token", Help: "配置", Hand: func(m *ice.Message, arg ...string) {
m.Cmd(nfs.DEFS, kit.HomePath(".gitconfig"), kit.Format(nfs.Template(m, "gitconfig"), m.Option(aaa.USERNAME), m.Option(aaa.EMAIL)))
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") })
INSTEADOF: {Name: "insteadof remote", Help: "代理", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(REPOS, INSTEADOF, arg)
}},
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)))
}},
INSTEADOF: {Name: "insteadof remote", Help: "代理", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(REPOS, INSTEADOF, arg)
GITEA: {Help: "资源", Hand: func(m *ice.Message, arg ...string) {
m.ProcessOpen(m.Cmdv("web.spide", ice.HUB, web.CLIENT_URL))
}},
web.DREAM_TABLES: {Hand: func(m *ice.Message, arg ...string) {
if !kit.IsIn(m.Option(mdb.TYPE), web.WORKER, web.SERVER) {
@ -167,8 +76,7 @@ func init() {
}
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), mdb.ImportantHashAction()), Hand: func(m *ice.Message, arg ...string) {
}, aaa.RoleAction(), web.DreamAction(), Prefix(REPOS)), Hand: func(m *ice.Message, arg ...string) {
if len(arg) > 0 && arg[0] == ctx.ACTION {
m.Cmdy(REPOS, arg)
} else if config, err := config.LoadConfig(config.GlobalScope); err == nil && config.User.Email == "" && mdb.Config(m, aaa.EMAIL) == "" {
@ -180,7 +88,7 @@ func init() {
m.Cmdy(REPOS, STATUS).Action(PULL, PUSH, INSTEADOF, OAUTH, CONFIGS, GITEA)
m.Cmdy(code.PUBLISH, ice.CONTEXTS, ice.DEV)
} 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
alpha
input
ssh
vim
bash
tmux
vim
alpha
input
yac
lex
webview
chrome
coder
java
node
coder
chrome
github
wework
lark
wx
mp
wx

View File

@ -1 +0,0 @@
package misc

View File

@ -1,13 +1,9 @@
package node
import (
"path"
"shylinux.com/x/ice"
"shylinux.com/x/icebergs/base/cli"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
kit "shylinux.com/x/toolkits"
)
const NODE = "node"
@ -17,19 +13,15 @@ type node struct {
regexp string `data:"js"`
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"`
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) {
cli.IsAlpine(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) {
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) {
s.Code.Xterm(m, []string{mdb.TYPE, NODE}, arg...)

View File

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

View File

@ -99,12 +99,12 @@ func (c *Context) Register(s *Context, x Server, cmd ...string) *Context {
return s
}
func (c *Context) MergeCommands(Commands Commands) *Context {
// for key, cmd := range Commands {
for _, cmd := range Commands {
for key, cmd := range Commands {
// for _, cmd := range Commands {
if cmd.Hand == nil && cmd.RawHand == nil {
if cmd.RawHand = logs.FileLines(2); cmd.Actions != nil {
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)
}
}