forked from x/icebergs
opt git
This commit is contained in:
parent
8fa1b390e5
commit
83c959a14e
@ -2,10 +2,7 @@ package code
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
ice "shylinux.com/x/icebergs"
|
ice "shylinux.com/x/icebergs"
|
||||||
"shylinux.com/x/icebergs/base/cli"
|
|
||||||
"shylinux.com/x/icebergs/base/nfs"
|
"shylinux.com/x/icebergs/base/nfs"
|
||||||
"shylinux.com/x/icebergs/base/web"
|
|
||||||
kit "shylinux.com/x/toolkits"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -15,9 +12,6 @@ const REPOS = nfs.REPOS
|
|||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
Index.MergeCommands(ice.Commands{REPOS: {Name: "repos name auto", Actions: ice.Actions{
|
Index.MergeCommands(ice.Commands{REPOS: {Name: "repos name auto", Actions: ice.Actions{
|
||||||
web.DREAM_CREATE: {Hand: func(m *ice.Message, arg ...string) {
|
|
||||||
kit.If(m.Option(nfs.REPOS), func(p string) { m.Cmd(cli.SYSTEM, GIT, "clone", p, m.Option(cli.CMD_DIR), ice.Maps{cli.CMD_DIR: ""}) })
|
|
||||||
}},
|
|
||||||
"status": {Hand: func(m *ice.Message, arg ...string) { m.Cmdy("web.code.git.status", arg) }},
|
"status": {Hand: func(m *ice.Message, arg ...string) { m.Cmdy("web.code.git.status", arg) }},
|
||||||
}, Hand: func(m *ice.Message, arg ...string) { m.Cmdy("web.code.git.repos", arg) }}})
|
}, Hand: func(m *ice.Message, arg ...string) { m.Cmdy("web.code.git.repos", arg) }}})
|
||||||
}
|
}
|
||||||
|
2
go.mod
2
go.mod
@ -3,8 +3,8 @@ module shylinux.com/x/icebergs
|
|||||||
go 1.11
|
go 1.11
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
shylinux.com/x/go-git/v5 v5.6.2
|
||||||
shylinux.com/x/go-qrcode 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
|
shylinux.com/x/ice v1.3.0
|
||||||
shylinux.com/x/toolkits v0.7.5
|
shylinux.com/x/toolkits v0.7.5
|
||||||
shylinux.com/x/websocket v0.0.2
|
shylinux.com/x/websocket v0.0.2
|
||||||
|
@ -31,6 +31,7 @@ func _configs_read(m *ice.Message, p string) ice.Maps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
CONFIG = "config"
|
||||||
USER_NAME = "user.name"
|
USER_NAME = "user.name"
|
||||||
USER_EMAIL = "user.email"
|
USER_EMAIL = "user.email"
|
||||||
)
|
)
|
||||||
|
@ -40,3 +40,5 @@ var Index = &ice.Context{Name: GIT, Help: "代码库", Commands: ice.Commands{
|
|||||||
}}
|
}}
|
||||||
|
|
||||||
func init() { code.Index.Register(Index, &web.Frame{}, REPOS) }
|
func init() { code.Index.Register(Index, &web.Frame{}, REPOS) }
|
||||||
|
|
||||||
|
func Prefix(arg ...string) string { return code.Prefix(GIT, kit.Keys(arg)) }
|
||||||
|
@ -1,172 +1,198 @@
|
|||||||
package git
|
package git
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"errors"
|
||||||
|
"net/url"
|
||||||
"path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"shylinux.com/x/gogit"
|
git "shylinux.com/x/go-git/v5"
|
||||||
|
"shylinux.com/x/go-git/v5/plumbing"
|
||||||
|
"shylinux.com/x/go-git/v5/plumbing/object"
|
||||||
|
"shylinux.com/x/go-git/v5/plumbing/transport/http"
|
||||||
|
|
||||||
ice "shylinux.com/x/icebergs"
|
ice "shylinux.com/x/icebergs"
|
||||||
|
"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/mdb"
|
"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"
|
||||||
kit "shylinux.com/x/toolkits"
|
kit "shylinux.com/x/toolkits"
|
||||||
)
|
)
|
||||||
|
|
||||||
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 {
|
func _repos_cmd(m *ice.Message, name string, arg ...string) *ice.Message {
|
||||||
return m.Copy(_git_cmd(m.Options(cli.CMD_DIR, _repos_path(name)), arg...))
|
return m.Copy(_git_cmd(m.Options(cli.CMD_DIR, _repos_path(m, name)), arg...))
|
||||||
}
|
}
|
||||||
func _repos_init(m *ice.Message, dir string) string {
|
func _repos_path(m *ice.Message, p string, arg ...string) string {
|
||||||
os.MkdirAll(path.Join(dir, REFS_HEADS), ice.MOD_DIR)
|
if p == path.Base(kit.Path("")) {
|
||||||
os.MkdirAll(path.Join(dir, OBJECTS_INFO), ice.MOD_DIR)
|
return kit.Path("", arg...)
|
||||||
return m.Cmdx(nfs.SAVE, path.Join(dir, "HEAD"), "ref: refs/heads/master")
|
}
|
||||||
|
return path.Join(nfs.USR, p, path.Join(arg...))
|
||||||
}
|
}
|
||||||
func _repos_insert(m *ice.Message, name string, path string) bool {
|
func _repos_open(m *ice.Message, p string) *git.Repository {
|
||||||
if repos, e := gogit.OpenRepository(_git_dir(path)); e == nil {
|
return mdb.HashSelectTarget(m, p, nil).(*git.Repository)
|
||||||
origin := kit.Select("", kit.Split(repos.GetOrigin()), -1)
|
}
|
||||||
kit.If(origin == "", func() { origin = _configs_read(m, _git_dir(path, CONFIG))["remote.origin.url"] })
|
func _repos_init(m *ice.Message, p string) {
|
||||||
if ci, e := repos.GetCommit(); e == nil {
|
m.Debug("what %v", p)
|
||||||
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)
|
git.PlainInit(p, true)
|
||||||
|
}
|
||||||
|
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}
|
||||||
|
if refer, err := repos.Head(); err == nil {
|
||||||
|
args = append(args, BRANCH, refer.Name().String())
|
||||||
|
if commit, err := repos.CommitObject(refer.Hash()); err == nil {
|
||||||
|
args = append(args, mdb.TIME, commit.Author.When.Format(ice.MOD_TIME), COMMIT, commit.Message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if remote, err := repos.Remotes(); err == nil && len(remote) > 0 {
|
||||||
|
args = append(args, ORIGIN, remote[0].Config().URLs[0])
|
||||||
|
}
|
||||||
|
mdb.HashCreate(m.Options(mdb.TARGET, repos), args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func _repos_each(m *ice.Message, title string, cb func(*git.Repository, ice.Maps) error) {
|
||||||
|
msg := m.Cmd("")
|
||||||
|
web.GoToast(m, title, func(toast func(string, int, int)) {
|
||||||
|
list, count, total := []string{}, 0, msg.Length()
|
||||||
|
msg.Table(func(value ice.Maps) {
|
||||||
|
toast(value[REPOS], count, total)
|
||||||
|
if err := cb(_repos_open(m, value[REPOS]), value); err != nil && err != git.NoErrAlreadyUpToDate {
|
||||||
|
web.Toast(m, err.Error(), "error: "+value[REPOS], "", "3s")
|
||||||
|
list = append(list, value[REPOS])
|
||||||
|
m.Sleep3s()
|
||||||
|
}
|
||||||
|
count++
|
||||||
|
})
|
||||||
|
if len(list) > 0 {
|
||||||
|
web.Toast(m, strings.Join(list, ice.NL), ice.FAILURE, "30s")
|
||||||
} else {
|
} else {
|
||||||
mdb.HashCreate(m, REPOS, name, nfs.PATH, path, mdb.TIME, m.Time(), BRANCH, repos.GetBranch(), ORIGIN, origin)
|
toast(ice.SUCCESS, count, total)
|
||||||
}
|
}
|
||||||
return true
|
})
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
func _repos_branch(m *ice.Message, dir string) {
|
func _repos_log(m *ice.Message, repos *git.Repository) error {
|
||||||
if repos, e := gogit.OpenRepository(dir); !m.Warn(e, ice.ErrNotFound, dir) {
|
iter, err := repos.Log(&git.LogOptions{})
|
||||||
nfs.DirDeepAll(m, path.Join(dir, REFS_HEADS), "", func(value ice.Maps) {
|
if err != nil {
|
||||||
if refer, e := repos.LookupReference(REFS_HEADS + value[nfs.PATH]); !m.Warn(e, ice.ErrNotValid, value[nfs.PATH]) {
|
return err
|
||||||
if ci, e := repos.LookupCommit(refer.Oid); !m.Warn(e, ice.ErrNotValid, refer.Oid.String()) {
|
|
||||||
m.Push(mdb.TIME, ci.Author.When.Format(ice.MOD_TIME)).Push(BRANCH, value[nfs.PATH])
|
|
||||||
m.Push(COMMIT, ci.Oid.Short()).Push(AUTHOR, ci.Author.Name).Push(MESSAGE, ci.Message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, nfs.PATH)
|
|
||||||
}
|
}
|
||||||
}
|
limit := 30
|
||||||
func _repos_commit(m *ice.Message, dir, branch string, cb func(*gogit.Commit, *gogit.Repository) bool) {
|
defer m.StatusTimeCount()
|
||||||
if repos, e := gogit.OpenRepository(dir); !m.Warn(e, ice.ErrNotFound, dir) {
|
m.Push(mdb.TIME, m.Time())
|
||||||
if refer, e := repos.LookupReference(REFS_HEADS + branch); !m.Warn(e, ice.ErrNotFound, branch) {
|
m.Push(COMMIT, INDEX)
|
||||||
if cb == nil {
|
m.Push(aaa.USERNAME, m.Option(ice.MSG_USERNAME))
|
||||||
m.Push(mdb.TIME, m.Time()).Push(COMMIT, cli.PWD).Push(AUTHOR, kit.Select(m.Option(ice.MSG_USERNAME), m.Option(ice.MSG_USERNICK))).Push(MESSAGE, "opt some")
|
m.Push(mdb.TEXT, "add some")
|
||||||
}
|
m.Push("files", 0).Push("adds", 0).Push("dels", 0)
|
||||||
for oid := refer.Oid; oid != nil; {
|
return iter.ForEach(func(commit *object.Commit) error {
|
||||||
if ci, e := repos.LookupCommit(oid); !m.Warn(e, ice.ErrNotFound, oid.String()) {
|
if m.Length() > limit {
|
||||||
if cb == nil {
|
return nil
|
||||||
m.Push(mdb.TIME, ci.Author.When.Format(ice.MOD_TIME)).Push(COMMIT, ci.Oid.Short()).Push(AUTHOR, ci.Author.Name).Push(MESSAGE, ci.Message)
|
}
|
||||||
} else if cb(ci, repos) {
|
m.Push(mdb.TIME, commit.Author.When)
|
||||||
break
|
m.Push(COMMIT, commit.Hash.String())
|
||||||
}
|
m.Push(aaa.USERNAME, commit.Author.Name)
|
||||||
if p := ci.ParentCommit(0); p != nil {
|
m.Push(mdb.TEXT, commit.Message)
|
||||||
oid = p.Oid
|
files, adds, dels := 0, 0, 0
|
||||||
continue
|
if stats, err := commit.Stats(); err == nil {
|
||||||
}
|
for _, stat := range stats {
|
||||||
}
|
files, adds, dels = files+1, adds+stat.Addition, dels+stat.Deletion
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
m.Push("files", files).Push("adds", adds).Push("dels", adds)
|
||||||
}
|
return nil
|
||||||
func _repos_cid(m *ice.Message, dir, branch, commit string) string {
|
|
||||||
if repos, e := gogit.OpenRepository(dir); !m.Warn(e, ice.ErrNotFound, dir) {
|
|
||||||
if refer, e := repos.LookupReference(REFS_TAGS + commit); e == nil {
|
|
||||||
m.Logs(nfs.FIND, "tags", commit, "commit", refer.Oid.String())
|
|
||||||
commit = refer.Oid.String()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return commit
|
|
||||||
}
|
|
||||||
func _repos_dir(m *ice.Message, dir, branch, commit, file string, cb func(*gogit.TreeEntry, *gogit.Repository) bool) {
|
|
||||||
if commit == cli.PWD {
|
|
||||||
nfs.DirDeepAll(m, path.Dir(dir), file, nil, "time,line,path")
|
|
||||||
m.Options(cli.CMD_DIR, path.Dir(dir)).Echo(_git_cmds(m, DIFF))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
commit = _repos_cid(m, dir, branch, commit)
|
|
||||||
_repos_commit(m, dir, branch, func(ci *gogit.Commit, repos *gogit.Repository) bool {
|
|
||||||
if !strings.HasPrefix(ci.Oid.String(), commit) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
prev := ice.Maps{}
|
|
||||||
if p := ci.ParentCommit(0); p != nil {
|
|
||||||
if ci, e := repos.LookupCommit(p.Oid); !m.Warn(e, ice.ErrNotFound, p.Oid.String()) {
|
|
||||||
if tree, e := repos.LookupTree(ci.TreeId()); !m.Warn(e, ice.ErrNotFound, ci.TreeId().String) {
|
|
||||||
tree.Walk(func(p string, v *gogit.TreeEntry) bool {
|
|
||||||
kit.If(v.Type == gogit.ObjectBlob, func() { prev[path.Join(p, v.Name)] = v.Oid.String() })
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if tree, e := repos.LookupTree(ci.TreeId()); !m.Warn(e, ice.ErrNotFound, ci.TreeId().String) {
|
|
||||||
m.Logs(nfs.FIND, REPOS, dir, BRANCH, branch, COMMIT, commit, TREE, tree.Oid.Short())
|
|
||||||
tree.Walk(func(p string, v *gogit.TreeEntry) bool {
|
|
||||||
if pp := path.Join(p, v.Name) + kit.Select("", ice.PS, v.Type == gogit.ObjectTree); strings.HasPrefix(pp, file) {
|
|
||||||
if v.Type == gogit.ObjectTree {
|
|
||||||
return false
|
|
||||||
} else if cb == nil {
|
|
||||||
if id, ok := prev[pp]; ok && id == v.Oid.String() {
|
|
||||||
if m.Option(ice.MSG_INDEX) == web.CODE_INNER {
|
|
||||||
m.Push(mdb.HASH, v.Oid.Short()).Push(nfs.PATH, pp).Push(mdb.STATUS, "")
|
|
||||||
}
|
|
||||||
} else if ok {
|
|
||||||
m.Push(mdb.HASH, v.Oid.Short()).Push(nfs.PATH, pp).Push(mdb.STATUS, "~~~")
|
|
||||||
} else {
|
|
||||||
m.Push(mdb.HASH, v.Oid.Short()).Push(nfs.PATH, pp).Push(mdb.STATUS, "+++")
|
|
||||||
}
|
|
||||||
delete(prev, pp)
|
|
||||||
} else if cb(v, repos) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
kit.For(prev, func(pp, id string) { m.Push(mdb.HASH, id[:6]).Push(nfs.PATH, pp).Push(mdb.STATUS, "---") })
|
|
||||||
if m.Sort(kit.Fields(mdb.STATUS, nfs.PATH), ice.STR_R, ice.STR); cb == nil {
|
|
||||||
m.Options(cli.CMD_DIR, dir).Echo(_git_cmds(m, DIFF, ci.Oid.String()+"^", ci.Oid.String()))
|
|
||||||
m.Status(mdb.TIME, ci.Author.When.Format(ice.MOD_TIME), DIFF, _git_cmds(m, DIFF, "--shortstat", ci.Oid.String()+"^", ci.Oid.String()), MESSAGE, ci.Message)
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
func _repos_cat(m *ice.Message, dir, branch, commit, file string) {
|
func _repos_stats(m *ice.Message, repos *git.Repository, h string) error {
|
||||||
if commit == cli.PWD {
|
commit, err := repos.CommitObject(plumbing.NewHash(h))
|
||||||
m.Cmdy(nfs.CAT, path.Join(path.Dir(dir), file))
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
stats, err := commit.Stats()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer m.StatusTimeCount()
|
||||||
|
for _, stat := range stats {
|
||||||
|
m.Push(nfs.FILE, stat.Name).Push("add", stat.Addition).Push("del", stat.Deletion)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func _repos_status(m *ice.Message, repos *git.Repository) error {
|
||||||
|
work, err := repos.Worktree()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
status, err := work.Status()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer m.StatusTimeCount()
|
||||||
|
for k, v := range status {
|
||||||
|
switch kit.Ext(k) {
|
||||||
|
case "swp", "swo":
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
m.Push(nfs.FILE, k).Push(STATUS, string(v.Worktree)+string(v.Staging))
|
||||||
|
switch v.Worktree {
|
||||||
|
case git.Untracked:
|
||||||
|
m.PushButton(ADD, nfs.TRASH)
|
||||||
|
case git.Modified:
|
||||||
|
m.PushButton(ADD)
|
||||||
|
default:
|
||||||
|
m.PushButton(COMMIT)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
func _repos_vimer(m *ice.Message, _repos_path func(m *ice.Message, p string, arg ...string) string, arg ...string) {
|
||||||
|
if len(arg) == 0 || arg[0] != ice.RUN {
|
||||||
|
arg = []string{path.Join(arg[:2]...), kit.Select("README.md", arg, 2)}
|
||||||
|
} else if kit.Select("", arg, 1) != ctx.ACTION {
|
||||||
|
ls := kit.Split(kit.Select(arg[1], m.Option(nfs.DIR_ROOT)), nfs.PS)
|
||||||
|
if ls[1] == INDEX {
|
||||||
|
if len(arg) < 3 {
|
||||||
|
m.Cmdy(nfs.DIR, nfs.PWD, kit.Dict(nfs.DIR_ROOT, _repos_path(m, ls[0])))
|
||||||
|
} else {
|
||||||
|
m.Cmdy(nfs.CAT, _repos_path(m, ls[0], arg[2]))
|
||||||
|
}
|
||||||
|
} else if commit, err := _repos_open(m, ls[0]).CommitObject(plumbing.NewHash(ls[1])); m.Warn(err) {
|
||||||
|
return
|
||||||
|
} else if len(arg) < 3 {
|
||||||
|
if iter, err := commit.Files(); !m.Warn(err) {
|
||||||
|
iter.ForEach(func(file *object.File) error {
|
||||||
|
m.Push(nfs.PATH, file.Name)
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if file, err := commit.File(arg[2]); !m.Warn(err) {
|
||||||
|
if content, err := file.Contents(); !m.Warn(err) {
|
||||||
|
m.Echo(content)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.DisplayLocal(m, "code/vimer.js")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
commit = _repos_cid(m, dir, branch, commit)
|
ctx.ProcessField(m, "", arg, arg...)
|
||||||
_repos_dir(m, dir, branch, commit, file, func(v *gogit.TreeEntry, repos *gogit.Repository) bool {
|
|
||||||
if blob, e := repos.LookupBlob(v.Oid); e == nil {
|
|
||||||
m.Logs(nfs.LOAD, REPOS, dir, BRANCH, branch, COMMIT, commit, BLOB, v.Oid.Short()).Echo(string(blob.Contents()))
|
|
||||||
} else {
|
|
||||||
m.Options(cli.CMD_DIR, dir).Echo(_git_cmds(m, "cat-file", "-p", v.Oid.String()))
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
OBJECTS_INFO = "objects/info/"
|
CLONE = "clone"
|
||||||
REFS_HEADS = "refs/heads/"
|
PULL = "pull"
|
||||||
REFS_TAGS = "refs/tags/"
|
PUSH = "push"
|
||||||
TREE = "tree"
|
LOG = "log"
|
||||||
BLOB = "blob"
|
ADD = "add"
|
||||||
|
TAG = "tag"
|
||||||
|
STASH = "stash"
|
||||||
|
COMMIT = "commit"
|
||||||
|
|
||||||
INIT = "init"
|
ORIGIN = "origin"
|
||||||
CONFIG = "config"
|
BRANCH = "branch"
|
||||||
ORIGIN = "origin"
|
MASTER = "master"
|
||||||
BRANCH = "branch"
|
INDEX = "index"
|
||||||
MASTER = "master"
|
|
||||||
AUTHOR = "author"
|
|
||||||
MESSAGE = "message"
|
|
||||||
)
|
)
|
||||||
const REPOS = "repos"
|
const REPOS = "repos"
|
||||||
|
|
||||||
@ -175,90 +201,114 @@ func init() {
|
|||||||
web.PP(ice.REQUIRE): {Name: "/require/shylinux.com/x/volcanos/proto.js", Help: "代码库", Hand: func(m *ice.Message, arg ...string) {
|
web.PP(ice.REQUIRE): {Name: "/require/shylinux.com/x/volcanos/proto.js", Help: "代码库", Hand: func(m *ice.Message, arg ...string) {
|
||||||
if len(arg) < 4 {
|
if len(arg) < 4 {
|
||||||
m.RenderStatusBadRequest()
|
m.RenderStatusBadRequest()
|
||||||
return
|
|
||||||
} else if path.Join(arg[:3]...) == ice.Info.Make.Module && nfs.Exists(m, path.Join(arg[3:]...)) {
|
} else if path.Join(arg[:3]...) == ice.Info.Make.Module && nfs.Exists(m, path.Join(arg[3:]...)) {
|
||||||
m.RenderDownload(path.Join(arg[3:]...))
|
m.RenderDownload(path.Join(arg[3:]...))
|
||||||
return
|
} else {
|
||||||
}
|
p := path.Join(kit.Select(ice.USR_REQUIRE, m.Cmdx(cli.SYSTEM, "go", "env", "GOMODCACHE")), path.Join(arg...))
|
||||||
p := path.Join(kit.Select(ice.USR_REQUIRE, m.Cmdx(cli.SYSTEM, "go", "env", "GOMODCACHE")), path.Join(arg...))
|
if !nfs.Exists(m, p) {
|
||||||
if !nfs.Exists(m, p) {
|
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]...), ice.AT, 2)
|
||||||
ls := strings.SplitN(path.Join(arg[:3]...), ice.AT, 2)
|
to := path.Join(ice.USR_REQUIRE, path.Join(arg[:3]...))
|
||||||
if v := kit.Select(ice.Info.Gomod[ls[0]], ls, 1); v == "" {
|
_, err := git.PlainClone(to, false, &git.CloneOptions{URL: "https://" + ls[0], ReferenceName: plumbing.NewBranchReferenceName(kit.Select(ice.Info.Gomod[ls[0]], ls, 1))})
|
||||||
_git_cmd(m, "clone", "https://"+ls[0], path.Join(ice.USR_REQUIRE, path.Join(arg[:3]...)))
|
m.Warn(err)
|
||||||
} else {
|
|
||||||
_git_cmd(m, "clone", "-b", v, "https://"+ls[0], path.Join(ice.USR_REQUIRE, path.Join(arg[:3]...)))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
m.RenderDownload(p)
|
||||||
}
|
}
|
||||||
m.RenderDownload(p)
|
|
||||||
}},
|
}},
|
||||||
})
|
})
|
||||||
Index.MergeCommands(ice.Commands{
|
Index.MergeCommands(ice.Commands{
|
||||||
REPOS: {Name: "repos repos@key branch@key commit@key path@key auto", Help: "代码库", Actions: ice.MergeActions(ice.Actions{
|
REPOS: {Name: "repos repos 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, ice.USR, "name,path", func(value ice.Maps) { _repos_insert(m, value[mdb.NAME], value[nfs.PATH]) })
|
m.Cmd(nfs.DIR, nfs.USR, func(value ice.Maps) { _repos_insert(m, value[nfs.PATH]) })
|
||||||
_repos_insert(m, path.Base(kit.Pwd()), kit.Pwd())
|
_repos_insert(m, kit.Path(""))
|
||||||
cli.IsSystem(m, GIT)
|
|
||||||
}},
|
}},
|
||||||
mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) {
|
CLONE: {Name: "clone origin* branch name path", Hand: func(m *ice.Message, arg ...string) {
|
||||||
switch arg[0] {
|
m.OptionDefault(mdb.NAME, path.Base(m.Option(ORIGIN)))
|
||||||
case REPOS:
|
m.OptionDefault(nfs.PATH, path.Join(path.Join(nfs.USR, m.Option(mdb.NAME))))
|
||||||
mdb.HashSelect(m).Cut(REPOS)
|
_, err := git.PlainClone(m.Option(nfs.PATH), false, &git.CloneOptions{URL: m.Option(ORIGIN)})
|
||||||
case BRANCH:
|
m.Warn(err)
|
||||||
m.Cmdy("", m.Option(REPOS)).Cut(BRANCH)
|
_repos_insert(m, m.Option(nfs.PATH))
|
||||||
case COMMIT:
|
|
||||||
m.Cmdy("", m.Option(REPOS), m.Option(BRANCH)).Cut("commit,author,message,time")
|
|
||||||
case nfs.PATH:
|
|
||||||
m.Cmdy("", m.Option(REPOS), m.Option(BRANCH), m.Option(COMMIT)).Cut("path,hash,status")
|
|
||||||
default:
|
|
||||||
mdb.HashInputs(m, arg)
|
|
||||||
}
|
|
||||||
}},
|
}},
|
||||||
mdb.CREATE: {Name: "create origin branch name path", Hand: func(m *ice.Message, arg ...string) {
|
PULL: {Hand: func(m *ice.Message, arg ...string) {
|
||||||
m.OptionDefault(mdb.NAME, kit.TrimExt(m.Option(ORIGIN), GIT))
|
_repos_each(m, "repos pull", func(repos *git.Repository, value ice.Maps) error {
|
||||||
m.OptionDefault(nfs.PATH, path.Join(nfs.USR, m.Option(mdb.NAME)))
|
if value[ORIGIN] == "" {
|
||||||
if _repos_insert(m, m.Option(mdb.NAME), m.Option(nfs.PATH)) {
|
return nil
|
||||||
return
|
} else if work, err := repos.Worktree(); err != nil {
|
||||||
}
|
return err
|
||||||
m.Cmd("", INIT, kit.Dict(cli.CMD_DIR, m.Option(nfs.PATH)))
|
|
||||||
_repos_insert(m, m.Option(mdb.NAME), m.Option(nfs.PATH))
|
|
||||||
}},
|
|
||||||
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(nfs.TemplateText(m, CONFIG), m.Option(ORIGIN)))
|
|
||||||
_git_cmd(m, PULL, ORIGIN, m.OptionDefault(BRANCH, MASTER))
|
|
||||||
}
|
|
||||||
}},
|
|
||||||
DIFF: {Hand: func(m *ice.Message, arg ...string) {
|
|
||||||
if len(arg) == 0 || arg[0] != ice.RUN {
|
|
||||||
arg = []string{path.Join(arg[:3]...), kit.Select("README.md", arg, 3)}
|
|
||||||
} else if kit.Select("", arg, 1) != ctx.ACTION {
|
|
||||||
ls := kit.Split(kit.Select(arg[1], m.Option(nfs.DIR_ROOT)), nfs.PS)
|
|
||||||
if dir := _git_dir(_repos_path(ls[0])); len(arg) < 3 {
|
|
||||||
_repos_dir(m, dir, ls[1], ls[2], kit.Select("", arg, 1), nil)
|
|
||||||
} else {
|
} else {
|
||||||
_repos_cat(m, dir, ls[1], ls[2], arg[2])
|
return work.Pull(&git.PullOptions{})
|
||||||
ctx.DisplayLocal(m, "code/inner.js")
|
|
||||||
}
|
}
|
||||||
return
|
})
|
||||||
|
}},
|
||||||
|
PUSH: {Hand: func(m *ice.Message, arg ...string) {
|
||||||
|
list := map[string]*url.URL{}
|
||||||
|
m.Cmd(nfs.CAT, kit.HomePath(".git-credentials"), func(line string) {
|
||||||
|
u := kit.ParseURL(line)
|
||||||
|
list[u.Host] = u
|
||||||
|
})
|
||||||
|
_repos_each(m, "repos push", func(repos *git.Repository, value ice.Maps) error {
|
||||||
|
if value[ORIGIN] == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
u := list[kit.ParseURL(value[ORIGIN]).Host]
|
||||||
|
if password, ok := u.User.Password(); !ok {
|
||||||
|
return errors.New("not found password")
|
||||||
|
} else {
|
||||||
|
return repos.Push(&git.PushOptions{Auth: &http.BasicAuth{Username: u.User.Username(), Password: password}})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}},
|
||||||
|
LOG: {Hand: func(m *ice.Message, arg ...string) {
|
||||||
|
_repos_log(m, _repos_open(m, kit.Select(m.Option(REPOS), arg, 0)))
|
||||||
|
}},
|
||||||
|
ADD: {Hand: func(m *ice.Message, arg ...string) {
|
||||||
|
if work, err := _repos_open(m, m.Option(REPOS)).Worktree(); !m.Warn(err) {
|
||||||
|
_, err := work.Add(m.Option(nfs.FILE))
|
||||||
|
m.Warn(err)
|
||||||
}
|
}
|
||||||
ctx.ProcessField(m, web.CODE_INNER, arg, arg...)
|
}},
|
||||||
|
COMMIT: {Name: "commit actions=add,opt,fix comment*=some", Hand: func(m *ice.Message, arg ...string) {
|
||||||
|
if work, err := _repos_open(m, m.Option(REPOS)).Worktree(); !m.Warn(err) {
|
||||||
|
_, err := work.Commit(m.Option("actions")+ice.SP+m.Option("comment"), &git.CommitOptions{})
|
||||||
|
m.Warn(err)
|
||||||
|
}
|
||||||
|
}},
|
||||||
|
STATUS: {Hand: func(m *ice.Message, arg ...string) {
|
||||||
|
_repos_each(m, "repos status", func(repos *git.Repository, value ice.Maps) error { return _repos_status(m, repos) })
|
||||||
|
}},
|
||||||
|
STASH: {Help: "缓存", Hand: func(m *ice.Message, arg ...string) { _repos_cmd(m, kit.Select(m.Option(REPOS), arg, 0), STASH) }},
|
||||||
|
TAG: {Name: "tag version", Help: "标签", Hand: func(m *ice.Message, arg ...string) {
|
||||||
|
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)
|
||||||
|
}},
|
||||||
|
code.VIMER: {Hand: func(m *ice.Message, arg ...string) { _repos_vimer(m, _repos_path, arg...) }},
|
||||||
|
nfs.TRASH: {Hand: func(m *ice.Message, arg ...string) {
|
||||||
|
m.Assert(m.Option(REPOS) != "")
|
||||||
|
mdb.HashRemove(m, m.Option(REPOS))
|
||||||
|
nfs.Trash(m, _repos_path(m, m.Option(REPOS), m.Option(nfs.FILE)))
|
||||||
|
}},
|
||||||
|
web.DREAM_CREATE: {Hand: func(m *ice.Message, arg ...string) {
|
||||||
|
kit.If(m.Option(REPOS), func(p string) {
|
||||||
|
m.Cmd("", CLONE, ORIGIN, p, nfs.PATH, m.Option(cli.CMD_DIR), ice.Maps{cli.CMD_DIR: ""})
|
||||||
|
})
|
||||||
}},
|
}},
|
||||||
}, mdb.HashAction(mdb.SHORT, REPOS, mdb.FIELD, "time,repos,branch,commit,origin"), mdb.ClearOnExitHashAction()), Hand: func(m *ice.Message, arg ...string) {
|
}, mdb.HashAction(mdb.SHORT, REPOS, mdb.FIELD, "time,repos,branch,commit,origin"), mdb.ClearOnExitHashAction()), Hand: func(m *ice.Message, arg ...string) {
|
||||||
if len(arg) == 0 || arg[0] == "" {
|
if len(arg) == 0 {
|
||||||
mdb.HashSelect(m, arg...).Action(mdb.CREATE)
|
mdb.HashSelect(m, arg...).Action(CLONE, PULL, PUSH, STATUS)
|
||||||
} else if dir := _git_dir(_repos_path(arg[0])); len(arg) == 1 || arg[1] == "" {
|
} else if len(arg) == 1 {
|
||||||
_repos_branch(m, dir)
|
_repos_log(m, _repos_open(m, arg[0]))
|
||||||
} else if len(arg) == 2 || arg[2] == "" {
|
} else if len(arg) == 2 {
|
||||||
_repos_commit(m, dir, arg[1], nil)
|
if repos := _repos_open(m, arg[0]); arg[1] == INDEX {
|
||||||
} else if len(arg) == 3 || arg[3] == "" || strings.HasSuffix(arg[3], ice.PS) {
|
_repos_status(m, repos)
|
||||||
_repos_dir(m, dir, arg[1], arg[2], kit.Select("", arg, 3), nil)
|
} else {
|
||||||
return
|
_repos_stats(m, repos, arg[1])
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
m.Cmdy("", DIFF, arg)
|
m.Cmdy("", code.VIMER, arg)
|
||||||
}
|
}
|
||||||
m.StatusTimeCount()
|
|
||||||
}},
|
}},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,215 +0,0 @@
|
|||||||
package git
|
|
||||||
|
|
||||||
import (
|
|
||||||
"compress/flate"
|
|
||||||
"compress/gzip"
|
|
||||||
"encoding/base64"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"path"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
ice "shylinux.com/x/icebergs"
|
|
||||||
"shylinux.com/x/icebergs/base/aaa"
|
|
||||||
"shylinux.com/x/icebergs/base/cli"
|
|
||||||
"shylinux.com/x/icebergs/base/ctx"
|
|
||||||
"shylinux.com/x/icebergs/base/gdb"
|
|
||||||
"shylinux.com/x/icebergs/base/mdb"
|
|
||||||
"shylinux.com/x/icebergs/base/nfs"
|
|
||||||
"shylinux.com/x/icebergs/base/tcp"
|
|
||||||
"shylinux.com/x/icebergs/base/web"
|
|
||||||
kit "shylinux.com/x/toolkits"
|
|
||||||
)
|
|
||||||
|
|
||||||
func _server_login(m *ice.Message) error {
|
|
||||||
if tcp.IsLocalHost(m, m.Option(ice.MSG_USERIP)) && ice.Info.Localhost {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
ls := strings.SplitN(m.R.Header.Get(web.Authorization), ice.SP, 2)
|
|
||||||
if strings.ToLower(ls[0]) != "basic" {
|
|
||||||
return fmt.Errorf("Authentication '%s' was not of 'Basic' type", ls[0])
|
|
||||||
}
|
|
||||||
data, err := base64.StdEncoding.DecodeString(ls[1])
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if ls = strings.SplitN(string(data), ice.DF, 2); m.Cmd("web.code.git.token", ls[0]).Append(TOKEN) != ls[1] {
|
|
||||||
return fmt.Errorf("username or password error")
|
|
||||||
}
|
|
||||||
if aaa.UserRole(m, ls[0]) == aaa.VOID {
|
|
||||||
return fmt.Errorf("userrole has no right")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
func _server_param(m *ice.Message, arg ...string) (string, string) {
|
|
||||||
repos, service := path.Join(kit.Slice(arg, 0, 1)...), kit.Select(arg[len(arg)-1], m.Option("service"))
|
|
||||||
switch {
|
|
||||||
case strings.HasSuffix(repos, INFO_REFS):
|
|
||||||
repos = strings.TrimSuffix(repos, INFO_REFS)
|
|
||||||
default:
|
|
||||||
repos = strings.TrimSuffix(repos, service)
|
|
||||||
}
|
|
||||||
m.Debug("what %v", repos)
|
|
||||||
return kit.Path(ice.USR_LOCAL_REPOS, strings.TrimSuffix(repos, ".git/")), strings.TrimPrefix(service, "git-")
|
|
||||||
}
|
|
||||||
func _server_repos(m *ice.Message, arg ...string) error {
|
|
||||||
repos, service := _server_param(m, arg...)
|
|
||||||
if m.Option(cli.CMD_DIR, repos); strings.HasSuffix(path.Join(arg...), INFO_REFS) {
|
|
||||||
web.RenderType(m.W, "", kit.Format("application/x-git-%s-advertisement", service))
|
|
||||||
// _server_writer(m, "# service=git-"+service+ice.NL, m.Cmd(cli.SYSTEM, "ice.bin", "web.git.repos", service, repos).Results())
|
|
||||||
// return nil
|
|
||||||
_server_writer(m, "# service=git-"+service+ice.NL, _git_cmds(m, service, "--stateless-rpc", "--advertise-refs", ice.PT))
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
reader, err := _server_reader(m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer reader.Close()
|
|
||||||
m.Options(cli.CMD_INPUT, reader, cli.CMD_OUTPUT, m.W)
|
|
||||||
web.RenderType(m.W, "", kit.Format("application/x-git-%s-result", service))
|
|
||||||
|
|
||||||
// m.Cmd(cli.SYSTEM, "ice.bin", "web.git.repos", service, repos)
|
|
||||||
// return nil
|
|
||||||
//
|
|
||||||
_git_cmd(m, service, "--stateless-rpc", ice.PT)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
func _server_writer(m *ice.Message, cmd string, str ...string) {
|
|
||||||
s := strconv.FormatInt(int64(len(cmd)+4), 16)
|
|
||||||
if len(s)%4 != 0 {
|
|
||||||
s = strings.Repeat("0", 4-len(s)%4) + s
|
|
||||||
}
|
|
||||||
m.W.Write([]byte(s + cmd + "0000" + strings.Join(str, "")))
|
|
||||||
}
|
|
||||||
func _server_reader(m *ice.Message) (io.ReadCloser, error) {
|
|
||||||
switch m.R.Header.Get("content-encoding") {
|
|
||||||
case "deflate":
|
|
||||||
return flate.NewReader(m.R.Body), nil
|
|
||||||
case "gzip":
|
|
||||||
return gzip.NewReader(m.R.Body)
|
|
||||||
}
|
|
||||||
return m.R.Body, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
INFO_REFS = "info/refs"
|
|
||||||
)
|
|
||||||
const SERVER = "server"
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
web.Index.MergeCommands(ice.Commands{"/x/": {Actions: ice.MergeActions(ctx.CmdAction(), aaa.WhiteAction(ctx.COMMAND, ice.RUN)), Hand: func(m *ice.Message, arg ...string) {
|
|
||||||
if arg[0] == ice.LIST {
|
|
||||||
m.Cmd("web.code.git.server", func(value ice.Maps) { m.Push(nfs.REPOS, web.MergeLink(m, "/x/"+value[nfs.REPOS]+".git")) })
|
|
||||||
m.Sort(nfs.REPOS)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !m.IsCliUA() || len(arg) > 0 && strings.Contains(arg[0], ice.AT) || len(arg) > 1 && arg[1] == ice.SRC {
|
|
||||||
if len(arg) > 0 && strings.Contains(arg[0], ice.AT) {
|
|
||||||
ls := strings.Split(arg[0], ice.AT)
|
|
||||||
_repos_cat(m, path.Join(ice.USR_LOCAL_REPOS, ls[0]), "master", ls[1], path.Join(arg[1:]...))
|
|
||||||
m.RenderResult()
|
|
||||||
} else if len(arg) > 1 && strings.HasPrefix(arg[1], "v") && strings.Contains(arg[1], ice.PT) {
|
|
||||||
_repos_cat(m, path.Join(ice.USR_LOCAL_REPOS, arg[0]), "master", arg[1], path.Join(arg[2:]...))
|
|
||||||
m.RenderResult()
|
|
||||||
} else if len(arg) > 1 && arg[1] == ice.SRC {
|
|
||||||
_repos_cat(m, path.Join(ice.USR_LOCAL_REPOS, arg[0]), "master", "", path.Join(arg[1:]...))
|
|
||||||
m.RenderResult()
|
|
||||||
} else {
|
|
||||||
web.RenderCmds(m, kit.Dict(ctx.DISPLAY, "/plugin/local/code/repos.js", ctx.INDEX, "web.code.git.inner",
|
|
||||||
ctx.ARGS, kit.List(strings.TrimSuffix(arg[0], ".git"), arg[1], "pwd", kit.Select("README.md", path.Join(kit.Slice(arg, 2)...)))))
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if m.RenderVoid(); m.Option("go-get") == "1" {
|
|
||||||
p := _git_url(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], ".git"), p)))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
switch repos, service := _server_param(m, arg...); service {
|
|
||||||
case "receive-pack":
|
|
||||||
if err := _server_login(m); m.Warn(err, ice.ErrNotLogin) {
|
|
||||||
web.RenderHeader(m.W, "WWW-Authenticate", `Basic realm="git server"`)
|
|
||||||
return
|
|
||||||
} else if !nfs.Exists(m, repos) {
|
|
||||||
m.Logs(mdb.CREATE, REPOS, repos)
|
|
||||||
_repos_init(m, repos)
|
|
||||||
}
|
|
||||||
case "upload-pack":
|
|
||||||
if m.Warn(!nfs.Exists(m, repos), ice.ErrNotFound, arg[0]) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m.Warn(_server_repos(m, arg...), ice.ErrNotValid)
|
|
||||||
}}})
|
|
||||||
Index.MergeCommands(ice.Commands{
|
|
||||||
"inner": {Name: "inner repos branch commit path auto token", Help: "服务器", Actions: ice.MergeActions(ice.Actions{}, aaa.RoleAction()), Hand: func(m *ice.Message, arg ...string) {
|
|
||||||
if m.Option(nfs.DIR_ROOT, ice.USR_LOCAL_REPOS); len(arg) == 0 {
|
|
||||||
} else if dir := path.Join(m.Option(nfs.DIR_ROOT), arg[0]); len(arg) == 1 {
|
|
||||||
} else if len(arg) == 2 {
|
|
||||||
} else if len(arg) == 3 || strings.HasSuffix(arg[3], nfs.PS) {
|
|
||||||
_repos_dir(m, dir, arg[1], arg[2], kit.Select("", arg, 3), nil)
|
|
||||||
} else {
|
|
||||||
m.Option(nfs.FILE, kit.Select("", arg, 3))
|
|
||||||
_repos_cat(m, dir, arg[1], arg[2], kit.Select("", arg, 3))
|
|
||||||
}
|
|
||||||
}},
|
|
||||||
SERVER: {Name: "server repos branch commit path auto create import token", Help: "代码源", Actions: ice.MergeActions(ice.Actions{
|
|
||||||
mdb.CREATE: {Name: "create name*=demo", Hand: func(m *ice.Message, arg ...string) {
|
|
||||||
_repos_init(m, path.Join(ice.USR_LOCAL_REPOS, m.Option(mdb.NAME)))
|
|
||||||
}},
|
|
||||||
mdb.IMPORT: {Hand: func(m *ice.Message, arg ...string) {
|
|
||||||
ReposList(m).Table(func(value ice.Maps) {
|
|
||||||
m.Option(cli.CMD_DIR, value[nfs.PATH])
|
|
||||||
remote := _git_url(m, value[REPOS])
|
|
||||||
_git_cmd(m, PUSH, remote, MASTER)
|
|
||||||
_git_cmd(m, PUSH, "--tags", remote, MASTER)
|
|
||||||
})
|
|
||||||
}},
|
|
||||||
nfs.TRASH: {Hand: func(m *ice.Message, arg ...string) {
|
|
||||||
m.Assert(m.Option(nfs.REPOS) != "")
|
|
||||||
nfs.Trash(m, path.Join(ice.USR_LOCAL_REPOS, m.Option(nfs.REPOS)))
|
|
||||||
}},
|
|
||||||
web.DREAM_INPUTS: {Hand: func(m *ice.Message, arg ...string) {
|
|
||||||
switch arg[0] {
|
|
||||||
case nfs.REPOS:
|
|
||||||
m.Cmd("", func(value ice.Maps) { m.Push(nfs.PATH, _git_url(m, value[nfs.PATH])) })
|
|
||||||
}
|
|
||||||
}},
|
|
||||||
"inner": {Help: "编辑器", Hand: func(m *ice.Message, arg ...string) {
|
|
||||||
if len(arg) == 0 || arg[0] != ice.RUN {
|
|
||||||
arg = []string{path.Join(ice.USR_LOCAL_REPOS, arg[0]), kit.Select("README.md", arg, 3)}
|
|
||||||
} else if kit.Select("", arg, 1) != ctx.ACTION {
|
|
||||||
if dir := path.Join(ice.USR_LOCAL_REPOS, m.Option(REPOS)); len(arg) < 3 {
|
|
||||||
_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")
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx.ProcessField(m, "", arg, arg...)
|
|
||||||
}},
|
|
||||||
TOKEN: {Help: "令牌", Hand: func(m *ice.Message, arg ...string) { m.Cmdy(TOKEN, cli.MAKE) }},
|
|
||||||
}, gdb.EventAction(web.DREAM_INPUTS)), Hand: func(m *ice.Message, arg ...string) {
|
|
||||||
if m.Option(nfs.DIR_ROOT, ice.USR_LOCAL_REPOS); len(arg) == 0 {
|
|
||||||
m.Option(ice.MSG_USERROLE, aaa.TECH)
|
|
||||||
m.Cmdy(nfs.DIR, nfs.PWD, "time,name,size,action", kit.Dict(nfs.DIR_TYPE, nfs.TYPE_DIR), func(value ice.Maps) {
|
|
||||||
m.PushScript("git clone " + _git_url(m, value[mdb.NAME]))
|
|
||||||
}).Cut("time,name,size,script,action").RenameAppend(mdb.NAME, nfs.REPOS).SortStrR(mdb.TIME)
|
|
||||||
m.Echo(strings.ReplaceAll(m.Cmdx("web.code.publish", ice.CONTEXTS), "app username", "dev username"))
|
|
||||||
m.Echo(m.Cmdx(TOKEN, m.Option(ice.MSG_USERNAME)))
|
|
||||||
} else if dir := path.Join(m.Option(nfs.DIR_ROOT), arg[0]); len(arg) == 1 {
|
|
||||||
_repos_branch(m, dir)
|
|
||||||
} else if len(arg) == 2 {
|
|
||||||
_repos_commit(m, dir, arg[1], nil)
|
|
||||||
} else if len(arg) == 3 || arg[3] == "" || strings.HasSuffix(arg[3], ice.PS) {
|
|
||||||
_repos_dir(m, dir, arg[1], arg[2], kit.Select("", arg, 3), nil)
|
|
||||||
} else {
|
|
||||||
m.Cmdy("", "inner", arg)
|
|
||||||
}
|
|
||||||
m.StatusTimeCount()
|
|
||||||
}},
|
|
||||||
})
|
|
||||||
}
|
|
@ -53,11 +53,11 @@ func init() {
|
|||||||
} else if len(arg) == 1 {
|
} else if len(arg) == 1 {
|
||||||
color := []string{cli.YELLOW, cli.BLUE, cli.CYAN, cli.RED}
|
color := []string{cli.YELLOW, cli.BLUE, cli.CYAN, cli.RED}
|
||||||
ctx.DisplayStory(m, "", mdb.FIELD, nfs.PATH, aaa.ROOT, arg[0])
|
ctx.DisplayStory(m, "", mdb.FIELD, nfs.PATH, aaa.ROOT, arg[0])
|
||||||
nfs.DirDeepAll(m, _repos_path(arg[0]), "", func(value ice.Maps) {
|
nfs.DirDeepAll(m, _repos_path(m, arg[0]), "", func(value ice.Maps) {
|
||||||
m.Push(cli.COLOR, color[strings.Count(value[nfs.PATH], ice.PS)%len(color)])
|
m.Push(cli.COLOR, color[strings.Count(value[nfs.PATH], ice.PS)%len(color)])
|
||||||
m.Push("", value, []string{nfs.PATH})
|
m.Push("", value, []string{nfs.PATH})
|
||||||
}, nfs.PATH)
|
}, nfs.PATH)
|
||||||
m.Option(nfs.DIR_ROOT, _repos_path(arg[0]))
|
m.Option(nfs.DIR_ROOT, _repos_path(m, arg[0]))
|
||||||
m.StatusTimeCount()
|
m.StatusTimeCount()
|
||||||
} else if len(arg) == 2 {
|
} else if len(arg) == 2 {
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package git
|
package git
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"path"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -113,15 +112,9 @@ func _status_list(m *ice.Message) (files, adds, dels int, last time.Time) {
|
|||||||
const (
|
const (
|
||||||
INSTEADOF = "insteadof"
|
INSTEADOF = "insteadof"
|
||||||
OAUTH = "oauth"
|
OAUTH = "oauth"
|
||||||
PULL = "pull"
|
|
||||||
PUSH = "push"
|
|
||||||
DIFF = "diff"
|
DIFF = "diff"
|
||||||
ADD = "add"
|
|
||||||
OPT = "opt"
|
OPT = "opt"
|
||||||
FIX = "fix"
|
FIX = "fix"
|
||||||
COMMIT = "commit"
|
|
||||||
STASH = "stash"
|
|
||||||
TAG = "tag"
|
|
||||||
|
|
||||||
TAGS = "tags"
|
TAGS = "tags"
|
||||||
VERSION = "version"
|
VERSION = "version"
|
||||||
@ -172,32 +165,6 @@ func init() {
|
|||||||
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.Remote, _git_remote(m)), "/chat/cmd/web.code.git.token", aaa.USERNAME, m.Option(ice.MSG_USERNAME), tcp.HOST, web.UserHost(m)))
|
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)))
|
||||||
}},
|
}},
|
||||||
PULL: {Help: "下载", Hand: func(m *ice.Message, arg ...string) {
|
|
||||||
_status_each(m, "", cli.SYSTEM, GIT, PULL)
|
|
||||||
_status_each(m, "", cli.SYSTEM, GIT, PULL, "--tags")
|
|
||||||
m.Sleep3s()
|
|
||||||
}},
|
|
||||||
PUSH: {Help: "上传", Hand: func(m *ice.Message, arg ...string) {
|
|
||||||
_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: "优化"}, 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()
|
|
||||||
}},
|
|
||||||
STASH: {Help: "缓存", Hand: func(m *ice.Message, arg ...string) { _repos_cmd(m, kit.Select(m.Option(REPOS), arg, 0), STASH) }},
|
|
||||||
TAG: {Name: "tag version", Help: "标签", Hand: func(m *ice.Message, arg ...string) {
|
|
||||||
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)
|
|
||||||
}},
|
|
||||||
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)))
|
|
||||||
}},
|
|
||||||
web.DREAM_TABLES: {Hand: func(m *ice.Message, arg ...string) {
|
web.DREAM_TABLES: {Hand: func(m *ice.Message, arg ...string) {
|
||||||
if m.Option(mdb.TYPE) != web.WORKER {
|
if m.Option(mdb.TYPE) != web.WORKER {
|
||||||
return
|
return
|
||||||
@ -215,6 +182,10 @@ func init() {
|
|||||||
m.Push(mdb.TEXT, strings.Join(text, ", "))
|
m.Push(mdb.TEXT, strings.Join(text, ", "))
|
||||||
}},
|
}},
|
||||||
}, gdb.EventAction(web.DREAM_TABLES), aaa.RoleAction()), Hand: func(m *ice.Message, arg ...string) {
|
}, gdb.EventAction(web.DREAM_TABLES), aaa.RoleAction()), Hand: func(m *ice.Message, arg ...string) {
|
||||||
|
if len(arg) > 0 && arg[0] == ctx.ACTION {
|
||||||
|
m.Cmdy(REPOS, arg)
|
||||||
|
return
|
||||||
|
}
|
||||||
if _configs_get(m, USER_EMAIL) == "" {
|
if _configs_get(m, USER_EMAIL) == "" {
|
||||||
m.Echo("please config user.email").Action(CONFIGS)
|
m.Echo("please config user.email").Action(CONFIGS)
|
||||||
} else if len(arg) == 0 {
|
} else if len(arg) == 0 {
|
||||||
|
@ -68,7 +68,7 @@ func init() {
|
|||||||
}},
|
}},
|
||||||
"_sum": {Name: "_sum [path] [total] [count|date] args...", Help: "统计量", Hand: func(m *ice.Message, arg ...string) {
|
"_sum": {Name: "_sum [path] [total] [count|date] args...", Help: "统计量", Hand: func(m *ice.Message, arg ...string) {
|
||||||
if len(arg) > 0 {
|
if len(arg) > 0 {
|
||||||
if nfs.Exists(m, _git_dir(arg[0])) || nfs.Exists(m, path.Join(arg[0], REFS_HEADS)) {
|
if nfs.Exists(m, _git_dir(arg[0])) || nfs.Exists(m, path.Join(arg[0], "refs/heads/")) {
|
||||||
m.Option(cli.CMD_DIR, arg[0])
|
m.Option(cli.CMD_DIR, arg[0])
|
||||||
arg = arg[1:]
|
arg = arg[1:]
|
||||||
}
|
}
|
||||||
|
@ -1,310 +1 @@
|
|||||||
package repos
|
package repos
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"net/url"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
git "shylinux.com/x/go-git/v5"
|
|
||||||
"shylinux.com/x/go-git/v5/plumbing"
|
|
||||||
"shylinux.com/x/go-git/v5/plumbing/object"
|
|
||||||
"shylinux.com/x/go-git/v5/plumbing/transport/file"
|
|
||||||
"shylinux.com/x/go-git/v5/plumbing/transport/http"
|
|
||||||
|
|
||||||
ice "shylinux.com/x/icebergs"
|
|
||||||
"shylinux.com/x/icebergs/base/aaa"
|
|
||||||
"shylinux.com/x/icebergs/base/cli"
|
|
||||||
"shylinux.com/x/icebergs/base/ctx"
|
|
||||||
"shylinux.com/x/icebergs/base/mdb"
|
|
||||||
"shylinux.com/x/icebergs/base/nfs"
|
|
||||||
"shylinux.com/x/icebergs/base/web"
|
|
||||||
"shylinux.com/x/icebergs/core/code"
|
|
||||||
kit "shylinux.com/x/toolkits"
|
|
||||||
)
|
|
||||||
|
|
||||||
func _repos_path(m *ice.Message, p string, arg ...string) string {
|
|
||||||
if p == path.Base(kit.Path("")) {
|
|
||||||
return kit.Path("", arg...)
|
|
||||||
}
|
|
||||||
return path.Join(nfs.USR, p, path.Join(arg...))
|
|
||||||
}
|
|
||||||
func _repos_open(m *ice.Message, p string) *git.Repository {
|
|
||||||
return mdb.HashSelectTarget(m, p, nil).(*git.Repository)
|
|
||||||
}
|
|
||||||
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}
|
|
||||||
if refer, err := repos.Head(); err == nil {
|
|
||||||
args = append(args, BRANCH, refer.Name().String())
|
|
||||||
if commit, err := repos.CommitObject(refer.Hash()); err == nil {
|
|
||||||
args = append(args, mdb.TIME, commit.Author.When.Format(ice.MOD_TIME), COMMIT, commit.Message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if remote, err := repos.Remotes(); err == nil && len(remote) > 0 {
|
|
||||||
args = append(args, ORIGIN, remote[0].Config().URLs[0])
|
|
||||||
}
|
|
||||||
mdb.HashCreate(m.Options(mdb.TARGET, repos), args)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func _repos_each(m *ice.Message, title string, cb func(*git.Repository, ice.Maps) error) {
|
|
||||||
msg := m.Cmd("")
|
|
||||||
web.GoToast(m, title, func(toast func(string, int, int)) {
|
|
||||||
list, count, total := []string{}, 0, msg.Length()
|
|
||||||
msg.Table(func(value ice.Maps) {
|
|
||||||
toast(value[REPOS], count, total)
|
|
||||||
if err := cb(_repos_open(m, value[REPOS]), value); err != nil && err != git.NoErrAlreadyUpToDate {
|
|
||||||
web.Toast(m, err.Error(), "error: "+value[REPOS], "", "3s")
|
|
||||||
list = append(list, value[REPOS])
|
|
||||||
m.Sleep3s()
|
|
||||||
}
|
|
||||||
count++
|
|
||||||
})
|
|
||||||
if len(list) > 0 {
|
|
||||||
web.Toast(m, strings.Join(list, ice.NL), ice.FAILURE, "30s")
|
|
||||||
} else {
|
|
||||||
toast(ice.SUCCESS, count, total)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
|
||||||
func _repos_log(m *ice.Message, repos *git.Repository) error {
|
|
||||||
iter, err := repos.Log(&git.LogOptions{})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
limit := 30
|
|
||||||
defer m.StatusTimeCount()
|
|
||||||
m.Push(mdb.TIME, m.Time())
|
|
||||||
m.Push(COMMIT, INDEX)
|
|
||||||
m.Push(aaa.USERNAME, m.Option(ice.MSG_USERNAME))
|
|
||||||
m.Push(mdb.TEXT, "add some")
|
|
||||||
m.Push("files", 0).Push("adds", 0).Push("dels", 0)
|
|
||||||
return iter.ForEach(func(commit *object.Commit) error {
|
|
||||||
if m.Length() > limit {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
m.Push(mdb.TIME, commit.Author.When)
|
|
||||||
m.Push(COMMIT, commit.Hash.String())
|
|
||||||
m.Push(aaa.USERNAME, commit.Author.Name)
|
|
||||||
m.Push(mdb.TEXT, commit.Message)
|
|
||||||
files, adds, dels := 0, 0, 0
|
|
||||||
if stats, err := commit.Stats(); err == nil {
|
|
||||||
for _, stat := range stats {
|
|
||||||
files, adds, dels = files+1, adds+stat.Addition, dels+stat.Deletion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m.Push("files", files).Push("adds", adds).Push("dels", adds)
|
|
||||||
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
|
|
||||||
}
|
|
||||||
defer m.StatusTimeCount()
|
|
||||||
for _, stat := range stats {
|
|
||||||
m.Push(nfs.FILE, stat.Name).Push("add", stat.Addition).Push("del", stat.Deletion)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
func _repos_status(m *ice.Message, repos *git.Repository) error {
|
|
||||||
work, err := repos.Worktree()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
status, err := work.Status()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer m.StatusTimeCount()
|
|
||||||
for k, v := range status {
|
|
||||||
switch kit.Ext(k) {
|
|
||||||
case "swp", "swo":
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
m.Push(nfs.FILE, k).Push(STATUS, string(v.Worktree)+string(v.Staging))
|
|
||||||
switch v.Worktree {
|
|
||||||
case git.Untracked:
|
|
||||||
m.PushButton(ADD, nfs.TRASH)
|
|
||||||
case git.Modified:
|
|
||||||
m.PushButton(ADD)
|
|
||||||
default:
|
|
||||||
m.PushButton(COMMIT)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
CLONE = "clone"
|
|
||||||
PULL = "pull"
|
|
||||||
PUSH = "push"
|
|
||||||
STATUS = "status"
|
|
||||||
ADD = "add"
|
|
||||||
COMMIT = "commit"
|
|
||||||
LOG = "log"
|
|
||||||
|
|
||||||
ORIGIN = "origin"
|
|
||||||
BRANCH = "branch"
|
|
||||||
INDEX = "index"
|
|
||||||
)
|
|
||||||
const (
|
|
||||||
REPOS = "repos"
|
|
||||||
)
|
|
||||||
const GIT = "git"
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
web.Index.MergeCommands(ice.Commands{
|
|
||||||
web.PP(ice.REQUIRE): {Name: "/require/shylinux.com/x/volcanos/proto.js", Help: "代码库", Hand: func(m *ice.Message, arg ...string) {
|
|
||||||
if len(arg) < 4 {
|
|
||||||
m.RenderStatusBadRequest()
|
|
||||||
} else if path.Join(arg[:3]...) == ice.Info.Make.Module && nfs.Exists(m, path.Join(arg[3:]...)) {
|
|
||||||
m.RenderDownload(path.Join(arg[3:]...))
|
|
||||||
} else {
|
|
||||||
p := path.Join(kit.Select(ice.USR_REQUIRE, m.Cmdx(cli.SYSTEM, "go", "env", "GOMODCACHE")), path.Join(arg...))
|
|
||||||
if !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]...), ice.AT, 2)
|
|
||||||
to := path.Join(ice.USR_REQUIRE, path.Join(arg[:3]...))
|
|
||||||
_, err := git.PlainClone(to, false, &git.CloneOptions{URL: "https://" + ls[0], ReferenceName: plumbing.NewBranchReferenceName(kit.Select(ice.Info.Gomod[ls[0]], ls, 1))})
|
|
||||||
m.Warn(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m.RenderDownload(p)
|
|
||||||
}
|
|
||||||
}},
|
|
||||||
})
|
|
||||||
code.Index.MergeCommands(ice.Commands{
|
|
||||||
REPOS: {Name: "repos repos 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, func(value ice.Maps) { _repos_insert(m, value[nfs.PATH]) })
|
|
||||||
_repos_insert(m, kit.Path(""))
|
|
||||||
}},
|
|
||||||
"upload-pack": {Hand: func(m *ice.Message, arg ...string) {
|
|
||||||
if err := file.ServeUploadPack(arg[0]); err != nil && err != io.EOF {
|
|
||||||
fmt.Fprintln(os.Stderr, "ERR:", err)
|
|
||||||
os.Exit(128)
|
|
||||||
}
|
|
||||||
}},
|
|
||||||
"receive-pack": {Hand: func(m *ice.Message, arg ...string) {
|
|
||||||
if err := file.ServeReceivePack(arg[0]); err != nil && err != io.EOF {
|
|
||||||
fmt.Fprintln(os.Stderr, "ERR:", err)
|
|
||||||
fmt.Fprintln(os.Stderr, arg[0])
|
|
||||||
os.Exit(128)
|
|
||||||
}
|
|
||||||
}},
|
|
||||||
CLONE: {Name: "clone origin* branch name path", 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))))
|
|
||||||
_, err := git.PlainClone(m.Option(nfs.PATH), false, &git.CloneOptions{URL: m.Option(ORIGIN)})
|
|
||||||
m.Warn(err)
|
|
||||||
}},
|
|
||||||
PULL: {Hand: func(m *ice.Message, arg ...string) {
|
|
||||||
_repos_each(m, "repos pull", func(repos *git.Repository, value ice.Maps) error {
|
|
||||||
if value[ORIGIN] == "" {
|
|
||||||
return nil
|
|
||||||
} else if work, err := repos.Worktree(); err != nil {
|
|
||||||
return err
|
|
||||||
} else {
|
|
||||||
return work.Pull(&git.PullOptions{})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}},
|
|
||||||
PUSH: {Hand: func(m *ice.Message, arg ...string) {
|
|
||||||
list := map[string]*url.URL{}
|
|
||||||
m.Cmd(nfs.CAT, kit.HomePath(".git-credentials"), func(line string) {
|
|
||||||
u := kit.ParseURL(line)
|
|
||||||
list[u.Host] = u
|
|
||||||
})
|
|
||||||
_repos_each(m, "repos push", func(repos *git.Repository, value ice.Maps) error {
|
|
||||||
if value[ORIGIN] == "" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
u := list[kit.ParseURL(value[ORIGIN]).Host]
|
|
||||||
if password, ok := u.User.Password(); !ok {
|
|
||||||
return errors.New("not found password")
|
|
||||||
} else {
|
|
||||||
return repos.Push(&git.PushOptions{Auth: &http.BasicAuth{Username: u.User.Username(), Password: password}})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}},
|
|
||||||
STATUS: {Hand: func(m *ice.Message, arg ...string) {
|
|
||||||
_repos_each(m, "repos status", func(repos *git.Repository, value ice.Maps) error { return _repos_status(m, repos) })
|
|
||||||
}},
|
|
||||||
ADD: {Hand: func(m *ice.Message, arg ...string) {
|
|
||||||
if work, err := _repos_open(m, m.Option(REPOS)).Worktree(); !m.Warn(err) {
|
|
||||||
_, err := work.Add(m.Option(nfs.FILE))
|
|
||||||
m.Warn(err)
|
|
||||||
}
|
|
||||||
}},
|
|
||||||
COMMIT: {Name: "commit actions=add,opt,fix comment*=some", Hand: func(m *ice.Message, arg ...string) {
|
|
||||||
if work, err := _repos_open(m, m.Option(REPOS)).Worktree(); !m.Warn(err) {
|
|
||||||
_, err := work.Commit(m.Option("actions")+ice.SP+m.Option("comment"), &git.CommitOptions{})
|
|
||||||
m.Warn(err)
|
|
||||||
}
|
|
||||||
}},
|
|
||||||
LOG: {Hand: func(m *ice.Message, arg ...string) {
|
|
||||||
_repos_log(m, _repos_open(m, kit.Select(m.Option(REPOS), arg, 0)))
|
|
||||||
}},
|
|
||||||
code.VIMER: {Hand: func(m *ice.Message, arg ...string) {
|
|
||||||
if len(arg) == 0 || arg[0] != ice.RUN {
|
|
||||||
arg = []string{path.Join(arg[:2]...), kit.Select("README.md", arg, 2)}
|
|
||||||
} else if kit.Select("", arg, 1) != ctx.ACTION {
|
|
||||||
ls := kit.Split(kit.Select(arg[1], m.Option(nfs.DIR_ROOT)), nfs.PS)
|
|
||||||
if ls[1] == INDEX {
|
|
||||||
if len(arg) < 3 {
|
|
||||||
m.Cmdy(nfs.DIR, nfs.PWD, kit.Dict(nfs.DIR_ROOT, _repos_path(m, ls[0])))
|
|
||||||
} else {
|
|
||||||
m.Cmdy(nfs.CAT, _repos_path(m, ls[0], arg[2]))
|
|
||||||
}
|
|
||||||
} else if commit, err := _repos_open(m, ls[0]).CommitObject(plumbing.NewHash(ls[1])); m.Warn(err) {
|
|
||||||
return
|
|
||||||
} else if len(arg) < 3 {
|
|
||||||
if iter, err := commit.Files(); !m.Warn(err) {
|
|
||||||
iter.ForEach(func(file *object.File) error {
|
|
||||||
m.Push(nfs.PATH, file.Name)
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if file, err := commit.File(arg[2]); !m.Warn(err) {
|
|
||||||
if content, err := file.Contents(); !m.Warn(err) {
|
|
||||||
m.Echo(content)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ctx.DisplayLocal(m, "code/vimer.js")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx.ProcessField(m, "", arg, arg...)
|
|
||||||
}},
|
|
||||||
nfs.TRASH: {Hand: func(m *ice.Message, arg ...string) {
|
|
||||||
kit.If(!m.Warn(m.Option(REPOS) == ""), func() { m.Cmdy(nfs.TRASH, _repos_path(m, m.Option(REPOS), m.Option(nfs.FILE))) })
|
|
||||||
}},
|
|
||||||
}, mdb.HashAction(mdb.SHORT, REPOS, mdb.FIELD, "time,repos,branch,commit,origin"), mdb.ClearOnExitHashAction()), Hand: func(m *ice.Message, arg ...string) {
|
|
||||||
if len(arg) == 0 {
|
|
||||||
mdb.HashSelect(m, arg...).Action(CLONE, PULL, PUSH, STATUS)
|
|
||||||
} else if len(arg) == 1 {
|
|
||||||
_repos_log(m, _repos_open(m, arg[0]))
|
|
||||||
// _repos_status(m, _repos_open(m, arg[0]))
|
|
||||||
} else if len(arg) == 2 {
|
|
||||||
if repos := _repos_open(m, arg[0]); arg[1] == INDEX {
|
|
||||||
_repos_status(m, repos)
|
|
||||||
} else {
|
|
||||||
_repos_stats(m, repos, arg[1])
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m.Cmdy("", code.VIMER, arg)
|
|
||||||
}
|
|
||||||
}},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user