Skip to content

Commit 5120a1f

Browse files
committed
refactor: refactor the help string-vars handle logic
- rename helper.HelpVars to gcli.HelpReplacer
1 parent dcbe38d commit 5120a1f

12 files changed

+160
-172
lines changed

app.go

+4-7
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,12 @@ func NewApp(fns ...func(app *App)) *App {
105105
Logf(VerbCrazy, "create a new cli application, and create base ")
106106

107107
// init base
108+
app.Ctx = gCtx
108109
app.base = newBase()
109110
app.opts = newGlobalOpts()
110111

111112
// set a default version
112113
app.Version = "1.0.0"
113-
app.Context = gCtx
114114

115115
for _, fn := range fns {
116116
fn(app)
@@ -151,7 +151,7 @@ func (app *App) initialize() {
151151
Logf(VerbCrazy, "initialize the cli application")
152152

153153
// init some info
154-
app.initHelpVars()
154+
app.initHelpReplacer()
155155
app.bindAppOpts()
156156

157157
// add default error handler.
@@ -209,7 +209,7 @@ func (app *App) AddCommand(c *Command) {
209209
// init command
210210
c.app = app
211211
// inherit some from application
212-
c.Context = app.Context
212+
c.Ctx = app.Ctx
213213

214214
// do add command
215215
app.addCommand(app.Name, c)
@@ -472,7 +472,7 @@ func (app *App) Run(args []string) (code int) {
472472
return app.exitOnEnd(code)
473473
}
474474

475-
Logf(VerbCrazy, "begin run console application, PID: %d", app.PID())
475+
Logf(VerbCrazy, "begin run console application, PID: %d", app.Ctx.PID())
476476

477477
var name string
478478
code, name = app.prepareRun()
@@ -528,9 +528,6 @@ func (app *App) doRunCmd(name string, args []string) (code int) {
528528
}
529529

530530
func (app *App) doRunFunc(args []string) (code int) {
531-
// app bind args TODO
532-
// app.ParseArgs(args)
533-
534531
// do execute command
535532
if err := app.Func(app, args); err != nil {
536533
code = ERR

app_test.go

+8-8
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ var (
2222
Desc: "an simple command",
2323
Func: func(c *gcli.Command, args []string) error {
2424
dump.Println(c.Path(), args)
25-
c.Set("simple", "simple command")
25+
c.Ctx.Set("simple", "simple command")
2626
return nil
2727
},
2828
}
@@ -45,7 +45,7 @@ var (
4545
Name: "sub1",
4646
Desc: "desc for top1.sub1",
4747
Func: func(c *gcli.Command, args []string) error {
48-
c.Set("msg", c.App().Get("top1:sub1"))
48+
c.Ctx.Set("msg", c.App().Ctx.Get("top1:sub1"))
4949
return nil
5050
},
5151
},
@@ -291,36 +291,36 @@ func TestApp_Run_subcommand(t *testing.T) {
291291
is := assert.New(t)
292292
id := "top1:sub1"
293293

294-
appWithMl.Set(id, "TestApp_Run_subcommand")
294+
appWithMl.Ctx.Set(id, "TestApp_Run_subcommand")
295295
appWithMl.Run([]string{"top1", "sub1"})
296296

297297
c := appWithMl.FindCommand(id)
298298
is.NotEmpty(c)
299-
is.Eq("TestApp_Run_subcommand", c.Get("msg"))
299+
is.Eq("TestApp_Run_subcommand", c.Ctx.Get("msg"))
300300
}
301301

302302
func TestApp_Run_by_cmd_ID(t *testing.T) {
303303
is := assert.New(t)
304304

305-
appWithMl.SetValue("top1:sub1", "TestApp_Run_by_cmd_ID")
305+
appWithMl.Ctx.Set("top1:sub1", "TestApp_Run_by_cmd_ID")
306306
appWithMl.Run([]string{"top1:sub1"})
307307

308308
c := appWithMl.FindCommand("top1:sub1")
309309
is.NotEmpty(c)
310-
is.Eq("TestApp_Run_by_cmd_ID", c.GetVal("msg"))
310+
is.Eq("TestApp_Run_by_cmd_ID", c.Ctx.Get("msg"))
311311
}
312312

313313
func TestApp_AddAliases_and_run(t *testing.T) {
314314
is := assert.New(t)
315315
id := "top1:sub1"
316316

317317
appWithMl.AddAliases(id, "ts1")
318-
appWithMl.SetValue(id, "TestApp_AddAliases_and_run")
318+
appWithMl.Ctx.Set(id, "TestApp_AddAliases_and_run")
319319
appWithMl.Run([]string{"ts1"})
320320

321321
c := appWithMl.FindCommand(id)
322322
is.NotEmpty(c)
323-
is.Eq("TestApp_AddAliases_and_run", c.GetVal("msg"))
323+
is.Eq("TestApp_AddAliases_and_run", c.Ctx.Get("msg"))
324324
}
325325

326326
func TestApp_showCommandHelp(t *testing.T) {

base.go

+20-30
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010
"strings"
1111

1212
"github.com/gookit/color"
13-
"github.com/gookit/gcli/v3/helper"
1413
"github.com/gookit/goutil/maputil"
1514
"github.com/gookit/goutil/structs"
1615
)
@@ -125,36 +124,27 @@ func (ctx *Context) hasHelpKeywords() bool {
125124
return strings.HasSuffix(ctx.argLine, " -h") || strings.HasSuffix(ctx.argLine, " --help")
126125
}
127126

128-
// SetValue to ctx
129-
func (ctx *Context) SetValue(key string, val any) {
130-
ctx.Set(key, val)
131-
}
132-
133-
// GetVal from ctx
134-
func (ctx *Context) GetVal(key string) interface{} {
135-
return ctx.Get(key)
136-
}
137-
138127
// ResetData from ctx
139128
func (ctx *Context) ResetData() {
140129
ctx.Data = make(maputil.Data)
141130
}
142131

143132
/*************************************************************
144-
* command Base
133+
* command base
145134
*************************************************************/
146135

147136
// will inject to every Command
148137
type base struct {
138+
color.SimplePrinter
149139
// Hooks manage. allowed hooks: "init", "before", "after", "error"
150140
*Hooks
151-
*Context
152-
color.SimplePrinter
153-
// HelpVars help message replace vars.
154-
helper.HelpVars
155-
// TODO tplVars for render help template text.
156-
tplVars map[string]any
141+
// HelpReplacer help message replace pairs.
142+
HelpReplacer
143+
// helpVars custom add vars for render help template.
144+
helpVars map[string]any
157145

146+
// Ctx for command
147+
Ctx *Context
158148
// Logo ASCII logo setting
159149
Logo *Logo
160150
// Version app version. like "1.0.1"
@@ -200,25 +190,25 @@ func newBase() base {
200190
// cmdAliases: make(maputil.Aliases),
201191
cmdAliases: structs.NewAliases(aliasNameCheck),
202192
// ExitOnEnd: false,
203-
tplVars: make(map[string]any),
193+
helpVars: make(map[string]any),
204194
// Context: NewCtx(),
205195
}
206196
}
207197

208198
// init common basic help vars
209-
func (b *base) initHelpVars() {
210-
b.AddVars(map[string]string{
211-
"pid": b.PIDString(),
212-
"workDir": b.workDir,
213-
"binFile": b.binFile,
214-
"binName": b.binName,
199+
func (b *base) initHelpReplacer() {
200+
b.AddReplaces(map[string]string{
201+
"pid": b.Ctx.PIDString(),
202+
"workDir": b.Ctx.workDir,
203+
"binFile": b.Ctx.binFile,
204+
"binName": b.Ctx.binName,
215205
})
216206
}
217207

218208
// ResetData from ctx
219209
func (b *base) ResetData() {
220-
if b.Context != nil {
221-
b.Context.ResetData()
210+
if b.Ctx != nil {
211+
b.Ctx.ResetData()
222212
}
223213
}
224214

@@ -392,7 +382,7 @@ func (b *base) AliasesMapping() map[string]string {
392382
return b.cmdAliases.Mapping()
393383
}
394384

395-
// AddTplVar to instance.
396-
func (b *base) AddTplVar(key string, val any) {
397-
b.tplVars[key] = val
385+
// AddHelpVar to instance.
386+
func (b *base) AddHelpVar(key string, val any) {
387+
b.helpVars[key] = val
398388
}

base_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ func TestApp_On_CmdNotFound_redirect(t *testing.T) {
115115
buf.Reset()
116116
simpleCmd.Init()
117117
simpleCmd.ResetData()
118-
assert.Eq(t, nil, simpleCmd.GetVal("simple"))
118+
assert.Eq(t, nil, simpleCmd.Ctx.Get("simple"))
119119

120120
cli := newNotExitApp()
121121
cli.Add(simpleCmd)
@@ -128,7 +128,7 @@ func TestApp_On_CmdNotFound_redirect(t *testing.T) {
128128

129129
err := ctx.App.Exec(simpleCmd.Name, nil)
130130
assert.NoErr(t, err)
131-
buf.WriteString("value:" + simpleCmd.Data.Str("simple"))
131+
buf.WriteString("value:" + simpleCmd.Ctx.Str("simple"))
132132
return true
133133
})
134134

cmd.go

+9-9
Original file line numberDiff line numberDiff line change
@@ -178,9 +178,9 @@ func (c *Command) IsDisabled() bool {
178178
return c.disabled
179179
}
180180

181-
// Runnable reports whether the command can be run; otherwise
181+
// IsRunnable reports whether the command can be run; otherwise
182182
// it is a documentation pseudo-command such as import path.
183-
func (c *Command) Runnable() bool {
183+
func (c *Command) IsRunnable() bool {
184184
return c.Func != nil
185185
}
186186

@@ -208,7 +208,7 @@ func (c *Command) AddCommand(sub *Command) {
208208
// inherit standalone value
209209
sub.standalone = c.standalone
210210
// inherit something from parent
211-
sub.Context = c.Context
211+
sub.Ctx = c.Ctx
212212

213213
// initialize command
214214
c.initialize()
@@ -291,22 +291,22 @@ func (c *Command) initCommandBase(cName string) {
291291
c.Hooks = &Hooks{}
292292
}
293293

294-
if c.Context == nil {
294+
if c.Ctx == nil {
295295
Logf(VerbDebug, "cmd: %s - use the gCtx as command context", cName)
296-
c.Context = gCtx
296+
c.Ctx = gCtx
297297
}
298298

299-
binWithPath := c.binName + " " + c.Path()
299+
binWithPath := c.Ctx.binName + " " + c.Path()
300300

301-
c.initHelpVars()
302-
c.AddVars(map[string]string{
301+
c.initHelpReplacer()
302+
c.AddReplaces(map[string]string{
303303
"cmd": cName,
304304
// binName with command name
305305
"binWithCmd": binWithPath,
306306
// binName with command path
307307
"binWithPath": binWithPath,
308308
// binFile with command
309-
"fullCmd": c.binFile + " " + cName,
309+
"fullCmd": c.Ctx.binFile + " " + cName,
310310
})
311311

312312
c.base.cmdNames = make(map[string]int)

cmd_test.go

+6-6
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ func TestNewCommand(t *testing.T) {
2121
})
2222

2323
is.NotEmpty(c)
24-
is.False(c.Runnable())
24+
is.False(c.IsRunnable())
2525
is.Nil(c.App())
2626

2727
err := c.Run([]string{})
@@ -55,7 +55,7 @@ func TestCommand_NewErrf(t *testing.T) {
5555
})
5656

5757
is.NotEmpty(c)
58-
is.True(c.Runnable())
58+
is.True(c.IsRunnable())
5959

6060
err := c.Run(simpleArgs)
6161
is.Err(err)
@@ -277,8 +277,8 @@ var c0 = gcli.NewCommand("test", "desc for test command", func(c *gcli.Command)
277277
c.AddArg("arg1", "arg1 desc")
278278
c.Func = func(c *gcli.Command, args []string) error {
279279
bf.WriteString("name=" + c.Name)
280-
c.Set("name", c.Name)
281-
c.Set("args", args)
280+
c.Ctx.Set("name", c.Name)
281+
c.Ctx.Set("args", args)
282282
// dump.P(c.ID(), "command Func is exec")
283283
return nil
284284
}
@@ -357,8 +357,8 @@ func TestCommand_Run_parseOptions(t *testing.T) {
357357

358358
// dump.P(gcli.GOpts(), c0.Context)
359359
is.NoErr(err)
360-
is.Eq("test", c0.Get("name"))
361-
is.Eq([]string{"txt"}, c0.Get("args"))
360+
is.Eq("test", c0.Ctx.Get("name"))
361+
is.Eq([]string{"txt"}, c0.Ctx.Get("args"))
362362

363363
is.Eq(10, int0)
364364
is.Eq("abc", str0)

hooks.go ext.go

+61
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package gcli
22

33
import (
44
"context"
5+
"fmt"
6+
"strings"
57

68
"github.com/gookit/gcli/v3/events"
79
"github.com/gookit/goutil/maputil"
@@ -168,3 +170,62 @@ func (hc *HookCtx) WithApp(a *App) *HookCtx {
168170
hc.App = a
169171
return hc
170172
}
173+
174+
/*************************************************************
175+
* app/cmd help string-var replacer
176+
*************************************************************/
177+
178+
// HelpVarFormat allow string replace on render help info.
179+
//
180+
// Default support:
181+
//
182+
// "{$binName}" "{$cmd}" "{$fullCmd}" "{$workDir}"
183+
const HelpVarFormat = "{$%s}"
184+
185+
// HelpReplacer provide string var replace for render help template.
186+
type HelpReplacer struct {
187+
VarOpen, VarClose string
188+
189+
// replaces you can add string-var map for render help info.
190+
replaces map[string]string
191+
}
192+
193+
// AddReplace get command name. AddReplace
194+
func (hv *HelpReplacer) AddReplace(name, value string) {
195+
if hv.replaces == nil {
196+
hv.replaces = make(map[string]string)
197+
}
198+
hv.replaces[name] = value
199+
}
200+
201+
// AddReplaces add multi tpl vars.
202+
func (hv *HelpReplacer) AddReplaces(vars map[string]string) {
203+
for n, v := range vars {
204+
hv.AddReplace(n, v)
205+
}
206+
}
207+
208+
// GetReplace get a help var by name
209+
func (hv *HelpReplacer) GetReplace(name string) string {
210+
return hv.replaces[name]
211+
}
212+
213+
// Replaces get all tpl vars.
214+
func (hv *HelpReplacer) Replaces() map[string]string {
215+
return hv.replaces
216+
}
217+
218+
// ReplacePairs replace string vars in the input text.
219+
func (hv *HelpReplacer) ReplacePairs(input string) string {
220+
// if not use var
221+
if !strings.Contains(input, "{$") {
222+
return input
223+
}
224+
225+
var ss []string
226+
for n, v := range hv.replaces {
227+
ss = append(ss, fmt.Sprintf(HelpVarFormat, n), v)
228+
}
229+
230+
return strings.NewReplacer(ss...).Replace(input)
231+
}

0 commit comments

Comments
 (0)