Skip to content

Commit

Permalink
wip: refactoring the app and cmd context logic
Browse files Browse the repository at this point in the history
  • Loading branch information
inhere committed Sep 8, 2022
1 parent 54b41a7 commit f335cf8
Show file tree
Hide file tree
Showing 8 changed files with 147 additions and 181 deletions.
29 changes: 13 additions & 16 deletions app.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ type AppConfig struct {
type App struct {
// internal use
// for manage commands
commandBase
base

AppConfig

Expand Down Expand Up @@ -104,23 +104,23 @@ func NewApp(fns ...func(app *App)) *App {
app := &App{
Name: "GCliApp",
Desc: "This is my console application",
opts: newDefaultGlobalOpts(),
opts: newGlobalOpts(),
// set a default version.
// Version: "1.0.0",
// config
// ExitOnEnd: true,
// group
// moduleCommands: make(map[string]map[string]*Command),
commandBase: newCommandBase(),
base: newBase(),
}

app.fs = NewFlags("appOptions").WithConfigFn(func(opt *FlagsConfig) {
opt.WithoutType = true
opt.Alignment = AlignLeft
})

// init commandBase
Logf(VerbCrazy, "create new commandBase on init application")
// init base
Logf(VerbCrazy, "create new base on init application")
// set a default version
app.Version = "1.0.0"

Expand Down Expand Up @@ -149,15 +149,14 @@ func (app *App) Config(fn func(a *App)) {
}

// binding global options
func (app *App) bindingGlobalOpts() {
Logf(VerbDebug, "will begin binding global options")
func (app *App) bindingGOpts() {
Logf(VerbDebug, "will begin binding app global options")
// global options flag
fs := app.fs

// binding global options
app.opts.bindingFlags(fs)
// add more ...
fs.BoolOpt(&gOpts.ShowVersion, "version", "V", false, "Display app version information")
// This is a internal option
fs.BoolVar(&gOpts.inCompletion, &FlagMeta{
Name: "in-completion",
Expand All @@ -180,14 +179,12 @@ func (app *App) initialize() {

Logf(VerbCrazy, "initialize the application")

// init some vars
if app.Hooks == nil {
app.Hooks = &Hooks{}
}
// init some info
app.InitCtx()
app.initHelpVars()

// binding global options
app.bindingGlobalOpts()
app.bindingGOpts()

// add default error handler.
if !app.HasHook(events.OnAppRunError) {
Expand Down Expand Up @@ -221,11 +218,11 @@ func (app *App) AddCommand(c *Command) {

// init command
c.app = app
// inherit global flags from application
// c.core.gFlags = app.gFlags
// inherit some from application
c.Context = app.Context

// do add command
app.commandBase.addCommand(app.Name, c)
app.base.addCommand(app.Name, c)

if c.HasCommands() {
app.hasSubcommands = true
Expand Down
54 changes: 28 additions & 26 deletions base.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ func (ctx *Context) Value(key any) any {
return ctx.Data.Get(key.(string))
}

// Init some common info
func (ctx *Context) Init() {
// InitCtx some common info
func (ctx *Context) InitCtx() {
binFile := os.Args[0]
workDir, _ := os.Getwd()

Expand All @@ -70,6 +70,7 @@ func (ctx *Context) Init() {
ctx.binFile = binFile
ctx.binName = filepath.Base(binFile)
ctx.argLine = strings.Join(os.Args[1:], " ")
// return ctx
}

// PID get pid
Expand Down Expand Up @@ -129,7 +130,7 @@ func (ctx *Context) hasHelpKeywords() bool {
*************************************************************/

// will inject to every Command
type commandBase struct {
type base struct {
// Hooks manage. allowed hooks: "init", "before", "after", "error"
*Hooks
*Context
Expand Down Expand Up @@ -169,8 +170,8 @@ type commandBase struct {
errors []error
}

func newCommandBase() commandBase {
return commandBase{
func newBase() base {
return base{
Hooks: &Hooks{},
Logo: &Logo{Style: "info"},
// init mapping
Expand All @@ -183,11 +184,12 @@ func newCommandBase() commandBase {
cmdAliases: structs.NewAliases(aliasNameCheck),
// ExitOnEnd: false,
helpData: make(map[string]any),
Context: NewCtx(),
}
}

// init common basic help vars
func (b *commandBase) initHelpVars() {
func (b *base) initHelpVars() {
b.AddVars(map[string]string{
"pid": b.PIDString(),
"workDir": b.workDir,
Expand All @@ -197,45 +199,45 @@ func (b *commandBase) initHelpVars() {
}

// GetCommand get a command by name
func (b *commandBase) GetCommand(name string) *Command {
func (b *base) GetCommand(name string) *Command {
return b.commands[name]
}

// Command get a command by name
func (b *commandBase) Command(name string) (c *Command, exist bool) {
func (b *base) Command(name string) (c *Command, exist bool) {
c, exist = b.commands[name]
return
}

// IsAlias name check
func (b *commandBase) IsAlias(alias string) bool {
func (b *base) IsAlias(alias string) bool {
return b.cmdAliases.HasAlias(alias)
}

// ResolveAlias get real command name by alias
func (b *commandBase) ResolveAlias(alias string) string {
func (b *base) ResolveAlias(alias string) string {
return b.cmdAliases.ResolveAlias(alias)
}

// HasCommands on the cmd/app
func (b *commandBase) HasCommands() bool {
func (b *base) HasCommands() bool {
return len(b.cmdNames) > 0
}

// HasCommand name check
func (b *commandBase) HasCommand(name string) bool {
func (b *base) HasCommand(name string) bool {
_, has := b.cmdNames[name]
return has
}

// IsCommand name check. alias of the HasCommand()
func (b *commandBase) IsCommand(name string) bool {
func (b *base) IsCommand(name string) bool {
_, has := b.cmdNames[name]
return has
}

// add Command to the group
func (b *commandBase) addCommand(pName string, c *Command) {
func (b *base) addCommand(pName string, c *Command) {
// init command
c.initialize()

Expand Down Expand Up @@ -275,7 +277,7 @@ func (b *commandBase) addCommand(pName string, c *Command) {
}

// Match command by path names. eg. ["top", "sub"]
func (b *commandBase) Match(names []string) *Command {
func (b *base) Match(names []string) *Command {
ln := len(names)
if ln == 0 {
panic("the command names is required")
Expand All @@ -299,45 +301,45 @@ func (b *commandBase) Match(names []string) *Command {
}

// FindCommand command by path. eg. "top:sub" or "top sub"
func (b *commandBase) FindCommand(path string) *Command {
func (b *base) FindCommand(path string) *Command {
return b.Match(splitPath2names(path))
}

// FindByPath command by path. eg. "top:sub" or "top sub"
func (b *commandBase) FindByPath(path string) *Command {
func (b *base) FindByPath(path string) *Command {
return b.Match(splitPath2names(path))
}

// MatchByPath command by path. eg. "top:sub" or "top sub"
func (b *commandBase) MatchByPath(path string) *Command {
func (b *base) MatchByPath(path string) *Command {
return b.Match(splitPath2names(path))
}

// SetLogo text and color style
func (b *commandBase) SetLogo(logo string, style ...string) {
func (b *base) SetLogo(logo string, style ...string) {
b.Logo.Text = logo
if len(style) > 0 {
b.Logo.Style = style[0]
}
}

// AddError to the application
func (b *commandBase) AddError(err error) {
func (b *base) AddError(err error) {
b.errors = append(b.errors, err)
}

// Commands get all commands
func (b *commandBase) Commands() map[string]*Command {
func (b *base) Commands() map[string]*Command {
return b.commands
}

// CmdNames get all command names
func (b *commandBase) CmdNames() []string {
func (b *base) CmdNames() []string {
return b.CommandNames()
}

// CommandNames get all command names
func (b *commandBase) CommandNames() []string {
func (b *base) CommandNames() []string {
var ss []string
for n := range b.cmdNames {
ss = append(ss, n)
Expand All @@ -346,16 +348,16 @@ func (b *commandBase) CommandNames() []string {
}

// CmdNameMap get all command names
func (b *commandBase) CmdNameMap() map[string]int {
func (b *base) CmdNameMap() map[string]int {
return b.cmdNames
}

// CmdAliases get cmd aliases
func (b *commandBase) CmdAliases() *structs.Aliases {
func (b *base) CmdAliases() *structs.Aliases {
return b.cmdAliases
}

// AliasesMapping get cmd aliases mapping
func (b *commandBase) AliasesMapping() map[string]string {
func (b *base) AliasesMapping() map[string]string {
return b.cmdAliases.Mapping()
}
36 changes: 14 additions & 22 deletions cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func (c HandlersChain) Last() RunnerFunc {
// Command a CLI command structure
type Command struct {
// internal use
commandBase
base

// --- provide option and argument parse and binding.

Expand Down Expand Up @@ -210,8 +210,8 @@ func (c *Command) AddCommand(sub *Command) {
sub.parent = c
// inherit standalone value
sub.standalone = c.standalone
// inherit global flags from parent
// sub.core.gFlags = c.gFlags
// inherit something from parent
sub.Context = c.Context

// initialize command
c.initialize()
Expand All @@ -220,7 +220,7 @@ func (c *Command) AddCommand(sub *Command) {
sub.pathNames = c.pathNames[0:]

// do add
c.commandBase.addCommand(c.Name, sub)
c.base.addCommand(c.Name, sub)
}

// Match sub command by input names
Expand All @@ -231,7 +231,7 @@ func (c *Command) Match(names []string) *Command {
if len(names) == 0 { // return self.
return c
}
return c.commandBase.Match(names)
return c.base.Match(names)
}

// MatchByPath command by path. eg: "top:sub"
Expand All @@ -252,11 +252,8 @@ func (c *Command) initialize() {
c.initialized = true
c.pathNames = append(c.pathNames, cName)

// init core
c.initCore(cName)

// init commandBase
c.initCommandBase()
// init base
c.initCommandBase(cName)

// load common subs
if len(c.Subs) > 0 {
Expand Down Expand Up @@ -290,10 +287,9 @@ func (c *Command) initialize() {
}

// init core
func (c *Command) initCore(cName string) {
Logf(VerbCrazy, "init command c.core for the command: %s", cName)
func (c *Command) initCommandBase(cName string) {
Logf(VerbCrazy, "init command c.base for the command: %s", cName)

// c.cmdLine = CLI
if c.Hooks == nil {
c.Hooks = &Hooks{}
}
Expand All @@ -310,17 +306,13 @@ func (c *Command) initCore(cName string) {
// binFile with command
"fullCmd": c.binFile + " " + cName,
})
}

func (c *Command) initCommandBase() {
Logf(VerbCrazy, "init command c.commandBase for the command: %s", c.Name)

c.commandBase.cmdNames = make(map[string]int)
c.commandBase.commands = make(map[string]*Command)
c.base.cmdNames = make(map[string]int)
c.base.commands = make(map[string]*Command)
// set an default value.
c.commandBase.nameMaxWidth = 12
// c.commandBase.cmdAliases = make(maputil.Aliases)
c.commandBase.cmdAliases = structs.NewAliases(aliasNameCheck)
c.base.nameMaxWidth = 12
// c.base.cmdAliases = make(maputil.Aliases)
c.base.cmdAliases = structs.NewAliases(aliasNameCheck)
}

// Next TODO processing, run all middleware handlers
Expand Down
2 changes: 1 addition & 1 deletion cmd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ func TestCommand_Run_emptyArgs(t *testing.T) {
bf.Reset()
is := assert.New(t)

gcli.SetCrazyMode()
gcli.SetVerbose(gcli.VerbCrazy)
defer gcli.ResetVerbose()

is.Eq("test", c0.Name)
Expand Down
Loading

0 comments on commit f335cf8

Please sign in to comment.