1
0
mirror of https://shylinux.com/x/icebergs synced 2025-04-25 09:08:06 +08:00
This commit is contained in:
IT 老营长 @云轩领航-创始人 2023-04-15 00:26:30 +08:00
parent ee2bde3732
commit 4b37df12e3
18 changed files with 248 additions and 188 deletions

View File

@ -146,11 +146,19 @@ func (f *Frame) Begin(m *ice.Message, arg ...string) {
func (f *Frame) Start(m *ice.Message, arg ...string) {
m.Optionv(FRAME, f)
switch f.source = kit.Select(STDIO, arg, 0); f.source {
case STDIO:
case WEBIO:
wio := m.Optionv(WEBIO).(io.ReadWriter)
r, w, _ := os.Pipe()
go func() { io.Copy(w, wio) }()
f.pipe, f.stdin, f.stdout = w, r, wio
kit.If(f.target == nil, func() { f.target = m.Target() })
m.Optionv(ice.MSG_OPTS, ice.MSG_USERNAME, ice.MSG_USERROLE)
f.scan(m, STDIO, "")
case STDIO:
r, w, _ := os.Pipe()
go func() { io.Copy(w, os.Stdin) }()
f.pipe, f.stdin, f.stdout = w, r, os.Stdout
kit.If(f.target == nil, func() { f.target = m.Target() })
m.Optionv(ice.MSG_OPTS, ice.MSG_USERNAME, ice.MSG_USERROLE)
f.scan(m, STDIO, "")
default:
@ -162,15 +170,14 @@ func (f *Frame) Start(m *ice.Message, arg ...string) {
}
}
}
m.Option(ice.MSG_SCRIPT, f.source)
f.target = m.Source()
if msg := m.Cmd(nfs.CAT, f.source); msg.IsErr() {
if msg := m.Cmd(nfs.CAT, m.Option(ice.MSG_SCRIPT, f.source)); msg.IsErr() {
return
} else {
buf := bytes.NewBuffer(make([]byte, 0, ice.MOD_BUFS))
f.stdin, f.stdout = bytes.NewBufferString(msg.Result()), buf
defer func() { m.Echo(buf.String()) }()
}
f.target = m.Source()
f.scan(m, "", "")
}
}
@ -183,6 +190,7 @@ func (f *Frame) Spawn(m *ice.Message, c *ice.Context, arg ...string) ice.Server
const (
FRAME = "frame"
SHELL = "shell"
WEBIO = "webio"
STDIO = "stdio"
PS1 = "PS1"
PS2 = "PS2"
@ -215,8 +223,8 @@ func init() {
}
}},
PROMPT: {Name: "prompt arg run", Help: "命令提示", Actions: ctx.ConfAction(
PS1, ice.List{"\033[33;44m", mdb.COUNT, "@", tcp.HOSTNAME, "[", mdb.TIME, "]", "\033[5m", TARGET, "\033[0m", "\033[44m", ">", "\033[0m ", "\033[?25h", "\033[32m"},
PS2, ice.List{mdb.COUNT, " ", TARGET, "> "},
PS1, ice.List{"\033[33;44m", mdb.COUNT, ice.AT, tcp.HOSTNAME, "[", mdb.TIME, "]", "\033[5m", TARGET, "\033[0m", "\033[44m", ">", "\033[0m ", "\033[?25h", "\033[32m"},
PS2, ice.List{mdb.COUNT, ice.SP, TARGET, "> "},
), Hand: func(m *ice.Message, arg ...string) {
if f, ok := m.Target().Server().(*Frame); ok {
f.prompt(m, arg...)

View File

@ -140,6 +140,7 @@ func init() {
}, ctx.CmdAction(), DreamAction()), Hand: func(m *ice.Message, arg ...string) {
if len(arg) == 0 {
_dream_list(m)
ctx.DisplayTableCard(m)
} else if arg[0] == ctx.ACTION {
gdb.Event(m, DREAM_ACTION, arg)
} else {

View File

@ -9,7 +9,6 @@ import (
"shylinux.com/x/icebergs/base/ctx"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
"shylinux.com/x/icebergs/base/ssh"
"shylinux.com/x/icebergs/base/yac"
kit "shylinux.com/x/toolkits"
)
@ -101,6 +100,11 @@ func init() {
Index.MergeCommands(ice.Commands{
GO: {Name: "go path auto", Help: "后端编程", Actions: ice.MergeActions(ice.Actions{
mdb.RENDER: {Hand: func(m *ice.Message, arg ...string) {
if arg[1] == "main.go" {
// ProcessXterm(m, ssh.WEBIO, "", arg[1])
ProcessXterm(m, "ice.bin source stdio", "", arg[1])
return
}
ctx.ProcessCommand(m, yac.STACK, kit.Simple(path.Join(arg[2], arg[1])))
return
cmds, text := "ice.bin source stdio", ctx.GetFileCmd(path.Join(arg[2], arg[1]))
@ -113,18 +117,15 @@ func init() {
ProcessXterm(m, cmds, text, arg[1])
}},
mdb.ENGINE: {Hand: func(m *ice.Message, arg ...string) {
if cmd := ctx.GetFileCmd(path.Join(arg[2], arg[1])); cmd != "" {
ctx.ProcessCommand(m, cmd, kit.Simple())
return
}
if msg := m.Cmd(yac.STACK, path.Join(arg[2], arg[1])); msg.Option("__index") != "" {
ctx.ProcessCommand(m, msg.Option("__index"), kit.Simple())
} else {
ctx.ProcessCommand(m, yac.STACK, kit.Simple(path.Join(arg[2], arg[1])))
}
return
if cmd := ctx.GetFileCmd(path.Join(arg[2], arg[1])); cmd != "" {
ctx.ProcessCommand(m, cmd, kit.Simple())
} else {
cmds := []string{GO, ice.RUN, path.Join(arg[2], arg[1])}
m.Cmdy(cli.SYSTEM, cmds).StatusTime(ssh.SHELL, strings.Join(cmds, ice.SP))
}
}},
TEMPLATE: {Hand: func(m *ice.Message, arg ...string) {
m.Echo(nfs.Template(m, "demo.go"), path.Base(path.Dir(path.Join(arg[2], arg[1]))))

View File

@ -17,16 +17,17 @@ func init() {
Index.MergeCommands(ice.Commands{
JS: {Name: "js path auto", Help: "前端", Actions: ice.MergeActions(ice.Actions{
mdb.RENDER: {Hand: func(m *ice.Message, arg ...string) {
if arg[1] == "main.js" {
m.EchoIFrame(nfs.PS)
return
}
ProcessXterm(m, "node", kit.Format(`require("./usr/volcanos/proto.js"), require("./usr/volcanos/publish/client/nodejs/proto.js"), Volcanos.meta._main("%s")`, path.Join(nfs.PS, arg[2], arg[1])))
}},
mdb.ENGINE: {Hand: func(m *ice.Message, arg ...string) {
if arg[2] == ice.USR_VOLCANOS {
m.Debug("what %v %v", arg[1], ice.PLUGIN_LOCAL)
if strings.HasPrefix(arg[1], "plugin/local/") {
ctx.ProcessCommand(m, kit.Select(ice.CAN_PLUGIN, "web."+strings.Replace(strings.TrimSuffix(strings.TrimPrefix(arg[1], "plugin/local/"), nfs.PT+JS), nfs.PS, nfs.PT, -1)), kit.Simple())
m.Debug("what %v", m.FormatMeta())
}
m.Debug("what %v", m.FormatMeta())
} else {
ctx.DisplayBase(m, require(arg[2], arg[1]))
ctx.ProcessCommand(m, kit.Select(ice.CAN_PLUGIN, ctx.GetFileCmd(kit.ExtChange(path.Join(arg[2], arg[1]), GO))), kit.Simple())

View File

@ -17,7 +17,7 @@ import (
kit "shylinux.com/x/toolkits"
)
func _xterm_get(m *ice.Message, h string) xterm.XTerm {
func _xterm_get(m *ice.Message, h string) *xterm.XTerm {
h = kit.Select(m.Option(mdb.HASH), h)
m.Assert(h != "")
mdb.HashModify(m, mdb.TIME, m.Time(), web.VIEW, m.Option(ice.MSG_DAEMON))
@ -25,7 +25,7 @@ func _xterm_get(m *ice.Message, h string) xterm.XTerm {
text := strings.Split(value[mdb.TEXT], ice.NL)
ls := kit.Split(strings.Split(kit.Select(nfs.SH, value[mdb.TYPE]), " # ")[0])
kit.If(value[nfs.PATH] != "" && !strings.HasSuffix(value[nfs.PATH], nfs.PS), func() { value[nfs.PATH] = path.Dir(value[nfs.PATH]) })
term, e := xterm.Command(m, value[nfs.PATH], cli.SystemFind(m, ls[0]), ls[1:]...)
term, e := xterm.Command(m, value[nfs.PATH], kit.Select(ls[0], cli.SystemFind(m, ls[0])), ls[1:]...)
if m.Warn(e) {
return nil
}
@ -52,7 +52,7 @@ func _xterm_get(m *ice.Message, h string) xterm.XTerm {
}
})
return term
}).(xterm.XTerm)
}).(*xterm.XTerm)
}
func _xterm_echo(m *ice.Message, h string, str string) {
m.Options(ice.MSG_DAEMON, mdb.HashSelectField(m, h, web.VIEW))
@ -123,7 +123,7 @@ func init() {
m.PushAction(web.OUTPUT, mdb.REMOVE).Action(mdb.CREATE, mdb.PRUNES)
} else {
if m.Length() == 0 {
arg[0] = m.Cmdx("", mdb.CREATE, arg)
arg[0] = m.Cmdx("", mdb.CREATE, mdb.TYPE, arg)
mdb.HashSelect(m, arg[0])
}
m.Push(mdb.HASH, arg[0])

View File

@ -6,6 +6,7 @@ import (
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/aaa"
"shylinux.com/x/icebergs/base/ctx"
"shylinux.com/x/icebergs/base/log"
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/web"
kit "shylinux.com/x/toolkits"
@ -61,6 +62,11 @@ func init() {
mdb.INSERT: {Name: "insert zone* type=once,step,week name* text begin_time@date close_time@date", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(TASK, mdb.INSERT, arg)
}},
mdb.SEARCH: {Hand: func(m *ice.Message, arg ...string) {
if arg[0] == mdb.FOREACH && arg[1] == "" {
m.PushSearch(mdb.TYPE, web.LINK, mdb.NAME, m.CommandKey(), mdb.TEXT, m.MergePodCmd("", "", log.DEBUG, ice.TRUE))
}
}},
ice.RUN: {Hand: func(m *ice.Message, arg ...string) {
if m.RenameOption(TASK_POD, ice.POD); ctx.PodCmd(m, m.PrefixKey(), ice.RUN, arg) {
return

View File

@ -16,7 +16,7 @@ const DRAW = "draw"
func init() {
Index.MergeCommands(ice.Commands{
DRAW: {Name: "draw path=src/main.svg@key pid refresh save edit actions", Help: "思维导图", Actions: ice.MergeActions(ice.Actions{
DRAW: {Name: "draw path=src/main.svg@key pid refresh save actions", Help: "思维导图", Actions: ice.MergeActions(ice.Actions{
ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {
m.Cmd(mdb.RENDER, mdb.CREATE, mdb.TYPE, nfs.SVG, mdb.NAME, m.PrefixKey())
}},

1
go.mod
View File

@ -3,7 +3,6 @@ module shylinux.com/x/icebergs
go 1.11
require (
shylinux.com/x/creackpty v0.0.2
shylinux.com/x/go-qrcode v0.0.2
shylinux.com/x/gogit v0.0.7
shylinux.com/x/ice v1.3.0

2
go.sum
View File

@ -1,5 +1,3 @@
shylinux.com/x/creackpty v0.0.2 h1:1ekWD5zeKZiQZCYvKSkHnm819wryZxzoq3kmvheC7bA=
shylinux.com/x/creackpty v0.0.2/go.mod h1:SOsAaW5FdicXUprrxgENk2JP1f8LdHBXZjqOFot488o=
shylinux.com/x/go-qrcode v0.0.2 h1:/c0PLj+1RT+kUPfnZVXwgbgH5m1SxBUjM2MIKXbDk+E=
shylinux.com/x/go-qrcode v0.0.2/go.mod h1:TlzGBENHXy19xC3AsC6h4Vs5fx2ZuDA4TZ0U3C2OeK4=
shylinux.com/x/gogit v0.0.7 h1:2ep5QpXWLs0UBCywJuUHda/aagskYvFmn0nj3vpEdY4=

View File

@ -19,6 +19,12 @@ func _git_url(m *ice.Message, repos string) string {
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)
}
const GIT = "git"

View File

@ -19,8 +19,7 @@ func _repos_path(name string) string {
return kit.Select(path.Join(ice.USR, name)+ice.PS, nfs.PWD, name == path.Base(kit.Pwd()))
}
func _repos_cmd(m *ice.Message, name string, arg ...string) *ice.Message {
m.Option(cli.CMD_DIR, _repos_path(name))
return m.Copy(_git_cmd(m, arg...))
return m.Copy(_git_cmd(m.Options(cli.CMD_DIR, _repos_path(name)), arg...))
}
func _repos_init(m *ice.Message, dir string) string {
os.MkdirAll(path.Join(dir, REFS_HEADS), ice.MOD_DIR)
@ -30,15 +29,11 @@ func _repos_init(m *ice.Message, dir string) string {
func _repos_insert(m *ice.Message, name string, path string) bool {
if repos, e := gogit.OpenRepository(_git_dir(path)); e == nil {
origin := kit.Select("", kit.Split(repos.GetOrigin()), -1)
if origin == "" {
origin = _configs_read(m, _git_dir(path, "config"))["remote.origin.url"]
}
kit.If(origin == "", func() { origin = _configs_read(m, _git_dir(path, "config"))["remote.origin.url"] })
if ci, e := repos.GetCommit(); e == nil {
mdb.HashCreate(m, REPOS, name, nfs.PATH, path, mdb.TIME, ci.Author.When.Format(ice.MOD_TIME), COMMIT, strings.TrimSpace(ci.Message),
BRANCH, repos.GetBranch(), ORIGIN, origin)
mdb.HashCreate(m, REPOS, name, nfs.PATH, path, mdb.TIME, ci.Author.When.Format(ice.MOD_TIME), COMMIT, strings.TrimSpace(ci.Message), BRANCH, repos.GetBranch(), ORIGIN, origin)
} else {
mdb.HashCreate(m, REPOS, name, nfs.PATH, path, mdb.TIME, m.Time(),
BRANCH, repos.GetBranch(), ORIGIN, origin)
mdb.HashCreate(m, REPOS, name, nfs.PATH, path, mdb.TIME, m.Time(), BRANCH, repos.GetBranch(), ORIGIN, origin)
}
return true
}
@ -215,9 +210,9 @@ func init() {
if p = path.Join(ice.USR_REQUIRE, path.Join(arg...)); !nfs.Exists(m, p) {
ls := strings.SplitN(path.Join(arg[:3]...), ice.AT, 2)
if v := kit.Select(ice.Info.Gomod[ls[0]], ls, 1); v == "" {
m.Cmd(cli.SYSTEM, "git", "clone", "https://"+ls[0], path.Join(ice.USR_REQUIRE, path.Join(arg[:3]...)))
_git_cmd(m, "clone", "https://"+ls[0], path.Join(ice.USR_REQUIRE, path.Join(arg[:3]...)))
} else {
m.Cmd(cli.SYSTEM, "git", "clone", "-b", v, "https://"+ls[0], path.Join(ice.USR_REQUIRE, path.Join(arg[:3]...)))
_git_cmd(m, "clone", "-b", v, "https://"+ls[0], path.Join(ice.USR_REQUIRE, path.Join(arg[:3]...)))
}
}
}
@ -256,7 +251,7 @@ func init() {
}},
INIT: {Hand: func(m *ice.Message, arg ...string) {
if dir := _repos_init(m, _git_dir(m.Option(cli.CMD_DIR))); m.Option(ORIGIN, kit.Select("", kit.Split(m.Option(ORIGIN)), -1)) != "" {
m.Cmd(nfs.SAVE, path.Join(dir, CONFIG), kit.Format(_repos_config, m.Option(ORIGIN)))
m.Cmd(nfs.SAVE, path.Join(dir, CONFIG), kit.Format(nfs.TemplateText(m, CONFIG), m.Option(ORIGIN)))
_git_cmd(m, PULL, ORIGIN, m.OptionDefault(BRANCH, MASTER))
}
}},
@ -268,7 +263,7 @@ func init() {
_repos_dir(m, dir, m.Option(BRANCH), m.Option(COMMIT), kit.Select("", arg, 1), nil)
} else {
_repos_cat(m, dir, m.Option(BRANCH), m.Option(COMMIT), arg[2])
ctx.DisplayLocal(m, "code/inner.js")
// ctx.DisplayLocal(m, "code/inner.js")
}
return
}
@ -292,12 +287,3 @@ func init() {
})
}
func ReposList(m *ice.Message) *ice.Message { return m.Cmd(REPOS, ice.OptionFields("repos,path")) }
var _repos_config = `
[remote "origin"]
url = %s
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
`

View File

@ -15,7 +15,6 @@ import (
"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,52 +33,6 @@ func _status_tag(m *ice.Message, tags string) string {
return "v0.0.1"
}
}
func _status_tags(m *ice.Message) {
vs := ice.Maps{}
m.Cmd(STATUS, func(value ice.Maps) {
if value[mdb.TYPE] == "##" {
if value[REPOS] == ice.RELEASE {
value[REPOS] = ice.ICE
}
vs[value[REPOS]] = strings.Split(value[TAGS], "-")[0]
}
})
web.GoToast(m, TAGS, func(toast func(string, int, int)) {
count, total := 0, len(vs)
defer toast(ice.SUCCESS, count, count)
for k := range vs {
if count++; k == ice.ICE {
k = ice.RELEASE
}
change := false
toast(k, count, total)
m.Option(nfs.DIR_ROOT, _repos_path(k))
mod := m.Cmdx(nfs.CAT, ice.GO_MOD, func(text string, line int) string {
ls := kit.Split(strings.TrimPrefix(text, ice.REQUIRE))
if len(ls) < 2 || !strings.Contains(ls[0], ice.PS) || !strings.Contains(ls[1], ice.PT) {
return text
}
if v, ok := vs[kit.Select("", strings.Split(ls[0], ice.PS), -1)]; ok && ls[1] != v {
m.Logs(mdb.MODIFY, REPOS, ls[0], nfs.FROM, ls[1], nfs.TO, v)
text, change = strings.Replace(text, ls[1], v, -1), true
}
return text
})
if mod == "" || !change {
continue
}
m.Cmd(nfs.SAVE, ice.GO_MOD, mod)
switch m.Option(cli.CMD_DIR, _repos_path(k)); k {
case ice.RELEASE, ice.ICEBERGS, ice.TOOLKITS:
m.Cmd(cli.SYSTEM, code.GO, cli.BUILD)
case ice.CONTEXTS:
defer m.Cmd(cli.SYSTEM, cli.MAKE)
default:
m.Cmd(cli.SYSTEM, cli.MAKE)
}
}
})
}
func _status_each(m *ice.Message, title string, cmds ...string) {
web.GoToast(m, kit.Select(strings.Join(cmds, ice.SP), title), func(toast func(string, int, int)) {
list, count, total := []string{}, 0, m.Cmd(REPOS).Length()
@ -87,8 +40,8 @@ func _status_each(m *ice.Message, title string, cmds ...string) {
toast(value[REPOS], count, total)
if msg := m.Cmd(cmds, kit.Dict(cli.CMD_DIR, value[nfs.PATH])); !cli.IsSuccess(msg) {
web.Toast(m, msg.Append(cli.CMD_ERR)+msg.Append(cli.CMD_OUT), "error: "+value[REPOS], "", "3s")
m.Sleep3s()
list = append(list, value[REPOS])
m.Sleep3s()
}
count++
})
@ -100,7 +53,7 @@ func _status_each(m *ice.Message, title string, cmds ...string) {
})
}
func _status_stat(m *ice.Message, files, adds, dels int) (int, int, int) {
kit.SplitKV(ice.SP, ice.FS, _git_cmds(m, DIFF, "--shortstat"), func(text string, ls []string) {
kit.SplitKV(ice.SP, ice.FS, _git_diff(m), func(text string, ls []string) {
n := kit.Int(ls[0])
switch {
case strings.Contains(text, "file"):
@ -114,7 +67,7 @@ func _status_stat(m *ice.Message, files, adds, dels int) (int, int, int) {
return files, adds, dels
}
func _status_list(m *ice.Message) (files, adds, dels int, last time.Time) {
onlychange := m.Option(ice.MSG_MODE) == mdb.ZONE || m.Option("view") == "change"
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])
@ -124,8 +77,8 @@ func _status_list(m *ice.Message) (files, adds, dels int, last time.Time) {
last = ci.Author.When
}
}
tags := _git_cmds(m, "describe", "--tags")
kit.SplitKV(ice.SP, ice.NL, _git_cmds(m, STATUS, "-sb"), func(text string, ls []string) {
tags := _git_tags(m)
kit.SplitKV(ice.SP, ice.NL, _git_status(m), func(text string, ls []string) {
switch kit.Ext(ls[1]) {
case "swp", "swo", ice.BIN, ice.VAR:
return
@ -134,8 +87,7 @@ func _status_list(m *ice.Message) (files, adds, dels int, last time.Time) {
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(" ", len(ls[0])-9), kit.Select("", ice.USR+ice.PS+value[REPOS]+ice.PS, value[REPOS] != ice.CONTEXTS)+ls[1]))
m.Push(nfs.PATH, value[nfs.PATH]).Push(mdb.VIEW, kit.Format("%s %s", ls[0]+strings.Repeat(ice.SP, len(ls[0])-9), kit.Select("", nfs.USR+value[REPOS]+nfs.PS, value[REPOS] != ice.CONTEXTS)+ls[1]))
}
switch ls[0] {
case "##":
@ -168,9 +120,8 @@ const (
ADD = "add"
OPT = "opt"
PRO = "pro"
FIX = "fix"
TAG = "tag"
PIE = "pie"
COMMENT = "comment"
VERSION = "version"
@ -199,7 +150,7 @@ func init() {
m.Push(arg[0], kit.Join(kit.Slice(ls, -1), ice.PS))
m.Push(arg[0], kit.Join(kit.Slice(ls, -2), ice.PS))
m.Push(arg[0], m.Option(nfs.FILE))
case VERSION, TAGS:
case VERSION:
m.Push(VERSION, _status_tag(m, m.Option(TAGS)))
case aaa.EMAIL:
m.Push(arg[0], _configs_get(m, USER_EMAIL), ice.Info.Make.Email)
@ -220,95 +171,36 @@ func init() {
m.Sleep3s()
}},
PUSH: {Help: "上传", Hand: func(m *ice.Message, arg ...string) {
if m.Option(REPOS) == "" {
_status_each(m, "", cli.SYSTEM, GIT, PUSH)
_status_each(m, "", cli.SYSTEM, GIT, PUSH, "--tags")
m.Sleep3s()
return
}
m.Option(cli.CMD_DIR, _repos_path(m.Option(REPOS)))
if strings.TrimSpace(_git_cmds(m, "rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{u}")) == "" {
_git_cmd(m, PUSH, "--set-upstream", ORIGIN, MASTER)
} else {
_git_cmd(m, PUSH)
}
_git_cmd(m, PUSH, "--tags")
_status_each(m, "", cli.SYSTEM, GIT, PUSH)
_status_each(m, "", cli.SYSTEM, GIT, PUSH, "--tags")
m.Sleep3s()
}},
ADD: {Help: "添加", Hand: func(m *ice.Message, arg ...string) {
_repos_cmd(m, m.Option(REPOS), ADD, m.Option(nfs.FILE))
}}, OPT: {Help: "优化"}, PRO: {Help: "升级"},
COMMIT: {Name: "commit action=opt,add,pro comment=some", Help: "提交", Hand: func(m *ice.Message, arg ...string) {
ADD: {Help: "添加", Hand: func(m *ice.Message, arg ...string) { _repos_cmd(m, m.Option(REPOS), ADD, m.Option(nfs.FILE)) }}, OPT: {Help: "优化"}, FIX: {Help: "修复"},
COMMIT: {Name: "commit action=add,opt,fix comment=some", Help: "提交", Hand: func(m *ice.Message, arg ...string) {
_repos_cmd(m, m.Option(REPOS), COMMIT, "-am", m.Option(ctx.ACTION)+ice.SP+m.Option(COMMENT))
m.ProcessBack()
}},
PIE: {Help: "饼图", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(TOTAL, PIE) }},
TAG: {Name: "tag version", Help: "标签", Hand: func(m *ice.Message, arg ...string) {
if m.Option(VERSION) == "" {
m.Option(VERSION, _status_tag(m, m.Option(TAGS)))
}
kit.If(m.Option(VERSION) == "", func() { m.Option(VERSION, _status_tag(m, m.Option(TAGS))) })
_repos_cmd(m, m.Option(REPOS), TAG, m.Option(VERSION))
_repos_cmd(m, m.Option(REPOS), PUSH, "--tags")
ctx.ProcessRefresh(m)
}},
TAGS: {Help: "标签", Hand: func(m *ice.Message, arg ...string) { _status_tags(m) }},
STASH: {Help: "缓存", Hand: func(m *ice.Message, arg ...string) {
if len(arg) == 0 && m.Option(REPOS) == "" {
_status_each(m, STASH, cli.SYSTEM, GIT, STASH)
} else {
_repos_cmd(m, kit.Select(m.Option(REPOS), arg, 0), STASH)
}
}},
BRANCH: {Help: "分支", Hand: func(m *ice.Message, arg ...string) {
for _, line := range kit.Split(_repos_cmd(m.Spawn(), arg[0], BRANCH).Result(), ice.NL, ice.NL) {
if strings.HasPrefix(line, "*") {
m.Push(BRANCH, strings.TrimPrefix(line, "* ")).PushButton("")
} else {
m.Push(BRANCH, strings.TrimSpace(line)).PushButton("branch_switch")
}
}
}},
"insteadof": {Name: "insteadof from* to", Help: "代理", Hand: func(m *ice.Message, arg ...string) {
m.Cmd(CONFIGS, func(value ice.Maps) {
if value[mdb.VALUE] == m.Option(nfs.FROM) {
_configs_set(m, "--unset", value[mdb.NAME])
}
})
if m.Option(nfs.TO) != "" {
_git_cmd(m, "config", "--global", "url."+m.Option(nfs.TO)+".insteadof", m.Option(nfs.FROM))
}
}},
"oauth": {Help: "授权", Hand: func(m *ice.Message, arg ...string) {
m.ProcessOpen(kit.MergeURL2(kit.Select(ice.Info.Make.Remote, m.Cmdx(cli.SYSTEM, "git", "remote", "get-url", "origin")), "/chat/cmd/web.code.git.token",
aaa.USERNAME, m.Option(ice.MSG_USERNAME), tcp.HOST, web.UserHost(m)))
}},
"token": {Name: "token token", Help: "令牌", Hand: func(m *ice.Message, arg ...string) {
list := []string{m.Option(TOKEN)}
m.Cmd(nfs.CAT, kit.HomePath(".git-credentials"), func(line string) { list = append(list, line) })
m.Cmd(nfs.SAVE, kit.HomePath(".git-credentials"), strings.Join(list, ice.NL)+ice.NL)
ctx.ProcessHold(m)
}},
"branch_switch": {Help: "切换", Hand: func(m *ice.Message, arg ...string) {
_repos_cmd(m, m.Option(REPOS), "checkout", m.Option(BRANCH))
_repos_cmd(m, kit.Select(m.Option(REPOS), arg, 0), STASH)
}},
nfs.TRASH: {Hand: func(m *ice.Message, arg ...string) {
m.Assert(m.Option(REPOS) != "" && m.Option(nfs.FILE) != "")
nfs.Trash(m, path.Join(_repos_path(m.Option(REPOS)), m.Option(nfs.FILE)))
}},
code.COMPILE: {Help: "编译", Hand: func(m *ice.Message, arg ...string) {
defer web.ToastProcess(m)()
m.Cmdy(code.VIMER, code.COMPILE)
"insteadof": {Name: "insteadof from* to", Help: "代理", Hand: func(m *ice.Message, arg ...string) {
m.Cmd(CONFIGS, func(value ice.Maps) {
kit.If(value[mdb.VALUE] == m.Option(nfs.FROM), func() { _configs_set(m, "--unset", value[mdb.NAME]) })
})
kit.If(m.Option(nfs.TO), func() { _git_cmd(m, CONFIG, "--global", "url."+m.Option(nfs.TO)+".insteadof", m.Option(nfs.FROM)) })
}},
code.PUBLISH: {Help: "发布", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(code.PUBLISH, ice.CONTEXTS, ice.MISC, ice.CORE)
}},
code.BINPACK: {Help: "发布模式", Hand: func(m *ice.Message, arg ...string) {
m.Cmd(nfs.LINK, ice.GO_SUM, path.Join(ice.SRC_RELEASE, ice.GO_SUM))
m.Cmd(nfs.LINK, ice.GO_MOD, path.Join(ice.SRC_RELEASE, ice.GO_MOD))
m.Cmdy(nfs.CAT, ice.GO_MOD)
m.Cmdy(code.VIMER, code.BINPACK)
}},
code.DEVPACK: {Help: "开发模式", Hand: func(m *ice.Message, arg ...string) {
m.Cmdy(code.VIMER, code.DEVPACK)
"oauth": {Help: "授权", Hand: func(m *ice.Message, arg ...string) {
m.ProcessOpen(kit.MergeURL2(kit.Select(ice.Info.Make.Remote, _git_remote(m)), "/chat/cmd/web.code.git.token", aaa.USERNAME, m.Option(ice.MSG_USERNAME), tcp.HOST, web.UserHost(m)))
}},
web.DREAM_TABLES: {Hand: func(m *ice.Message, arg ...string) {
if m.Option(mdb.TYPE) != web.WORKER {
@ -326,19 +218,18 @@ func init() {
}
m.Push(mdb.TEXT, strings.Join(text, ", "))
}},
}, gdb.EventAction(web.DREAM_TABLES), ctx.CmdAction(), aaa.RoleAction()), Hand: func(m *ice.Message, arg ...string) {
}, gdb.EventAction(web.DREAM_TABLES), aaa.RoleAction()), Hand: func(m *ice.Message, arg ...string) {
if _configs_get(m, USER_EMAIL) == "" {
m.Echo("please config user.email").Action(CONFIGS)
} else if len(arg) == 0 {
files, adds, dels, last := _status_list(m)
m.StatusTimeCount("files", files, "adds", adds, "dels", dels, "last", last.Format(ice.MOD_TIME), "origin", _git_cmds(m, "remote", "get-url", "origin"))
m.Action(PULL, PUSH, "insteadof", "oauth")
m.Sort("repos,type,file")
m.StatusTimeCount("files", files, "adds", adds, "dels", dels, "last", last.Format(ice.MOD_TIME), nfs.ORIGIN, _git_remote(m))
m.Action(PULL, PUSH, "insteadof", "oauth").Sort("repos,type,file")
} else {
_repos_cmd(m, arg[0], DIFF)
files, adds, dels := _status_stat(m, 0, 0, 0)
m.StatusTime("files", files, "adds", adds, "dels", dels)
m.Action(COMMIT, TAGS, STASH, BRANCH)
m.Action(COMMIT, STASH)
}
}},
})

View File

@ -29,7 +29,7 @@ func init() {
)
Index.MergeCommands(ice.Commands{
TOTAL: {Name: "total repos auto pie", Help: "统计量", Actions: ice.MergeActions(ice.Actions{
PIE: {Help: "饼图", Hand: func(m *ice.Message, arg ...string) {
"pie": {Help: "饼图", Hand: func(m *ice.Message, arg ...string) {
defer ctx.DisplayStory(m, "pie.js")
m.Cmd("", func(value ice.Maps) {
if value[REPOS] != mdb.TOTAL {

65
misc/xterm/pty_darwin.go Normal file
View File

@ -0,0 +1,65 @@
//go:build darwin
// +build darwin
package xterm
import (
"errors"
"os"
"syscall"
"unsafe"
kit "shylinux.com/x/toolkits"
)
func open() (pty, tty *os.File, err error) {
pFD, err := syscall.Open("/dev/ptmx", syscall.O_RDWR|syscall.O_CLOEXEC, 0)
if err != nil {
return nil, nil, err
}
p := os.NewFile(uintptr(pFD), "/dev/ptmx")
defer func() { kit.If(err != nil, func() { _ = p.Close() }) }()
sname, err := ptsname(p)
if err != nil {
return nil, nil, err
}
if err := grantpt(p); err != nil {
return nil, nil, err
}
if err := unlockpt(p); err != nil {
return nil, nil, err
}
t, err := os.OpenFile(sname, os.O_RDWR|syscall.O_NOCTTY, 0)
if err != nil {
return nil, nil, err
}
return p, t, nil
}
func ptsname(f *os.File) (string, error) {
n := make([]byte, _IOC_PARM_LEN(syscall.TIOCPTYGNAME))
err := ioctl(f.Fd(), syscall.TIOCPTYGNAME, uintptr(unsafe.Pointer(&n[0])))
if err != nil {
return "", err
}
for i, c := range n {
if c == 0 {
return string(n[:i]), nil
}
}
return "", errors.New("TIOCPTYGNAME string not NUL-terminated")
}
func grantpt(f *os.File) error { return ioctl(f.Fd(), syscall.TIOCPTYGRANT, 0) }
func unlockpt(f *os.File) error { return ioctl(f.Fd(), syscall.TIOCPTYUNLK, 0) }
const (
_IOC_VOID uintptr = 0x20000000
_IOC_OUT uintptr = 0x40000000
_IOC_IN uintptr = 0x80000000
_IOC_IN_OUT uintptr = _IOC_OUT | _IOC_IN
_IOC_DIRMASK = _IOC_VOID | _IOC_OUT | _IOC_IN
_IOC_PARAM_SHIFT = 13
_IOC_PARAM_MASK = (1 << _IOC_PARAM_SHIFT) - 1
)
func _IOC_PARM_LEN(ioctl uintptr) uintptr { return (ioctl >> 16) & _IOC_PARAM_MASK }

47
misc/xterm/pty_linux.go Normal file
View File

@ -0,0 +1,47 @@
//go:build linux
// +build linux
package xterm
import (
"os"
"strconv"
"syscall"
"unsafe"
kit "shylinux.com/x/toolkits"
)
func open() (*os.File, *os.File, error) {
p, err := os.OpenFile("/dev/ptmx", os.O_RDWR, 0)
if err != nil {
return nil, nil, err
}
defer func() { kit.If(err != nil, func() { _ = p.Close() }) }()
sname, err := ptsname(p)
if err != nil {
return nil, nil, err
}
if err := unlockpt(p); err != nil {
return nil, nil, err
}
t, err := os.OpenFile(sname, os.O_RDWR|syscall.O_NOCTTY, 0)
if err != nil {
return nil, nil, err
}
return p, t, nil
}
func ptsname(f *os.File) (string, error) {
var n uint32
err := ioctl(f.Fd(), syscall.TIOCGPTN, uintptr(unsafe.Pointer(&n)))
if err != nil {
return "", err
}
return "/dev/pts/" + strconv.Itoa(int(n)), nil
}
func unlockpt(f *os.File) error {
var u int32
return ioctl(f.Fd(), syscall.TIOCSPTLCK, uintptr(unsafe.Pointer(&u)))
}

View File

@ -0,0 +1,27 @@
//go:build !windows
// +build !windows
package xterm
import (
"os"
"syscall"
"unsafe"
)
func Setsize(t *os.File, ws *Winsize) error {
return ioctl(t.Fd(), syscall.TIOCSWINSZ, uintptr(unsafe.Pointer(ws)))
}
const (
TIOCGWINSZ = syscall.TIOCGWINSZ
TIOCSWINSZ = syscall.TIOCSWINSZ
)
func ioctl(fd, cmd, ptr uintptr) error {
_, _, e := syscall.Syscall(syscall.SYS_IOCTL, fd, cmd, ptr)
if e != 0 {
return e
}
return nil
}

View File

@ -0,0 +1,12 @@
//go:build windows
// +build windows
package pty
import (
"errors"
"os"
)
func Setsize(*os.File, *Winsize) error { return errors.New("unsupported") }
func open() (pty, tty *os.File, err error) { return nil, nil, errors.New("unsuported") }

View File

@ -3,20 +3,27 @@ package xterm
import (
"os"
"os/exec"
"syscall"
pty "shylinux.com/x/creackpty"
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/nfs"
kit "shylinux.com/x/toolkits"
)
type Winsize struct {
Rows uint16 // ws_row: Number of rows (in cells)
Cols uint16 // ws_col: Number of columns (in cells)
X uint16 // ws_xpixel: Width in pixels
Y uint16 // ws_ypixel: Height in pixels
}
type XTerm struct {
*exec.Cmd
*os.File
}
func (s XTerm) Setsize(rows, cols string) error {
return pty.Setsize(s.File, &pty.Winsize{Rows: uint16(kit.Int(rows)), Cols: uint16(kit.Int(cols))})
return Setsize(s.File, &Winsize{Rows: uint16(kit.Int(rows)), Cols: uint16(kit.Int(cols))})
}
func (s XTerm) Writeln(data string, arg ...ice.Any) {
s.Write(kit.Format(data, arg...) + ice.NL)
@ -27,11 +34,16 @@ func (s XTerm) Write(data string) (int, error) {
func (s XTerm) Close() error {
return s.Cmd.Process.Kill()
}
func Command(m *ice.Message, dir string, cli string, arg ...string) (XTerm, error) {
func Command(m *ice.Message, dir string, cli string, arg ...string) (*XTerm, error) {
cmd := exec.Command(cli, arg...)
cmd.Dir = nfs.MkdirAll(m, kit.Path(dir))
cmd.Env = append(cmd.Env, os.Environ()...)
cmd.Env = append(cmd.Env, "TERM=xterm")
tty, err := pty.Start(cmd)
return XTerm{cmd, tty}, err
cmd.SysProcAttr = &syscall.SysProcAttr{Setsid: true, Setctty: true}
pty, tty, err := open()
if err != nil {
return nil, err
}
cmd.Stdin, cmd.Stdout, cmd.Stderr = tty, tty, tty
return &XTerm{cmd, pty}, cmd.Start()
}