hzDocs
hzDocs
文章 / 文档hedzr.com首页

cmdr series

介绍 cmdr

Guide

你的首个 CLI app更适合工程实践的版本
循序渐进
基本概念
命令命令:执行外部程序命令:预设参数命令:重定向命令:动态命令清单命令:在配置文件中定义别名清单命令:事件响应函数标志标志:必须项标志:可翻转组标志:枚举值标志:`Head -1` 风格标志:调用外部工具获得输入标志:自动否定标志:加号 `+` 前缀标志:事件响应函数解析结果内建命令和标志帮助子系统可共享共存的 app 实例辨析顶级函数WithOptsBackstage
如何……
Auto-close the ClosersRead config into structUsing is DetectorsUsing Store

References

What's New
Packages

Others

Examples
Blueprint
产品发布
产品发布之前
介绍 cmdr-cxx

Guide

cmdr supports

Intro

Guide

More features

References

Others

evendeep(-go)

Guide

Usagesdeepcopydeepdiffdeepequal
logg/slog(-go)

Guide

Guide

others

Components
trie-cxx

Guide

Guide

links

On Github

Read config into struct

Working with Store and struct

介绍

Manual of `hedzr/store`

Chapter: Using Store

`hedzr/store` on Github

cmdr.Set() 返回的 Store 对象包含了 app 的配置数据。层次化的配置数据可以通过 dottedPath 来访问。

// get `app.logging.file` as a string
println(cmdr.Set().MustString("logging.file"))

但有时候,将一颗子树抽出并映射到 struct 中可能是有用的。

cmdr.v2 通过 Store 对象的方法 To() / GetSectionFrom() 来实现这样的映射。其原型为:

To(path string, holder any, opts ...MOpt[T]) (err error)

同时,cmdr.To(path, holder, opts...) 是更便捷的调用。使用方法如下:

func TestTo(t *testing.T) {
	ctx := context.Background()
	app := cmdr.Create("app", "v1", `author`, `desc`,
		cli.WithArgs("test-app", "--debug"),
	).OnAction(func(ctx context.Context, cmd cli.Cmd, args []string) (err error) {
		b := cmdr.Store().MustBool("debug")
		println("debug flag: ", b)
		if !b {
			t.Fail()
		}
		println(cmdr.Set().Dump())
		type manS struct {
			Dir  string
			Type int
		}
		type genS struct {
			Manual manS
		}
		var v genS
		err = cmdr.To("cmd.generate", &v)
		if err != nil {
			t.Fail()
		}
		if v.Manual.Type != 1 {
			t.Fail()
		}
		return
	}).
		Build()
	err := app.Run(ctx)
	if err != nil {
		t.Errorf("Error: %v", err)
	}
}
func TestStore_GetSectionFrom(t *testing.T) {
	conf := newBasicStore()
	conf.Set("app.logging.words", []any{"a", 1, false})
	conf.Set("app.server.sites", -1)
	t.Logf("\nPath\n%v\n", conf.Dump())

    type loggingS struct {
    	File   uint
    	Rotate uint64
    	Words  []any
    }

    type serverS struct {
    	Start int
    	Sites int
    }

    type appS struct {
    	Debug   bool
    	Dump    int
    	Verbose bool
    	Logging loggingS
    	Server  serverS
    }

    type cfgS struct {
    	App appS
    }

    var ss cfgS
    err := conf.GetSectionFrom("", &ss)
    t.Logf("cfgS: %v | err: %v", ss, err)

    assertEqual(t, []any{"a", 1, false}, ss.App.Logging.Words)
    assertEqual(t, -1, ss.App.Server.Sites)

    if !reflect.DeepEqual(ss.App.Logging.Words, []any{"a", 1, false}) {
    	t.Fail()
    }

    err = conf.GetSectionFrom("nonexist", nil)
    t.Log("nothing happened")

    err = conf.GetSectionFrom("nonexist", &ss)
    t.Logf("cfgS: %v | err: %v", ss, err)
    if err != nil {
    	t.Fail()
    }
    assertTrue(t, ss.App.Server.Sites == -1)

}

func newBasicStore(opts ...Opt) \*storeS {
conf := New(opts...)
conf.Set("app.debug", false)
// t.Logf("\nPath\n%v\n", conf.dump())
conf.Set("app.verbose", true)
// t.Logf("\nPath\n%v\n", conf.dump())
conf.Set("app.dump", 3)
conf.Set("app.logging.file", "/tmp/1.log")
conf.Set("app.server.start", 5)

    // conf.Set("app.logging.rotate", 6)
    // conf.Set("app.logging.words", []string{"a", "1", "false"})

    ss := conf.WithPrefix("app.logging")
    ss.Set("rotate", 6)
    ss.Set("words", []string{"a", "1", "false"})
    return conf.(*storeS)

}

以 Test 1 为例,一个标准的 cmdr app 带有内建的 generate 子命令,相应的配置项节选如下:

  app.cmd.                      <B>
    generate.                   <B>
      manual.                   <B>
        dir                     <L> app.cmd.generate.manual.dir =>
        type                    <L> app.cmd.generate.manual.type => 1
      doc.dir                   <L> app.cmd.generate.doc.dir =>
      shell.                    <B>
        Shell                   <L> app.cmd.generate.shell.Shell => auto
        dir                     <L> app.cmd.generate.shell.dir =>
        output                  <L> app.cmd.generate.shell.output =>
        auto                    <L> app.cmd.generate.shell.auto => true
        zsh                     <L> app.cmd.generate.shell.zsh => false
        bash                    <L> app.cmd.generate.shell.bash => false
        fi                      <B>
          sh                    <L> app.cmd.generate.shell.fish => false
          g                     <L> app.cmd.generate.shell.fig => false
        powershell              <L> app.cmd.generate.shell.powershell => false
        elvish                  <L> app.cmd.generate.shell.elvish => false

从 app.cmd.generate 抽出子树映射到 genS 结构当中将会提取 app.cmd.generate.manual.dir 和 app.cmd.generate.manual.type 配置项。

这也意味着 v.(genS).Manual.Type 必然获得值 1。

了解更多

Manual of `hedzr/store`

Chapter: Using Store

`hedzr/store` on Github

What is Next?

Components

Components

On Github

How is this guide?

最后更新于

目录

介绍
了解更多