1
0
forked from x/ContextOS
This commit is contained in:
shaoying 2019-01-07 23:16:55 +08:00
parent 014a591bb6
commit b965e0c78a
4 changed files with 88 additions and 168 deletions

View File

@ -146,21 +146,21 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
if v, ok := kit.Chain(conf, "cmd").(string); ok { if v, ok := kit.Chain(conf, "cmd").(string); ok {
arg[0] = m.Parse(v) arg[0] = m.Parse(v)
} }
cmd := exec.Command(arg[0])
if v, ok := kit.Chain(conf, "path").(string); ok {
cmd.Path = m.Parse(v)
}
m.Log("info", "cmd.path %v", cmd.Path)
args := []string{} args := []string{arg[0]}
if list, ok := kit.Chain(conf, "arg").([]interface{}); ok { if list, ok := kit.Chain(conf, "arg").([]interface{}); ok {
for _, v := range list { for _, v := range list {
args = append(args, m.Parse(v)) args = append(args, m.Parse(v))
} }
} }
if args = append(args, arg[1:]...); len(args) > 0 { args = append(args, arg[1:]...)
cmd.Args = args cmd := exec.Command(args[0], args[1:]...)
if v, ok := kit.Chain(conf, "path").(string); ok {
cmd.Path = m.Parse(v)
} }
m.Log("info", "cmd.path %v", cmd.Path)
m.Log("info", "cmd.arg %v", cmd.Args) m.Log("info", "cmd.arg %v", cmd.Args)
for k, v := range m.Confm("system_env") { for k, v := range m.Confm("system_env") {
@ -204,10 +204,6 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
if e := cmd.Run(); e != nil { if e := cmd.Run(); e != nil {
m.Echo("error: ").Echo("%s\n", e).Echo(err.String()) m.Echo("error: ").Echo("%s\n", e).Echo(err.String())
m.Log("trace", "%s\n", e) m.Log("trace", "%s\n", e)
b, _ := cmd.CombinedOutput()
m.Echo("error: %s", string(b))
m.Log("trace", "error: %s", string(b))
} else { } else {
switch m.Option("cmd_parse") { switch m.Option("cmd_parse") {
case "json": case "json":

View File

@ -304,9 +304,14 @@ type Message struct {
} }
func (m *Message) Log(action string, str string, arg ...interface{}) *Message { func (m *Message) Log(action string, str string, arg ...interface{}) *Message {
if l := m.Sess("log", false); l != nil { if l := m.Sess("log", false); l != nil {
if log, ok := l.target.Server.(LOGGER); ok { if log, ok := l.target.Server.(LOGGER); ok {
log.Log(m, action, str, arg...) log.Log(m, action, str, arg...)
if action == "error" {
log.Log(m, "error", "%s", m.Format("full"))
log.Log(m, "error", "%s\n\n", string(debug.Stack()))
}
return m return m
} }
} }
@ -927,7 +932,7 @@ func (m *Message) Parse(arg interface{}) string {
if len(str) > 1 && str[0] == '@' { if len(str) > 1 && str[0] == '@' {
return m.Confx(str[1:]) return m.Confx(str[1:])
} }
return m.Cmdx(str) return str
} }
return "" return ""
} }
@ -1135,13 +1140,13 @@ func (m *Message) TryCatch(msg *Message, safe bool, hand ...func(msg *Message))
case io.EOF: case io.EOF:
case nil: case nil:
default: default:
m.Log("stack", "%s", msg.Format("full")) m.Log("stack", "m: %s", m.Format("full"))
m.Log("stack", "msg: %s", msg.Format("full"))
m.Log("stack", "%s\n%s\n", e, string(debug.Stack())) m.Log("stack", "%s\n%s\n", e, string(debug.Stack()))
if len(hand) > 1 { if len(hand) > 1 {
m.TryCatch(msg, safe, hand[1:]...) m.TryCatch(msg, safe, hand[1:]...)
} else if !safe { } else if !safe {
m.Log("error", "%s not catch %v", msg.Format(), e)
msg.Assert(e) msg.Assert(e)
} }
} }
@ -1233,8 +1238,11 @@ func (m *Message) Confm(key string, args ...interface{}) map[string]interface{}
if len(args) > 0 { if len(args) > 0 {
switch arg := args[0].(type) { switch arg := args[0].(type) {
case []interface{}: case []interface{}:
chain, args = arg, args[1:]
case []string: case []string:
chain, args = arg, args[1:] chain, args = arg, args[1:]
case string:
chain, args = arg, args[1:]
} }
} }

View File

@ -2,6 +2,7 @@ package log
import ( import (
"contexts/ctx" "contexts/ctx"
"path"
"toolkit" "toolkit"
"fmt" "fmt"
@ -38,7 +39,7 @@ func (log *LOG) Log(msg *ctx.Message, action string, str string, arg ...interfac
for _, v := range []string{action, "bench"} { for _, v := range []string{action, "bench"} {
for i := len(args); i >= 0; i-- { for i := len(args); i >= 0; i-- {
if value := log.Value(m, append([]string{v}, args[:i]...)); kit.Right(value) && kit.Right(value["file"]) { if value := log.Value(m, append([]string{v}, args[:i]...)); kit.Right(value) && kit.Right(value["file"]) {
name := kit.Format(value["file"]) name := path.Join(m.Conf("logdir"), kit.Format(value["file"]))
file, ok := log.file[name] file, ok := log.file[name]
if !ok { if !ok {
if f, e := os.Create(name); e == nil { if f, e := os.Create(name); e == nil {
@ -67,6 +68,7 @@ func (log *LOG) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server
return s return s
} }
func (log *LOG) Begin(m *ctx.Message, arg ...string) ctx.Server { func (log *LOG) Begin(m *ctx.Message, arg ...string) ctx.Server {
os.Mkdir(m.Conf("logdir"), 0770)
log.file = map[string]*os.File{} log.file = map[string]*os.File{}
return log return log
} }
@ -87,6 +89,7 @@ var Index = &ctx.Context{Name: "log", Help: "日志中心",
"nout": &ctx.Cache{Name: "nout", Value: "0", Help: "日志输出数量"}, "nout": &ctx.Cache{Name: "nout", Value: "0", Help: "日志输出数量"},
}, },
Configs: map[string]*ctx.Config{ Configs: map[string]*ctx.Config{
"logdir": &ctx.Config{Name: "logdir", Value: "var/log", Help: ""},
"output": &ctx.Config{Name: "output", Value: map[string]interface{}{ "output": &ctx.Config{Name: "output", Value: map[string]interface{}{
"error": map[string]interface{}{"value": map[string]interface{}{"file": "error.log", "meta": []interface{}{"time", "ship"}, "color_begin": "\033[31m", "color_end": "\033[0m"}}, "error": map[string]interface{}{"value": map[string]interface{}{"file": "error.log", "meta": []interface{}{"time", "ship"}, "color_begin": "\033[31m", "color_end": "\033[0m"}},
"trace": map[string]interface{}{"value": map[string]interface{}{"file": "error.log", "meta": []interface{}{"time", "ship"}, "color_begin": "\033[32m", "color_end": "\033[0m"}}, "trace": map[string]interface{}{"value": map[string]interface{}{"file": "error.log", "meta": []interface{}{"time", "ship"}, "color_begin": "\033[32m", "color_end": "\033[0m"}},

View File

@ -858,14 +858,6 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
"qr_size": &ctx.Config{Name: "qr_size", Value: "256", Help: "二维码的默认大小"}, "qr_size": &ctx.Config{Name: "qr_size", Value: "256", Help: "二维码的默认大小"},
"pscolor": &ctx.Config{Name: "pscolor", Value: "2", Help: "pscolor"}, "pscolor": &ctx.Config{Name: "pscolor", Value: "2", Help: "pscolor"},
"nfs_name": &ctx.Config{Name: "nfs_name", Value: "file", Help: "默认模块命名", Hand: func(m *ctx.Message, x *ctx.Config, arg ...string) string {
if len(arg) > 0 {
return arg[0]
}
return fmt.Sprintf("%s%d", x.Value, m.Capi("nfile", 1))
}},
"nfs_help": &ctx.Config{Name: "nfs_help", Value: "file", Help: "默认模块帮助"},
"buf_size": &ctx.Config{Name: "buf_size", Value: "1024", Help: "读取文件的缓存区的大小"}, "buf_size": &ctx.Config{Name: "buf_size", Value: "1024", Help: "读取文件的缓存区的大小"},
"dir_conf": &ctx.Config{Name: "dir_conf", Value: map[string]interface{}{ "dir_conf": &ctx.Config{Name: "dir_conf", Value: map[string]interface{}{
@ -873,19 +865,20 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
}, Help: "读取文件的缓存区的大小"}, }, Help: "读取文件的缓存区的大小"},
"dir_type": &ctx.Config{Name: "dir_type(file/dir/all)", Value: "all", Help: "dir命令输出的文件类型, file: 只输出普通文件, dir: 只输出目录文件, 否则输出所有文件"}, "dir_type": &ctx.Config{Name: "dir_type(file/dir/all)", Value: "all", Help: "dir命令输出的文件类型, file: 只输出普通文件, dir: 只输出目录文件, 否则输出所有文件"},
"dir_name": &ctx.Config{Name: "dir_name(name/tree/path/full)", Value: "name", Help: "dir命令输出文件名的类型, name: 文件名, tree: 带缩进的文件名, path: 相对路径, full: 绝对路径"},
"dir_fields": &ctx.Config{Name: "dir_fields(time/type/name/size/line/hash)", Value: "time size line filename", Help: "dir命令输出文件名的类型, name: 文件名, tree: 带缩进的文件名, path: 相对路径, full: 绝对路径"}, "dir_fields": &ctx.Config{Name: "dir_fields(time/type/name/size/line/hash)", Value: "time size line filename", Help: "dir命令输出文件名的类型, name: 文件名, tree: 带缩进的文件名, path: 相对路径, full: 绝对路径"},
"git_branch": &ctx.Config{Name: "git_branch", Value: "--list", Help: "版本控制状态参数"}, "git": &ctx.Config{Name: "git", Value: map[string]interface{}{
"git_status": &ctx.Config{Name: "git_status", Value: "-sb", Help: "版本控制状态参数"}, "args": []interface{}{"-C", "@git_dir"},
"git_diff": &ctx.Config{Name: "git_diff", Value: "--stat", Help: "版本控制状态参数"}, "info": map[string]interface{}{"cmds": []interface{}{"log", "status", "branch"}},
"git_log": &ctx.Config{Name: "git_log", Value: "--pretty=%h %an(%ad) %s --date=format:%m/%d %H:%M --graph", Help: "版本控制状态参数"}, "branch": map[string]interface{}{"args": []interface{}{"branch", "-v"}},
"git_log_form": &ctx.Config{Name: "git_log", Value: "stat", Help: "版本控制状态参数"}, "status": map[string]interface{}{"args": []interface{}{"status", "-sb"}},
"git_log_skip": &ctx.Config{Name: "git_log", Value: "0", Help: "版本控制状态参数"}, "log": map[string]interface{}{"args": []interface{}{"log", "-n", "limit", "--reverse", "pretty", "date"}},
"git_log_line": &ctx.Config{Name: "git_log", Value: "3", Help: "版本控制状态参数"}, "trans": map[string]interface{}{
"git_path": &ctx.Config{Name: "git_path", Value: ".", Help: "版本控制默认路径"}, "date": "--date=format:%m/%d %H:%M",
"git_info": &ctx.Config{Name: "git_info", Value: "branch status diff log", Help: "命令集合"}, "pretty": "--pretty=format:%h %ad %an %s",
"limit": "10",
},
}, Help: "命令集合"},
"paths": &ctx.Config{Name: "paths", Value: []interface{}{"var", "usr", "etc", ""}, Help: "文件路径"}, "paths": &ctx.Config{Name: "paths", Value: []interface{}{"var", "usr", "etc", ""}, Help: "文件路径"},
}, },
Commands: map[string]*ctx.Command{ Commands: map[string]*ctx.Command{
@ -953,143 +946,63 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
} }
return return
}}, }},
"git": &ctx.Command{ "git": &ctx.Command{Name: "git", Help: "版本控制", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
Name: "git branch|status|diff|log|info arg... [dir path]...", if len(arg) > 0 && arg[0] == "sum" {
Help: "版本控制, branch: 分支管理, status: 查看状态, info: 查看分支与状态, dir: 指定路径", if out, e := exec.Command("git", "log", "--shortstat", "--pretty=commit: %ad", "--date=format:%Y-%m-%d").CombinedOutput(); m.Assert(e) {
Form: map[string]int{"dir": 1, "git_info": 1, "git_log": 1, "git_log_form": 1}, for _, v := range strings.Split(string(out), "commit: ") {
Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) { if l := strings.Split(v, "\n"); len(l) > 2 {
m.Cmdy("cli.system", "git", arg) fs := strings.Split(strings.TrimSpace(l[2]), ", ")
m.Add("append", "date", l[0])
if adds := strings.Split(fs[1], " "); len(fs) > 2 {
dels := strings.Split(fs[2], " ")
m.Add("append", "adds", adds[0])
m.Add("append", "dels", dels[0])
} else if adds[1] == "insertions(+)" {
m.Add("append", "adds", adds[0])
m.Add("append", "dels", "0")
} else {
m.Add("append", "adds", "0")
m.Add("append", "dels", adds[0])
}
}
}
m.Table()
}
return return
}
if len(arg) == 0 { if len(arg) == 0 {
arg = []string{"info"} m.Cmdy("nfs.config", "git")
} return
cmds := []string{arg[0]}
switch arg[0] {
case "s":
arg[0] = "status"
case "b":
arg[0] = "branch"
case "d":
arg[0] = "diff"
}
if arg[0] == "info" {
cmds = strings.Split(m.Confx("git_info"), " ")
} }
wd, e := os.Getwd() wd, e := os.Getwd()
m.Assert(e) m.Assert(e)
if !m.Has("dir") { m.Option("git_dir", wd)
m.Option("dir", m.Confx("dir"))
} cmds := []string{}
for _, p := range m.Meta["dir"] { if v := m.Confv("git", []string{arg[0], "cmds"}); v != nil {
if !path.IsAbs(p) { cmds = append(cmds, kit.Trans(v)...)
p = path.Join(wd, p)
}
m.Echo("path: %s\n", p)
for _, c := range cmds {
args := []string{}
switch c {
case "branch", "status", "diff":
if c != "status" {
args = append(args, "--color")
}
args = append(args, strings.Split(m.Confx("git_"+c, arg, 1), " ")...)
if len(arg) > 2 {
args = append(args, arg[2:]...)
}
case "difftool":
cmd := exec.Command("git", "difftool", "-y")
m.Log("info", "cmd: %s %v", "git", "difftool", "-y")
cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr
if e := cmd.Start(); e != nil {
m.Echo("error: ")
m.Echo("%s\n", e)
} else if e := cmd.Wait(); e != nil {
m.Echo("error: ")
m.Echo("%s\n", e)
}
continue
case "csv":
cmd := exec.Command("git", "log", "--shortstat", "--pretty=commit: %ad", "--date=format:%Y-%m-%d")
if out, e := cmd.CombinedOutput(); e != nil {
m.Echo("error: ")
m.Echo("%s\n", e)
} else { } else {
f, e := os.Create(arg[1]) cmds = append(cmds, arg[0])
m.Assert(e)
defer f.Close()
type stat struct {
date string
adds int
dels int
} }
stats := []*stat{}
list := strings.Split(string(out), "commit: ") for _, cmd := range cmds {
for _, v := range list { args := append([]string{}, kit.Trans(m.Confv("git", "args"))...)
l := strings.Split(v, "\n") if v := m.Confv("git", []string{cmd, "args"}); v != nil {
if len(l) > 2 { args = append(args, kit.Trans(v)...)
fs := strings.Split(strings.Trim(l[2], " "), ", ")
stat := &stat{date: l[0]}
if len(fs) > 2 {
adds := strings.Split(fs[1], " ")
dels := strings.Split(fs[2], " ")
a, e := strconv.Atoi(adds[0])
m.Assert(e)
stat.adds = a
d, e := strconv.Atoi(dels[0])
m.Assert(e)
stat.dels = d
} else { } else {
adds := strings.Split(fs[1], " ") args = append(args, cmd)
a, e := strconv.Atoi(adds[0])
m.Assert(e)
if adds[1] == "insertions(+)" {
stat.adds = a
} else {
stat.dels = a
} }
}
stats = append(stats, stat)
}
}
fmt.Fprintf(f, "order,date,adds,dels,sum,top,bottom,last\n")
l := len(stats)
for i := 0; i < l/2; i++ {
stats[i], stats[l-i-1] = stats[l-i-1], stats[i]
}
sum := 0
for i, v := range stats {
fmt.Fprintf(f, "%d,%s,%d,%d,%d,%d,%d,%d\n", i, v.date, v.adds, v.dels, sum, sum+v.adds, sum-v.dels, sum+v.adds-v.dels)
sum += v.adds - v.dels
}
}
continue
case "log":
args = append(args, "--color")
args = append(args, strings.Split(m.Confx("git_log"), " ")...)
args = append(args, fmt.Sprintf("--%s", m.Confx("git_log_form")))
args = append(args, m.Confx("git_log_skip", arg, 1, "--skip=%s"))
args = append(args, m.Confx("git_log_line", arg, 2, "-n %s"))
default:
args = append(args, arg[1:]...) args = append(args, arg[1:]...)
for i, _ := range args {
args[i] = m.Parse(args[i])
args[i] = kit.Select(args[i], m.Conf("git", []string{"trans", args[i]}))
} }
switch c { m.Cmd("cli.system", "git", args).Echo("\n\n").CopyTo(m)
case "commit":
m.Find("web.code").Cmd("counter", "ncommit", 1)
case "push":
m.Find("web.code").Cmd("counter", "npush", 1)
}
m.Log("info", "cmd: %s %v", "git", kit.Trans("-C", p, c, args))
msg := m.Sess("cli").Cmd("system", "git", "-C", p, c, args)
m.Copy(msg, "result").Copy(msg, "append")
m.Echo("\n")
}
} }
return return
}}, }},