{"id":20608759,"url":"https://github.com/andeya/cfgo","last_synced_at":"2025-04-15T04:24:03.530Z","repository":{"id":57482143,"uuid":"90865409","full_name":"andeya/cfgo","owner":"andeya","description":"Cfgo from the YAML document, bi-directional synchronous multi-module configuration.","archived":false,"fork":false,"pushed_at":"2022-06-26T15:29:53.000Z","size":81,"stargazers_count":9,"open_issues_count":0,"forks_count":5,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-28T15:51:48.814Z","etag":null,"topics":["auto-sync-config","configuration","multi-config","multi-module-config","reload-config","yaml"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/andeya.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-05-10T13:07:36.000Z","updated_at":"2022-06-26T15:29:56.000Z","dependencies_parsed_at":"2022-09-02T04:20:19.294Z","dependency_job_id":null,"html_url":"https://github.com/andeya/cfgo","commit_stats":null,"previous_names":["henrylee2cn/cfgo"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andeya%2Fcfgo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andeya%2Fcfgo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andeya%2Fcfgo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andeya%2Fcfgo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andeya","download_url":"https://codeload.github.com/andeya/cfgo/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249004774,"owners_count":21196940,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["auto-sync-config","configuration","multi-config","multi-module-config","reload-config","yaml"],"created_at":"2024-11-16T10:11:48.018Z","updated_at":"2025-04-15T04:24:03.514Z","avatar_url":"https://github.com/andeya.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# cfgo  [![GoDoc](https://godoc.org/github.com/tsuna/gohbase?status.png)](https://godoc.org/github.com/andeya/cfgo)\n\nCfgo from the YAML document, bi-directional synchronous multi-module configuration.\n\nThe structure of the generated document will reflect the structure of the value itself.\n\nMaps and pointers (to struct, string, int, etc) are accepted as the in value.\n\nStruct fields are only unmarshalled if they are exported (have an upper case\nfirst letter), and are unmarshalled using the field name lowercased as the\ndefault key. Custom keys may be defined via the \"yaml\" name in the field\ntag: the content preceding the first comma is used as the key, and the\nfollowing comma-separated options are used to tweak the marshalling process.\nConflicting names result in a runtime error.\n\nThe field tag format accepted is:\n\n    (...) yaml:\"[\u003ckey\u003e][,\u003cflag1\u003e[,\u003cflag2\u003e]]\" (...)\n\nThe following flags are currently supported:\n\n    omitempty    Only include the field if it's not set to the zero\n                 value for the type or to empty slices or maps.\n                 Does not apply to zero valued structs.\n\n    flow         Marshal using a flow style (useful for structs,\n                 sequences and maps).\n\n    inline       Inline the field, which must be a struct or a map,\n                 causing all of its fields or keys to be processed as if\n                 they were part of the outer struct. For maps, keys must\n                 not conflict with the yaml keys of other struct fields.\n\nIn addition, if the key is `-`, the field is ignored.\n\n# register config\n\n- m1/module_1.go\n\n```go\npackage m1\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/andeya/cfgo\"\n)\n\ntype T1 struct {\n\tF int `yaml:\"a,omitempty\"`\n\tB int\n}\n\nfunc (t *T1) Reload(bind cfgo.BindFunc) error {\n\tfmt.Println(\"module_1: T1 reload do some thing...\")\n\treturn bind()\n}\n\nfunc init() {\n\tstructPtr1 := \u0026T1{\n\t\tF: 1, //default value\n\t\tB: 2, //default value\n\t}\n\t{\n\t\tc := cfgo.MustGet(\"config/config.yaml\")\n\t\tc.MustReg(\"section1\", structPtr1)\n\t}\n\t// or\n\t// cfgo.MustReg(\"section1\", structPtr1)\n\tfmt.Printf(\"structPtr1(config/config.yaml): %+v\\n\\n\", structPtr1)\n}\n\n```\n\n- m2/module_2.go\n\n```go\npackage m2\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/andeya/cfgo\"\n)\n\ntype T2 struct {\n\tX string\n\tY []string `yaml:\",flow\"`\n\tZ []int\n\tN bool\n}\n\nfunc (t *T2) Reload(bind cfgo.BindFunc) error {\n\tfmt.Println(\"module_2: T2 reload do some thing...\")\n\treturn bind()\n}\n\nfunc init() {\n\tstructPtr2 := \u0026T2{\n\t\tX: \"xxx\",                   //default value\n\t\tY: []string{\"x\", \"y\", \"z\"}, //default value\n\t\tZ: []int{1, 2, 3},          //default value\n\t}\n\t{\n\t\tc := cfgo.MustGet(\"config/config.yaml\")\n\t\tc.MustReg(\"section2\", structPtr2)\n\t}\n\t// or\n\t// cfgo.MustReg(\"section2\", structPtr2)\n\tfmt.Printf(\"structPtr2(config/config.yaml): %+v\\n\\n\", structPtr2)\n}\n\n```\n\n- main.go\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/andeya/cfgo\"\n\t\"github.com/andeya/cfgo/example/m1\"\n\t_ \"github.com/andeya/cfgo/example/m2\"\n)\n\ntype T struct {\n\tC string\n\tm1.T1\n}\n\nfunc (t *T) Reload(bind cfgo.BindFunc) error {\n\tfmt.Println(\"main T reload do some thing...\")\n\treturn bind()\n}\n\nfunc main() {\n\tstructPtr := \u0026T{\n\t\tC: \"c\",\n\t\tT1: m1.T1{\n\t\t\tB: 2, //default value\n\t\t},\n\t}\n\n\t// output: config/config.yaml\n\n\tc := cfgo.MustGet(\"config/config.yaml\")\n\tc.MustReg(\"section\", structPtr)\n\t// or\n\t// cfgo.MustReg(\"section\", structPtr)\n\n\tfmt.Printf(\"structPtr(config/config.yaml): %+v\\n\\n\", structPtr)\n\n\t// output: config/config3.yaml\n\t\n\tc3 := cfgo.MustGet(\"config/config3.yaml\")\n\tc3.MustReg(\"section\", structPtr)\n\t\n\tfmt.Printf(\"structPtr(config/config3.yaml): %+v\\n\\n\", structPtr)\n\n\tfmt.Printf(\" ----------------------------------------------------------- \\n\\n\")\n\n\tfmt.Printf(\"config/config.yaml content:\\n%s\\n\\n\", c.Content())\n\t// or\n\t// fmt.Printf(\"config.yaml content:\\n%s\\n\\n\", cfgo.Content())\n\n\tfmt.Printf(\" ----------------------------------------------------------- \\n\\n\")\n\n\tfmt.Printf(\"config/config3.yaml content:\\n%s\\n\\n\", c3.Content())\n}\n```\n\nprint:\n\n```\nmodule_1: T1 reload do some thing...\nstructPtr1(config/config.yaml): \u0026{F:1 B:2}\n\nmodule_2: T2 reload do some thing...\nstructPtr2(config/config.yaml): \u0026{X:xxx Y:[x y z] Z:[1 2 3] N:false}\n\n=== RUN   Test1\nmain T reload do some thing...\nstructPtr(config/config.yaml): \u0026{C:c T1:{F:0 B:2}}\n\nmain T reload do some thing...\nstructPtr(config/config3.yaml): \u0026{C:c T1:{F:0 B:2}}\n\n ----------------------------------------------------------- \n\nconfig/config.yaml content:\nsection:\n  c: c\n  t1:\n    b: 2\n\nsection1:\n  a: 1\n  b: 2\n\nsection2:\n  x: xxx\n  \"y\": [x, \"y\", z]\n  z:\n  - 1\n  - 2\n  - 3\n  \"n\": false\n\n\n ----------------------------------------------------------- \n\nconfig/config3.yaml content:\nsection:\n  c: c\n  t1:\n    b: 2\n\n```\n\noutput `config/config.yaml`:\n\n```\nsection:\n  c: c\n  t1:\n    b: 2\n\nsection1:\n  a: 1\n  b: 2\n\nsection2:\n  x: xxx\n  \"y\": [x, \"y\", z]\n  z:\n  - 1\n  - 2\n  - 3\n  \"n\": false\n\n```\n\noutput `config/config3.yaml`:\n\n```\nsection:\n  c: c\n  t1:\n    b: 2\n\n```\n\n# custom config\n\nCfgo allows to custom non-automated configuration in yaml file.\n\nexample `config/mixed_config.yaml`:\n\n```\n# cfgo-register section\nregister:\n  auto: true\n\n# your custom section\ncustom: true\n\n```\n\ngolang code main.go:\n\n```\npackage main\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/andeya/cfgo\"\n)\n\ntype M struct {\n\tAuto bool\n}\n\nfunc (m *M) Reload(bind cfgo.BindFunc) error {\n\treturn bind()\n}\n\nfunc main() {\n\tm := new(M)\n\tmixed := cfgo.MustGet(\"config/mixed_config.yaml\")\n\tmixed.MustReg(\"register\", m)\n\n\tfmt.Printf(\"config/mixed_config.yaml content:\\n%s\\n\\n\", mixed.Content())\n\tfmt.Printf(\"config/mixed_config.yaml config m:\\n%#v\\n\\n\", m)\n\t{\n\t\tcustom, _ := mixed.GetSection(\"custom\")\n\t\tfmt.Printf(\"config/mixed_config.yaml GetSection 'custom':\\n%#v\\n\\n\", custom)\n\t}\n\t{\n\t\tvar custom bool\n\t\t_ = mixed.BindSection(\"custom\", \u0026custom)\n\t\tfmt.Printf(\"config/mixed_config.yaml BindSection 'custom':\\n%#v\\n\\n\", custom)\n\t}\n}\n```\n\nRun the command `go run main.go`, will print:\n\n```\nconfig/mixed_config.yaml content:\nregister:\n  auto: true\n\n# ------------------------- non-automated configuration -------------------------\n\ncustom:\n  true\n\n\nconfig/mixed_config.yaml config m:\n\u0026main.M{Auto:true}\n\nconfig/mixed_config.yaml GetSection 'custom':\ntrue\n\nconfig/mixed_config.yaml BindSection 'custom':\ntrue\n```\n\nnow `config/mixed_config.yaml` content auto-change to:\n\n```\nregister:\n  auto: true\n\n# ------------------------- non-automated configuration -------------------------\n\ncustom:\n  true\n\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandeya%2Fcfgo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandeya%2Fcfgo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandeya%2Fcfgo/lists"}