{"id":18581919,"url":"https://github.com/coder/serpent","last_synced_at":"2025-04-10T11:35:40.714Z","repository":{"id":223730628,"uuid":"761336034","full_name":"coder/serpent","owner":"coder","description":"CLI framework for scale and configurability inspired by Cobra","archived":false,"fork":false,"pushed_at":"2024-11-18T20:28:03.000Z","size":608,"stargazers_count":18,"open_issues_count":9,"forks_count":4,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-02T22:35:30.904Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"cc0-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/coder.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-02-21T17:19:10.000Z","updated_at":"2025-03-06T10:07:56.000Z","dependencies_parsed_at":"2024-03-18T05:22:32.473Z","dependency_job_id":"46bff126-97b5-4bfb-a970-89dc649c1f0b","html_url":"https://github.com/coder/serpent","commit_stats":null,"previous_names":["coder/serpent"],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coder%2Fserpent","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coder%2Fserpent/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coder%2Fserpent/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coder%2Fserpent/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/coder","download_url":"https://codeload.github.com/coder/serpent/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248208688,"owners_count":21065205,"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":[],"created_at":"2024-11-07T00:08:21.654Z","updated_at":"2025-04-10T11:35:35.695Z","avatar_url":"https://github.com/coder.png","language":"Go","readme":"# serpent\n\n[![Go Reference](https://pkg.go.dev/badge/github.com/coder/serpent.svg)](https://pkg.go.dev/github.com/coder/serpent)\n\n`serpent` is a Go CLI configuration framework based on [cobra](https://github.com/spf13/cobra) and used by [coder/coder](https://github.com/coder/coder).\nIt's designed for large-scale CLIs with dozens of commands and hundreds\nof options. If you're building a small, self-contained tool, go with\ncobra.\n\n![help example](./example/help.png)\n\nWhen compared to cobra, serpent strives for:\n\n* Better default help output inspired by the Go toolchain\n* Greater flexibility in accepting options that span across multiple sources\n* Composition via middleware\n* Testability (e.g. OS Stdout and Stderr is only available to commands explicitly)\n\n## Basic Usage\n\nSee `example/echo`:\n\n```go\npackage main\n\nimport (\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/coder/serpent\"\n)\n\nfunc main() {\n\tvar upper bool\n\tcmd := serpent.Command{\n\t\tUse:   \"echo \u003ctext\u003e\",\n\t\tShort: \"Prints the given text to the console.\",\n\t\tOptions: serpent.OptionSet{\n\t\t\t{\n\t\t\t\tName:        \"upper\",\n\t\t\t\tValue:       serpent.BoolOf(\u0026upper),\n\t\t\t\tFlag:        \"upper\",\n\t\t\t\tDescription: \"Prints the text in upper case.\",\n\t\t\t},\n\t\t},\n\t\tHandler: func(inv *serpent.Invocation) error {\n\t\t\tif len(inv.Args) == 0 {\n\t\t\t\tinv.Stderr.Write([]byte(\"error: missing text\\n\"))\n\t\t\t\tos.Exit(1)\n\t\t\t}\n\n\t\t\ttext := inv.Args[0]\n\t\t\tif upper {\n\t\t\t\ttext = strings.ToUpper(text)\n\t\t\t}\n\n\t\t\tinv.Stdout.Write([]byte(text))\n\t\t\treturn nil\n\t\t},\n\t}\n\n\terr := cmd.Invoke().WithOS().Run()\n\tif err != nil {\n\t\tpanic(err)\n\t}\n}\n```\n\n## Design\nThis Design section assumes you have a good understanding of how `cobra` works.\n\n### Options\n\nSerpent is designed for high-configurability. To us, that means providing\nmany ways to configure the same value (env, YAML, flags, etc.) and keeping\nthe code clean and testable as you scale the number of options.\n\nSerpent's [Option](https://pkg.go.dev/github.com/coder/serpent#Option) type looks like:\n\n```go\ntype Option struct {\n\tName string\n\tFlag string\n\tEnv string\n\tDefault string\n\tValue pflag.Value\n\t// ...\n}\n```\n\nAnd is used by each [Command](https://pkg.go.dev/github.com/coder/serpent#Command) when\npassed as an array to the `Options` field.\n\n## More coming...\nThis README is a stub for now. We'll better explain the design and usage\nof `serpent` in the future.","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcoder%2Fserpent","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcoder%2Fserpent","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcoder%2Fserpent/lists"}