Skip to content

Commit bcf85d7

Browse files
committed
update README.md
1 parent a79d6e9 commit bcf85d7

File tree

1 file changed

+149
-11
lines changed

1 file changed

+149
-11
lines changed

README.md

Lines changed: 149 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,14 @@ v2 is in earlier state but the baseline is stable:
9696
- extensible codecs and providers for loading from data sources
9797

9898
- Three kinds of config files are searched and loaded via `loaders.NewConfigFileLoader()`:
99-
- Primary: main config, shipped with installable package.
100-
- Secondary: 2ndry config. Wrapped by reseller(s).
101-
- Alternative: user's local config, writeable. The runtime changeset will be written back to this file while app stopping.
99+
1. __Primary__: main config, shipped with installable package.
100+
2. __Secondary__: 2ndry config. Wrapped by reseller(s).
101+
3. __Alternative__: user's local config, writeable. The runtime changeset will be written back to this file while app stopping.
102+
103+
- Variety of approaches for building command system with attached flags
104+
1. traditional stream calls (`app.Cmd("verbose", "v").Action(onVerbose)`)
105+
2. concise modes by [`Create`](https://pkg.go.dev/github.com/hedzr/cmdr/v2#Create) and cmd/xxcmd.go
106+
3. use [`Create.BuildFrom`](https://pkg.go.dev/github.com/hedzr/cmdr/v2#Create) to build cmdsys from a struct value via `[App.FromStruct]`, see example [#example_Create_buildFromStructValue](https://pkg.go.dev/github.com/hedzr/cmdr/v2/#example_Create_buildFromStructValue); or, attaching subcmds and flags to a subcmd by `app.Cmd().FromStruct(&root{})` following any traditional calls.
102107

103108
- Generating shell autocompletion scripts
104109
- supported shells are: zsh, bash, fish, powershell, ...
@@ -114,38 +119,56 @@ v2 is in earlier state but the baseline is stable:
114119
[^3]: `hedzr/logg` provides a slog like and colorful logging library
115120
[^4]: `hedzr/is` is a basic environ detectors library
116121

117-
Getting started from [New](https://pkg.go.dev/github.com/hedzr/cmdr/v2#New) or [Create](https://pkg.go.dev/github.com/hedzr/cmdr/v2#Create) function.
118-
119122
More minor details need to be evaluated and reimplemented if it's still meaningful in v2.
120123

121-
### cmdr-loaders
124+
### News
125+
126+
Getting started from [New](https://pkg.go.dev/github.com/hedzr/cmdr/v2#New) or [Create](https://pkg.go.dev/github.com/hedzr/cmdr/v2#Create) function, and see the quickstart docs at [Concise Version - hzDocs](https://docs.hedzr.com/en/docs/cmdr.v2/guide/g02-concise-version/) and [Step by step - hzDocs](https://docs.hedzr.com/en/docs/cmdr.v2/guide/steps/).
122127

123128
Since v2.0.3, loaders had been splitted as a standalone repo so that we can keep cmdr v2 smaller and independer. See the relevant subproject [cmdr-loaders](https://github.com/hedzr/cmdr-loaders)[^5].
124129

125130
Since v2.1.12, we did main alternative features like autocompletion generating, manpage reading and generating, and made quite a lot of fixes and improvments. Now the main APIs come to stable.
126131

127-
Since v2.1.26, we added `App.FromStruct(structValue, opts...)` to build the command system from a struct-value, which deconstructs the given struct's definitions and constrcts the cmd-sys. For more detail, see also []
132+
Since v2.1.26, we added `App.FromStruct(structValue, opts...)` to build the command system from a struct-value, which deconstructs the given struct's definitions and constrcts the cmd-sys. And we also added `App.Cmd().FromStruct(&root{})` to build for a subcmd in a later release. Now the parsed cmdline args will be written into your struct value. For more detail, see also [From struct-value and Tag - hzDocs](https://docs.hedzr.com/en/docs/cmdr.v2/guide/steps/g13-build-from-struct/)
128133

129134
The full-functional tests and examples are moved into [cmdr-tests](https://github.com/hedzr/cmdr-tests).
130135

131136
[^5]: `hedzr/cmdr-loaders` provides an external config file loaders with GNU File Standard supports.
132137

133138
## History
134139

135-
v2.1 is a stable version:
140+
v2.2 would be a stable version:
136141

137142
- v2.2.0 PLANNED: the final stable version for v2.
138143
- v2.1.x: preview version for the new APIs.
139144
- Full list: [CHANGELOG](https://github.com/hedzr/cmdr/blob/master/CHANGELOG)
140145

141146
## Guide
142147

148+
Please go to our docsite for these pages:
149+
150+
- [Concise Version - hzDocs](https://docs.hedzr.com/en/docs/cmdr.v2/guide/g02-concise-version/)
151+
- [Step by step - hzDocs](https://docs.hedzr.com/en/docs/cmdr.v2/guide/steps/)
152+
- ...
153+
143154
You can build command system by kinds of forms:
144155

145-
- traditional stream calls from `[New()](https://pkg.go.dev/github.com/hedzr/cmdr/v2#New)` (`cmdr.New().Cmd("verbose", "v").Action(onVerbose)`)
146-
- concise modes by `[Create()](https://pkg.go.dev/github.com/hedzr/cmdr/v2#Create)` and cmd/xxcmd.go
147-
- use `[Create().BuildFrom()](https://pkg.go.dev/github.com/hedzr/cmdr/v2#Create)` to build cmdsys from a struct value via `[App.FromStruct()](https://pkg.go.dev/github.com/hedzr/cmdr/v2/cli#App)`, see example [#example_Create_buildFromStructValue](https://pkg.go.dev/github.com/hedzr/cmdr/v2/#example_Create_buildFromStructValue)
156+
1. traditional stream calls (`app.Cmd("verbose", "v").Action(onVerbose)`)
157+
2. concise modes by [`Create`](https://pkg.go.dev/github.com/hedzr/cmdr/v2#Create) and cmd/xxcmd.go
158+
3. use [`Create.BuildFrom`](https://pkg.go.dev/github.com/hedzr/cmdr/v2#Create) to build cmdsys from a struct value via `[App.FromStruct]`, see example [#example_Create_buildFromStructValue](https://pkg.go.dev/github.com/hedzr/cmdr/v2/#example_Create_buildFromStructValue); or, attaching subcmds and flags to a subcmd by `app.Cmd().FromStruct(&root{})` following any traditional calls.
148159

160+
### Traditional style
161+
162+
```go
163+
app.Cmd("soundex", "snd", "sndx", "sound").
164+
Description("soundex test").
165+
Group("Test").
166+
TailPlaceHolders("[text1, text2, ...]").
167+
OnAction(soundex).
168+
Build()
169+
```
170+
171+
### Concise version
149172

150173
A typical cli-app can be (its concise version at [examples/tiny/concise/main.go](https://github.com/hedzr/cmdr/blob/master/examples/tiny/concise/main.go)):
151174

@@ -292,6 +315,121 @@ func (presetCmd) Add(app cli.App) {
292315
}
293316
```
294317

318+
### From a struct value
319+
320+
Adding subcmds and flags to an existed command `multiCmd` is dead simple, this way:
321+
322+
```go
323+
package cmd
324+
325+
import (
326+
"context"
327+
"os"
328+
329+
"github.com/hedzr/cmdr/v2/cli"
330+
"github.com/hedzr/is"
331+
logz "github.com/hedzr/logg/slog"
332+
)
333+
334+
type multiCmd struct{}
335+
336+
func (multiCmd) Add(app cli.App) {
337+
if is.DebuggerAttached() {
338+
logz.SetLevel(logz.TraceLevel)
339+
app.WithOpts(cli.WithArgs(os.Args[0], "~~tree"))
340+
}
341+
app.Cmd("multi", "m", "").
342+
Description("multi-level test and imported form struct").
343+
// Group("Test").
344+
TailPlaceHolders("[text1, text2, ...]").
345+
OnAction(soundex).
346+
FromStruct(root{}).
347+
With(func(b cli.CommandBuilder) {
348+
// b.FromStruct(&root{})
349+
})
350+
}
351+
352+
type root struct {
353+
b bool // unexported values ignored
354+
Int int `cmdr:"-"` // ignored
355+
A `title:"a-cmd" shorts:"a,a1,a2" alias:"a1-cmd,a2-cmd" desc:"A command for demo" required:"true"`
356+
B
357+
C
358+
F1 int
359+
F2 string
360+
}
361+
362+
type A struct {
363+
D
364+
F1 int
365+
F2 string
366+
}
367+
type B struct {
368+
F2 int
369+
F3 string
370+
}
371+
type C struct {
372+
F3 bool
373+
F4 string
374+
}
375+
type D struct {
376+
E
377+
FromNowOn F
378+
F3 bool
379+
F4 string
380+
}
381+
type E struct {
382+
F3 bool `title:"f3" shorts:"ff" alias:"f3ff" desc:"A flag for demo" required:"true"`
383+
F4 string
384+
}
385+
type F struct {
386+
F5 uint
387+
F6 byte
388+
}
389+
390+
// a --f1 1 --f2 str
391+
// --a.f1 1 --a.f2 str
392+
393+
func (A) With(cb cli.CommandBuilder) {
394+
// customize for A command, for instance: fb.ExtraShorts("ff")
395+
logz.Info(". - A.With() invoked.", "cmdbuilder", cb)
396+
}
397+
func (A) F1With(fb cli.FlagBuilder) {
398+
// customize for A.F1 flag, for instance: fb.ExtraShorts("ff")
399+
logz.Info(". - A.F1With() invoked.", "flgbuilder", fb)
400+
}
401+
402+
// Action method will be called if end-user type subcmd for it (like `app a d e --f3`).
403+
func (E) Action(ctx context.Context, cmd cli.Cmd, args []string) (err error) {
404+
logz.Info(". - E.Action() invoked.", "cmd", cmd, "args", args)
405+
_, err = cmd.App().DoBuiltinAction(ctx, cli.ActionDefault, stringArrayToAnyArray(args)...)
406+
return
407+
}
408+
409+
// Action method will be called if end-user type subcmd for it (like `app a d f --f5=7`).
410+
func (s F) Action(ctx context.Context, cmd cli.Cmd, args []string) (err error) {
411+
(&s).Inc()
412+
logz.Info(". - F.Action() invoked.", "cmd", cmd, "args", args, "F5", s.F5)
413+
_, err = cmd.App().DoBuiltinAction(ctx, cli.ActionDefault, stringArrayToAnyArray(args)...)
414+
return
415+
}
416+
417+
func (s *F) Inc() {
418+
s.F5++
419+
}
420+
421+
func stringArrayToAnyArray(args []string) (ret []any) {
422+
for _, it := range args {
423+
ret = append(ret, it)
424+
}
425+
return
426+
}
427+
```
428+
429+
For the detail, or check out its bindable version, go to [From struct-value and Tag - hzDocs](https://docs.hedzr.com/en/docs/cmdr.v2/guide/steps/g13-build-from-struct/).
430+
431+
### Next Step
432+
295433
More examples please go to [cmdr-tests/examples](https://github.com/hedzr/cmdr-tests/tree/master/examples).
296434

297435
## License

0 commit comments

Comments
 (0)