diff --git a/misc/git/repos.go b/misc/git/repos.go index c9c000e4..98e1a6fb 100644 --- a/misc/git/repos.go +++ b/misc/git/repos.go @@ -11,13 +11,11 @@ import ( "shylinux.com/x/icebergs/base/ctx" "shylinux.com/x/icebergs/base/mdb" "shylinux.com/x/icebergs/base/nfs" + "shylinux.com/x/icebergs/base/web" kit "shylinux.com/x/toolkits" ) func _repos_path(name string) string { - if strings.Contains(name, ":\\") { - return name - } 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 { @@ -25,7 +23,7 @@ func _repos_cmd(m *ice.Message, name string, arg ...string) *ice.Message { return m.Copy(_git_cmd(m, arg...)) } func _repos_init(m *ice.Message, p string) string { - os.MkdirAll(path.Join(p, "refs/heads/"), ice.MOD_DIR) + os.MkdirAll(path.Join(p, REFS_HEADS), ice.MOD_DIR) os.MkdirAll(path.Join(p, "objects/info/"), ice.MOD_DIR) return m.Cmdx(nfs.SAVE, path.Join(p, "HEAD"), "ref: refs/heads/master") } @@ -33,10 +31,10 @@ func _repos_insert(m *ice.Message, name string, path string) bool { if repos, e := gogit.OpenRepository(_git_dir(path)); e == nil { 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, kit.Select("", kit.Slice(kit.Split(repos.GetOrigin()), -1), 0)) + BRANCH, repos.GetBranch(), ORIGIN, kit.Select("", kit.Split(repos.GetOrigin()), -1)) } else { mdb.HashCreate(m, REPOS, name, nfs.PATH, path, mdb.TIME, m.Time(), - BRANCH, repos.GetBranch(), ORIGIN, kit.Select("", kit.Slice(kit.Split(repos.GetOrigin()), -1), 0)) + BRANCH, repos.GetBranch(), ORIGIN, kit.Select("", kit.Split(repos.GetOrigin()), -1)) } return true } @@ -44,14 +42,14 @@ func _repos_insert(m *ice.Message, name string, path string) bool { } func _repos_branch(m *ice.Message, dir string) { if repos, e := gogit.OpenRepository(dir); !m.Warn(e, ice.ErrNotFound, dir) { - nfs.DirDeepAll(m, path.Join(dir, "refs/heads/"), "", func(value ice.Maps) { - if refer, e := repos.LookupReference("refs/heads/" + value[nfs.PATH]); !m.Warn(e, ice.ErrNotValid, value[nfs.PATH]) { + nfs.DirDeepAll(m, path.Join(dir, REFS_HEADS), "", func(value ice.Maps) { + if refer, e := repos.LookupReference(REFS_HEADS + value[nfs.PATH]); !m.Warn(e, ice.ErrNotValid, value[nfs.PATH]) { 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)) m.Push(BRANCH, value[nfs.PATH]) m.Push(COMMIT, ci.Oid.String()[:6]) m.Push(AUTHOR, ci.Author.Name) - m.Push(mdb.TEXT, ci.Message) + m.Push(MESSAGE, ci.Message) } } }, nfs.PATH) @@ -59,12 +57,12 @@ func _repos_branch(m *ice.Message, dir string) { } func _repos_commit(m *ice.Message, dir, branch string, cb func(*gogit.Commit, *gogit.Repository) bool) { if repos, e := gogit.OpenRepository(dir); !m.Warn(e, ice.ErrNotFound, dir) { - if refer, e := repos.LookupReference("refs/heads/" + branch); !m.Warn(e, ice.ErrNotFound, branch) { + if refer, e := repos.LookupReference(REFS_HEADS + branch); !m.Warn(e, ice.ErrNotFound, branch) { if cb == nil { m.Push(mdb.TIME, m.Time()) m.Push(COMMIT, cli.PWD) m.Push(AUTHOR, kit.Select(m.Option(ice.MSG_USERNAME), m.Option(ice.MSG_USERNICK))) - m.Push(mdb.TEXT, "opt some") + m.Push(MESSAGE, "opt some") } for oid := refer.Oid; oid != nil; { if ci, e := repos.LookupCommit(oid); !m.Warn(e, ice.ErrNotValid, oid.String()) { @@ -72,7 +70,7 @@ func _repos_commit(m *ice.Message, dir, branch string, cb func(*gogit.Commit, *g m.Push(mdb.TIME, ci.Author.When.Format(ice.MOD_TIME)) m.Push(COMMIT, ci.Oid.String()[:6]) m.Push(AUTHOR, ci.Author.Name) - m.Push(mdb.TEXT, ci.Message) + m.Push(MESSAGE, ci.Message) } else if cb(ci, repos) { break } @@ -89,29 +87,59 @@ func _repos_commit(m *ice.Message, dir, branch string, cb func(*gogit.Commit, *g 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.Option(cli.CMD_DIR, path.Dir(dir)) + m.Echo(_git_cmds(m, DIFF)) return } else if file == nfs.PWD { file = "" } _repos_commit(m, dir, branch, func(ci *gogit.Commit, repos *gogit.Repository) bool { - if strings.HasPrefix(ci.Oid.String(), commit) { - if tree, e := repos.LookupTree(ci.TreeId()); !m.Warn(e, ice.ErrNotValid, ci.TreeId().String) { - m.Logs(mdb.SELECT, REPOS, dir, BRANCH, branch, COMMIT, commit, "tree", tree.Oid.String()[:6]) - tree.Walk(func(p string, v *gogit.TreeEntry) int { - if strings.HasPrefix(path.Join(p, v.Name), file) { - if cb == nil { - m.Push(mdb.HASH, v.Id.String()[:6]) - m.Push(nfs.PATH, path.Join(p, v.Name)+kit.Select("", ice.PS, v.Type == gogit.ObjectTree)) - } else if cb(v, repos) { - return -1 - } - } - return 0 - }) - } - return true + if !strings.HasPrefix(ci.Oid.String(), commit) { + return false } - return false + list := ice.Maps{} + if p := ci.Parent(0); p != nil { + if ci, e := repos.LookupCommit(p.Oid); e == nil { + if tree, e := repos.LookupTree(ci.TreeId()); !m.Warn(e, ice.ErrNotValid, ci.TreeId().String) { + tree.Walk(func(p string, v *gogit.TreeEntry) int { + list[path.Join(p, v.Name)+kit.Select("", ice.PS, v.Type == gogit.ObjectTree)] = v.Id.String() + return 0 + }) + } + } + } + if tree, e := repos.LookupTree(ci.TreeId()); !m.Warn(e, ice.ErrNotValid, ci.TreeId().String) { + m.Logs(mdb.SELECT, REPOS, dir, BRANCH, branch, COMMIT, commit, "tree", tree.Oid.String()[:6]) + tree.Walk(func(p string, v *gogit.TreeEntry) int { + if strings.HasPrefix(path.Join(p, v.Name), file) { + if cb == nil { + pp := path.Join(p, v.Name) + kit.Select("", ice.PS, v.Type == gogit.ObjectTree) + if v.Type == gogit.ObjectTree { + + } else if id, ok := list[pp]; ok && id == v.Id.String() { + if m.Option("_index") == web.CODE_INNER { + m.Push(mdb.HASH, v.Id.String()[:6]).Push(nfs.PATH, pp).Push(mdb.STATUS, "") + } + } else if ok { + m.Push(mdb.HASH, v.Id.String()[:6]).Push(nfs.PATH, pp).Push(mdb.STATUS, "~~~") + } else { + m.Push(mdb.HASH, v.Id.String()[:6]).Push(nfs.PATH, pp).Push(mdb.STATUS, "+++") + } + delete(list, pp) + } else if cb(v, repos) { + return -1 + } + } + return 0 + }) + } + kit.Fetch(list, 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.Option(cli.CMD_DIR, dir) + m.Echo(_git_cmds(m, DIFF, ci.Oid.String()+"^", ci.Oid.String())) + m.Status(mdb.TIME, ci.Author.When.Format(ice.MOD_TIME), "stat", _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) { @@ -132,22 +160,38 @@ func _repos_cat(m *ice.Message, dir, branch, commit, file string) { } const ( - ORIGIN = "origin" - BRANCH = "branch" - MASTER = "master" - AUTHOR = "author" - INIT = "init" + REFS_HEADS = "refs/heads/" + + CONFIG = "config" + ORIGIN = "origin" + BRANCH = "branch" + MASTER = "master" + AUTHOR = "author" + MESSAGE = "message" + INIT = "init" ) const REPOS = "repos" func init() { Index.MergeCommands(ice.Commands{ - REPOS: {Name: "repos repos branch commit path auto create inner", Help: "代码库", Actions: ice.MergeActions(ice.Actions{ + REPOS: {Name: "repos repos@key branch@key commit@key path@key auto", Help: "代码库", Actions: ice.MergeActions(ice.Actions{ 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]) }) _repos_insert(m, path.Base(kit.Pwd()), kit.Pwd()) cli.IsSystem(m, GIT) }}, + mdb.INPUTS: {Hand: func(m *ice.Message, arg ...string) { + switch arg[0] { + case REPOS: + mdb.HashSelect(m).Cut(REPOS) + case BRANCH: + m.Cmdy("", m.Option(REPOS)).Cut(BRANCH) + 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") + } + }}, mdb.CREATE: {Name: "create origin name path", Hand: func(m *ice.Message, arg ...string) { m.OptionDefault(mdb.NAME, strings.TrimSuffix(path.Base(m.Option(ORIGIN)), ".git")) m.OptionDefault(nfs.PATH, path.Join(ice.USR, m.Option(mdb.NAME))) @@ -159,7 +203,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(_repos_config, m.Option(ORIGIN))) _git_cmd(m, PULL, ORIGIN, m.OptionDefault(BRANCH, MASTER)) } }}, @@ -167,24 +211,26 @@ func init() { if len(arg) == 0 || arg[0] != ice.RUN { arg = []string{_repos_path(arg[0]), kit.Select("README.md", arg, 3)} } else if kit.Select("", arg, 1) != ctx.ACTION { - if ctx.DisplayLocal(m, "code/inner.js"); len(arg) < 3 { - _repos_dir(m, _git_dir(_repos_path(m.Option(REPOS))), m.Option(BRANCH), m.Option(COMMIT), kit.Select("", arg, 1), nil) + if dir := _git_dir(_repos_path(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, _git_dir(_repos_path(m.Option(REPOS))), m.Option(BRANCH), m.Option(COMMIT), arg[2]) + _repos_cat(m, dir, m.Option(BRANCH), m.Option(COMMIT), arg[2]) + ctx.DisplayLocal(m, "code/inner.js") } return } - ctx.ProcessField(m, "web.code.inner", arg, arg...) + ctx.ProcessField(m, web.CODE_INNER, arg, arg...) }}, }, mdb.HashAction(mdb.SHORT, REPOS, mdb.FIELD, "time,repos,branch,commit,origin"), mdb.ClearHashOnExitAction()), Hand: func(m *ice.Message, arg ...string) { if len(arg) == 0 || arg[0] == "" { - mdb.HashSelect(m, arg...) - } else if len(arg) == 1 || arg[1] == "" { - _repos_branch(m, _git_dir(_repos_path(arg[0]))) + mdb.HashSelect(m, arg...).Action(mdb.CREATE) + } else if dir := _git_dir(_repos_path(arg[0])); len(arg) == 1 || arg[1] == "" { + _repos_branch(m, dir) } else if len(arg) == 2 || arg[2] == "" { - _repos_commit(m, _git_dir(_repos_path(arg[0])), arg[1], nil) + _repos_commit(m, dir, arg[1], nil) } else if len(arg) == 3 || arg[3] == "" || strings.HasSuffix(arg[3], ice.PS) { - _repos_dir(m, _git_dir(_repos_path(arg[0])), arg[1], arg[2], kit.Select("", arg, 3), nil) + _repos_dir(m, dir, arg[1], arg[2], kit.Select("", arg, 3), nil) + return } else { m.Cmdy("", "inner", arg) }