1
0
forked from x/icebergs
This commit is contained in:
shaoying 2022-11-20 01:38:31 +08:00
parent 41021ff55b
commit b2b20bcc1b
18 changed files with 109 additions and 136 deletions

View File

@ -17,5 +17,5 @@ func init() { ice.Index.Register(Index, nil, ROLE, SESS, TOTP, USER, RSA) }
func Right(m *ice.Message, arg ...ice.Any) bool {
return m.Option(ice.MSG_USERROLE) == ROOT || !m.Warn(m.Cmdx(ROLE, RIGHT, m.Option(ice.MSG_USERROLE), arg) != ice.OK,
ice.ErrNotRight, kit.Join(kit.Simple(arg), ice.PT), USERROLE, m.Option(ice.MSG_USERROLE), logs.FileLineMeta(kit.FileLine(2, 3)))
ice.ErrNotRight, kit.Join(kit.Simple(arg), ice.PT), USERROLE, m.Option(ice.MSG_USERROLE), logs.FileLineMeta(logs.FileLine(2)))
}

View File

@ -16,7 +16,7 @@ func _sess_check(m *ice.Message, sessid string) {
return
}
_source := logs.FileLineMeta(logs.FileLine(-1, 3))
_source := logs.FileLineMeta(logs.FileLine(-1))
mdb.HashSelectDetail(m, sessid, func(value ice.Map) {
if m.Warn(kit.Time(kit.Format(value[mdb.TIME])) < kit.Time(m.Time()), ice.ErrNotValid, sessid) {
return // 会话超时
@ -98,5 +98,5 @@ func SessAuth(m *ice.Message, value ice.Maps, arg ...string) {
m.Option(ice.MSG_USERROLE, value[USERROLE])
m.Option(ice.MSG_USERNAME, value[USERNAME])
m.Option(ice.MSG_USERNICK, value[USERNICK])
m.Auth(USERROLE, value[USERROLE], USERNAME, value[USERNAME], USERNICK, value[USERNICK], arg, logs.FileLineMeta(logs.FileLine(2, 3)))
m.Auth(USERROLE, value[USERROLE], USERNAME, value[USERNAME], USERNICK, value[USERNICK], arg, logs.FileLineMeta(logs.FileLine(2)))
}

View File

@ -29,7 +29,7 @@ func _user_login(m *ice.Message, name, word string) {
_user_create(m.Spawn(), name, word)
}
_source := logs.FileLineMeta(logs.FileLine(-1, 3))
_source := logs.FileLineMeta(logs.FileLine(-1))
mdb.HashSelectDetail(m.Spawn(), name, func(value ice.Map) {
if m.Warn(word != "" && word != kit.Format(kit.Value(value, PASSWORD)), ice.ErrNotRight) {
return

View File

@ -9,6 +9,7 @@ import (
"shylinux.com/x/icebergs/base/mdb"
"shylinux.com/x/icebergs/base/nfs"
kit "shylinux.com/x/toolkits"
"shylinux.com/x/toolkits/logs"
)
func _command_list(m *ice.Message, name string) {
@ -230,7 +231,7 @@ func GetFileCmd(dir string) string {
func GetCmdFile(m *ice.Message, cmds string) (file string) {
m.Search(cmds, func(key string, cmd *ice.Command) {
if cmd.RawHand == nil {
file = kit.Split(kit.FileLine(cmd.Hand, 100), ":")[0]
file = kit.Split(logs.FileLines(cmd.Hand), ":")[0]
} else {
for k, v := range ice.Info.File {
if v == cmds {

View File

@ -6,7 +6,7 @@ import (
ice "shylinux.com/x/icebergs"
"shylinux.com/x/icebergs/base/mdb"
kit "shylinux.com/x/toolkits"
"shylinux.com/x/toolkits/logs"
)
const MESSAGE = "message"
@ -18,7 +18,7 @@ func init() {
t := reflect.TypeOf(m)
for i := 0; i < t.NumMethod(); i++ {
method := t.Method(i)
p := kit.FileLine(method.Func.Interface(), 4)
p := logs.FileLine(method.Func.Interface())
m.Push(mdb.NAME, method.Name)
m.Push(mdb.TEXT, strings.Split(p, ice.ICEBERGS+"/")[1])
}

View File

@ -15,7 +15,7 @@ func init() {
mdb.CREATE: {Name: "create name", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
m.Go(func() {
cb := m.OptionCB("")
h := mdb.HashCreate(m, m.OptionSimple(mdb.NAME), mdb.STATUS, START, ice.CMD, logs.FileLine(cb, 100))
h := mdb.HashCreate(m, m.OptionSimple(mdb.NAME), mdb.STATUS, START, ice.CMD, logs.FileLines(cb))
defer func() {
if e := recover(); e == nil {
mdb.HashModify(m, mdb.HASH, h, mdb.STATUS, STOP)

View File

@ -214,7 +214,7 @@ func ZoneModify(m *ice.Message, arg ...Any) {
func ZoneSelect(m *ice.Message, arg ...string) *ice.Message {
arg = kit.Slice(arg, 0, 2)
m.Fields(len(arg), kit.Fields(TIME, m.Config(SHORT), COUNT), m.Config(FIELD))
if m.Cmdy(SELECT, m.PrefixKey(), "", ZONE, arg, logs.FileLineMeta(logs.FileLine(-1, 3))); len(arg) == 0 {
if m.Cmdy(SELECT, m.PrefixKey(), "", ZONE, arg, logs.FileLineMeta(logs.FileLine(-1))); len(arg) == 0 {
if m.Config(SHORT) != "" {
m.Sort(m.Config(SHORT))
}

View File

@ -140,7 +140,7 @@ func _serve_main(m *ice.Message, w http.ResponseWriter, r *http.Request) bool {
// 模块回调
for _, h := range rewriteList {
if m.Config(LOGHEADERS) == ice.TRUE {
m.Info("%s: %v", r.URL.Path, kit.FileLine(h, 3), meta)
m.Info("%s: %v", r.URL.Path, logs.FileLine(h), meta)
}
switch h := h.(type) {
case func(w http.ResponseWriter, r *http.Request) func():

View File

@ -201,7 +201,7 @@ func init() {
}
func IsNotValidShare(m *ice.Message, value ice.Maps) bool {
_source := logs.FileLineMeta(logs.FileLine(2, 3))
_source := logs.FileLineMeta(logs.FileLine(2))
if m.Warn(value[mdb.TIME] < m.Time(), ice.ErrNotValid, m.Option(SHARE), value[mdb.TIME], m.Time(), _source) {
return true
}

View File

@ -85,7 +85,7 @@ func (frame *Frame) Start(m *ice.Message, arg ...string) bool {
return
}
msg.Log(ROUTE, "%s <- %s", s.Name, k, meta)
ice.Info.Route[path.Join(list[s], k)] = ctx.FileCmd(kit.FileLine(x.Hand, 300))
ice.Info.Route[path.Join(list[s], k)] = ctx.FileCmd(logs.FileLines(x.Hand))
frame.HandleFunc(k, func(frame http.ResponseWriter, r *http.Request) {
m.TryCatch(msg.Spawn(), true, func(msg *ice.Message) {
_serve_handle(k, x, msg, frame, r)

View File

@ -19,10 +19,7 @@ func (m *Message) Prefix(arg ...string) string {
return m.Target().PrefixKey(arg...)
}
func (m *Message) Config(key string, arg ...Any) string {
if len(arg) > 0 {
m.Conf(m.PrefixKey(), kit.Keym(key), arg[0])
}
return m.Conf(m.PrefixKey(), kit.Keym(key))
return kit.Format(m.Configv(key, arg...))
}
func (m *Message) Configv(key string, arg ...Any) Any {
if len(arg) > 0 {
@ -30,9 +27,9 @@ func (m *Message) Configv(key string, arg ...Any) Any {
}
return m.Confv(m.PrefixKey(), kit.Keym(key))
}
func (m *Message) ConfigSimple(key ...string) (list []string) {
func (m *Message) ConfigSimple(key ...string) (res []string) {
for _, k := range kit.Split(kit.Join(key)) {
list = append(list, k, m.Config(k))
res = append(res, k, m.Config(k))
}
return
}

26
exec.go
View File

@ -11,24 +11,24 @@ import (
"shylinux.com/x/toolkits/task"
)
func (m *Message) TryCatch(msg *Message, silent bool, hand ...func(msg *Message)) *Message {
func (m *Message) TryCatch(msg *Message, catch bool, cb ...func(msg *Message)) *Message {
defer func() {
switch e := recover(); e {
case nil, io.EOF:
default:
fileline := m.FormatStack(2, 100)
fileline := m.FormatStack(2, 1)
m.Log(LOG_WARN, "catch: %s %s", e, fileline).Log("chain", msg.FormatChain())
m.Log(LOG_WARN, "catch: %s %s", e, fileline).Log("stack", msg.FormatStack(2, 100))
m.Log(LOG_WARN, "catch: %s %s", e, fileline).Result(ErrWarn, e, SP, fileline)
if len(hand) > 1 {
m.TryCatch(msg, silent, hand[1:]...)
} else if !silent {
m.Log(LOG_WARN, "catch: %s %s", e, fileline).Log("stack", m.FormatStack(2, 100))
m.Log(LOG_WARN, "catch: %s %s", e, fileline).Result(ErrWarn, e, SP, m.FormatStack(2, 5))
if len(cb) > 1 {
m.TryCatch(msg, catch, cb[1:]...)
} else if !catch {
m.Assert(e)
}
}
}()
if len(hand) > 0 {
hand[0](msg)
if len(cb) > 0 {
cb[0](msg)
}
return m
}
@ -42,9 +42,9 @@ func (m *Message) Assert(expr Any) bool {
}
case error:
default:
expr = errors.New(kit.Format("error: %v %s", e, logs.FileLine(2, 3)))
expr = errors.New(kit.Format("error: %v", e))
}
m.Result(ErrWarn, expr)
m.Result(ErrWarn, expr, logs.FileLine(2))
panic(expr)
}
func (m *Message) Sleep(d Any, arg ...Any) *Message {
@ -61,7 +61,7 @@ func (m *Message) TableGo(cb Any) *Message {
defer wg.Wait()
m.Tables(func(value Maps) {
wg.Add(1)
task.Put(kit.FileLine(cb, 3), func(*task.Task) error {
task.Put(logs.FileLine(cb), func(*task.Task) error {
defer wg.Done()
switch cb := cb.(type) {
case func(Maps, *task.Lock):
@ -77,7 +77,7 @@ func (m *Message) TableGo(cb Any) *Message {
return m
}
func (m *Message) Go(cb Any) *Message {
task.Put(kit.FileLine(cb, 3), func(task *task.Task) error {
task.Put(logs.FileLine(cb), func(task *task.Task) error {
m.TryCatch(m, true, func(m *Message) {
switch cb := cb.(type) {
case func(*Message):

34
init.go
View File

@ -27,11 +27,11 @@ func (s *Frame) Start(m *Message, arg ...string) bool {
m.Cap(CTX_STREAM, strings.Split(m.Time(), SP)[1])
m.Cmd(kit.Keys(MDB, CTX_INIT))
m.Cmd(kit.Keys(CLI, CTX_INIT))
m.Cmdy(INIT, arg)
m.Cmd(INIT, arg)
for _, k := range kit.Split(kit.Select("ctx,log,gdb,ssh", os.Getenv(CTX_DAEMON))) {
m.Start(k)
}
m.Cmdy(arg)
m.Cmd(arg)
return true
}
func (s *Frame) Close(m *Message, arg ...string) bool {
@ -43,7 +43,10 @@ func (s *Frame) Close(m *Message, arg ...string) bool {
}
})
conf.Close()
go func() { m.Sleep3s(); os.Exit(kit.Int(Pulse.Option(EXIT))) }()
go func() {
m.Sleep3s()
os.Exit(kit.Int(Pulse.Option(EXIT)))
}()
return true
}
func (s *Frame) Spawn(m *Message, c *Context, arg ...string) Server { return &Frame{} }
@ -57,14 +60,10 @@ const (
var Index = &Context{Name: ICE, Help: "冰山模块", Configs: Configs{HELP: {Value: kit.Data(INDEX, Info.Help)}}, Commands: Commands{
CTX_INIT: {Hand: func(m *Message, arg ...string) {
m.root.Travel(func(p *Context, c *Context) {
if cmd, ok := c.Commands[CTX_INIT]; ok && p != nil {
c._command(m.Spawn(c), cmd, CTX_INIT, arg...)
}
})
m.Travel(func(p *Context, c *Context) { if p != nil { c._command(m.Spawn(c), c.Commands[CTX_INIT], CTX_INIT, arg...) } })
}},
INIT: {Hand: func(m *Message, arg ...string) {
m.root.Cmd(CTX_INIT)
m.Cmd(CTX_INIT)
m.Cmd(SOURCE, ETC_INIT_SHY)
}},
HELP: {Hand: func(m *Message, arg ...string) { m.Echo(m.Config(INDEX)) }},
@ -72,23 +71,14 @@ var Index = &Context{Name: ICE, Help: "冰山模块", Configs: Configs{HELP: {Va
EXIT: {Hand: func(m *Message, arg ...string) {
m.root.Option(EXIT, kit.Select("0", arg, 0))
m.Cmd(SOURCE, ETC_EXIT_SHY)
m.root.Cmd(CTX_EXIT)
m.Cmd(CTX_EXIT)
}},
CTX_EXIT: {Hand: func(m *Message, arg ...string) {
defer m.Target().Close(m.root.Spawn(), arg...)
m.root.Travel(func(p *Context, c *Context) {
if cmd, ok := c.Commands[CTX_EXIT]; ok && p != nil {
m.TryCatch(m.Spawn(c), true, func(msg *Message) {
c._command(msg, cmd, CTX_EXIT, arg...)
})
}
})
defer m.Target().Close(m.Spawn(), arg...)
m.Travel(func(p *Context, c *Context) { if p != nil { c._command(m.Spawn(c), c.Commands[CTX_EXIT] , CTX_EXIT, arg...) } })
}},
}, server: &Frame{}}
var Pulse = &Message{time: time.Now(), code: 0,
meta: map[string][]string{}, data: Map{},
source: Index, target: Index, Hand: true,
}
var Pulse = &Message{time: time.Now(), code: 0, meta: map[string][]string{}, data: Map{}, source: Index, target: Index, Hand: true}
func init() { Index.root, Pulse.root = Index, Pulse }

30
logs.go
View File

@ -37,7 +37,7 @@ func (m *Message) join(arg ...Any) (string, []Any) {
return kit.Join(list, SP), meta
}
func (m *Message) log(level string, str string, arg ...Any) *Message {
_source := logs.FileLineMeta(logs.FileLine(3, 3))
_source := logs.FileLineMeta(logs.FileLine(3))
if Info.Log != nil {
Info.Log(m, m.FormatPrefix(), level, logs.Format(str, append(arg, _source)...))
}
@ -103,9 +103,8 @@ func (m *Message) Warn(err Any, arg ...Any) bool {
}
str, meta := m.join(arg...)
m.log(LOG_WARN, str, meta...)
if !m.IsErr() {
if m.error(arg...); len(arg) > 0 {
switch kit.Format(arg[0]) {
if !m.IsErr() && len(arg) > 0 {
switch m.error(arg...); kit.Format(arg[0]) {
case ErrNotLogin:
m.RenderStatusUnauthorized(str)
case ErrNotRight:
@ -116,38 +115,35 @@ func (m *Message) Warn(err Any, arg ...Any) bool {
m.RenderStatusBadRequest(str)
}
}
}
return true
}
func (m *Message) ErrorNotImplement(arg ...Any) {
m.Error(true, append(kit.List(ErrNotImplement), arg...)...)
}
func (m *Message) Error(err bool, arg ...Any) bool {
if err {
str, meta := m.join(arg...)
m.log(LOG_ERROR, m.FormatChain())
m.log(LOG_ERROR, str, meta)
m.log(LOG_ERROR, m.FormatStack(1, 100))
m.log(LOG_ERROR, m.FormatStack(2, 100))
m.error(arg...)
return true
}
return false
}
func (m *Message) ErrorNotImplement(arg ...Any) {
m.Error(true, append(kit.List(ErrNotImplement), arg...)...)
}
func (m *Message) error(arg ...Any) {
if len(arg) == 0 {
arg = append(arg, "", "")
} else if len(arg) == 1 {
arg = append(arg, "")
}
if len(arg) > 2 {
str, meta := m.join(arg[2:]...)
m.Resultv(ErrWarn, arg[0], arg[1], str, meta)
arg = append(arg[0:2], str, meta)
}
func (m *Message) IsErrNotFound() bool {
return m.IsErr(ErrNotFound)
m.Resultv(ErrWarn, kit.Simple(arg))
}
func (m *Message) IsErr(arg ...string) bool {
return len(arg) == 0 && m.Result(0) == ErrWarn || len(arg) > 0 && m.Result(1) == arg[0]
}
func (m *Message) IsErrNotFound() bool {
return m.IsErr(ErrNotFound)
}
func (m *Message) Debug(str string, arg ...Any) {
if str == "" {
str = m.FormatMeta()

81
meta.go
View File

@ -63,22 +63,21 @@ func (m *Message) Set(key string, arg ...string) *Message {
return m.Add(key, arg...)
}
func (m *Message) Add(key string, arg ...string) *Message {
if len(arg) == 0 {
return m
}
switch key {
case MSG_DETAIL, MSG_RESULT:
m.meta[key] = append(m.meta[key], arg...)
case MSG_OPTION, MSG_APPEND:
if len(arg) == 0 {
break
}
if index := 0; key == MSG_APPEND {
if m.meta[MSG_OPTION], index = kit.SliceRemove(m.meta[MSG_OPTION], arg[0]); index > -1 {
delete(m.meta, arg[0])
}
}
if kit.IndexOf(m.meta[key], arg[0]) == -1 {
if m.meta[arg[0]] = append(m.meta[arg[0]], arg[1:]...); kit.IndexOf(m.meta[key], arg[0]) == -1 {
m.meta[key] = append(m.meta[key], arg[0])
}
m.meta[arg[0]] = append(m.meta[arg[0]], arg[1:]...)
}
return m
}
@ -112,6 +111,7 @@ func (m *Message) Push(key string, value Any, arg ...Any) *Message {
for _, k := range head {
var v Any
switch k {
case "_target":
case KEY, HASH:
if key != "" && key != FIELDS_DETAIL {
v = key
@ -140,10 +140,6 @@ func (m *Message) Push(key string, value Any, arg ...Any) *Message {
}
switch v := kit.Format(v); key {
case FIELDS_DETAIL:
switch k {
case "_target":
continue
}
m.Add(MSG_APPEND, KEY, strings.TrimPrefix(k, EXTRA+PT))
m.Add(MSG_APPEND, VALUE, v)
default:
@ -247,13 +243,40 @@ func (m *Message) Table(cbs ...func(index int, value Maps, head []string)) *Mess
return m
}
const (
TABLE_SPACE = "table.space"
TABLE_ROW_SEP = "table.row_sep"
TABLE_COL_SEP = "table.col_sep"
TABLE_COMPACT = "table.compact"
TABLE_SPACE = "table.space"
TABLE_ALIGN = "table.align"
)
rows := kit.Select(NL, m.Option(TABLE_ROW_SEP))
cols := kit.Select(SP, m.Option(TABLE_COL_SEP))
show := func(value []string) {
for i, v := range value {
if m.Echo(v); i < len(value)-1 {
m.Echo(cols)
}
}
m.Echo(rows)
}
compact := m.Option(TABLE_COMPACT) == TRUE
space := kit.Select(SP, m.Option(TABLE_SPACE))
align := kit.Select("left", m.Option(TABLE_ALIGN))
_align := func(value string, width int) string {
if compact {
return value + space
}
n := width - kit.Width(value, len(space))
switch align {
case "left":
return value + strings.Repeat(space, n)
case "right":
return strings.Repeat(space, n) + value
case "center":
return strings.Repeat(space, n/2) + value + strings.Repeat(space, n-n/2)
}
return value + space
}
length, width := 0, map[string]int{}
for _, k := range m.meta[MSG_APPEND] {
if len(m.meta[k]) > length {
@ -266,36 +289,9 @@ func (m *Message) Table(cbs ...func(index int, value Maps, head []string)) *Mess
}
}
}
rows := kit.Select(NL, m.Option(TABLE_ROW_SEP))
cols := kit.Select(SP, m.Option(TABLE_COL_SEP))
show := func(value []string) {
for i, v := range value {
if m.Echo(v); i < len(value)-1 {
m.Echo(cols)
}
}
m.Echo(rows)
}
compact := m.Option(TABLE_COMPACT) == TRUE
_align := kit.Select("left", m.Option(TABLE_ALIGN))
align := func(value string, width int) string {
if compact {
return value + space
}
n := width - kit.Width(value, len(space))
switch _align {
case "left":
return value + strings.Repeat(space, n)
case "right":
return strings.Repeat(space, n) + value
case "center":
return strings.Repeat(space, n/2) + value + strings.Repeat(space, n-n/2)
}
return value + space
}
show(kit.Simple(m.meta[MSG_APPEND], func(k string) string { return align(k, width[k]) }))
show(kit.Simple(m.meta[MSG_APPEND], func(k string) string { return _align(k, width[k]) }))
for i := 0; i < length; i++ {
show(kit.Simple(m.meta[MSG_APPEND], func(k string) string { return align(kit.Select("", m.meta[k], i), width[k]) }))
show(kit.Simple(m.meta[MSG_APPEND], func(k string) string { return _align(kit.Select("", m.meta[k], i), width[k]) }))
}
return m
}
@ -311,9 +307,6 @@ const (
)
func (m *Message) Sort(key string, arg ...string) *Message {
if m.FieldsIsDetail() {
return m
}
keys, cmps := kit.Split(key), kit.Simple()
for i, k := range keys {
cmp := kit.Select("", arg, i)
@ -368,8 +361,8 @@ func (m *Message) Sort(key string, arg ...string) *Message {
min = j
}
}
if min != i {
list[i], list[min] = list[min], list[i]
for j := min; j > i; j-- {
list[j], list[j-1] = list[j-1], list[j]
}
}
for _, k := range m.meta[MSG_APPEND] {

View File

@ -168,7 +168,7 @@ func (m *Message) CmdHand(cmd *Command, key string, arg ...string) *Message {
if m._key, m._cmd = key, cmd; cmd == nil {
return m
}
if m._target = kit.FileLine(cmd.Hand, 3); cmd.RawHand != nil {
if m._target = logs.FileLine(cmd.Hand); cmd.RawHand != nil {
m._target = kit.Format(cmd.RawHand)
}
if fileline := kit.Select(m._target, m._source, m.target.Name == MDB); key == SELECT {
@ -184,7 +184,7 @@ func (m *Message) CmdHand(cmd *Command, key string, arg ...string) *Message {
return m
}
func (m *Message) _command(arg ...Any) *Message {
args, opts, cbs, _source := []Any{}, Map{}, kit.Value(nil), logs.FileLine(3, 3)
args, opts, cbs, _source := []Any{}, Map{}, kit.Value(nil), logs.FileLine(3)
for _, v := range arg {
switch val := v.(type) {
case string:
@ -293,7 +293,7 @@ func (c *Context) _action(m *Message, cmd *Command, key string, sub string, h *A
}
}
}
if m._target = kit.FileLine(h.Hand, 3); cmd.RawHand != nil {
if m._target = logs.FileLine(h.Hand); cmd.RawHand != nil {
m._target = kit.Format(cmd.RawHand)
}
m.Log(LOG_CMDS, "%s.%s %s %d %v", c.Name, key, sub, len(arg), arg,

View File

@ -6,6 +6,7 @@ import (
"time"
kit "shylinux.com/x/toolkits"
"shylinux.com/x/toolkits/logs"
)
type Option struct {
@ -169,9 +170,9 @@ func DisplayBase(file string, arg ...string) Maps {
return Maps{DISPLAY: file, STYLE: kit.Join(arg, SP)}
}
func FileRequire(n int) string {
p := kit.Split(kit.FileLine(n, 100), DF)[0]
p := kit.Split(logs.FileLines(n), DF)[0]
if strings.Contains(p, "go/pkg/mod") {
return path.Join("/require", strings.Split(p, "go/pkg/mod")[1])
}
return path.Join("/require/"+kit.ModPath(n), path.Base(p))
return path.Join("/require", kit.ModPath(n), path.Base(p))
}

11
type.go
View File

@ -10,6 +10,7 @@ import (
"time"
kit "shylinux.com/x/toolkits"
"shylinux.com/x/toolkits/logs"
)
type Any = interface{}
@ -95,10 +96,10 @@ func (c *Command) GetFileLine() string {
case string:
return h
default:
return kit.FileLine(c.RawHand, 100)
return logs.FileLines(c.RawHand)
}
} else if c.Hand != nil {
return kit.FileLine(c.Hand, 100)
return logs.FileLines(c.Hand)
} else {
return ""
}
@ -216,12 +217,6 @@ func (c *Context) Merge(s *Context) *Context {
for k, v := range s.Configs {
c.Configs[k] = v
}
if c.Caches == nil {
c.Caches = Caches{}
}
for k, v := range s.Caches {
c.Caches[k] = v
}
return c
}
func (c *Context) Begin(m *Message, arg ...string) *Context {