{"id":13676478,"url":"https://github.com/desertbit/grumble","last_synced_at":"2025-04-29T07:32:22.091Z","repository":{"id":28078205,"uuid":"116043627","full_name":"desertbit/grumble","owner":"desertbit","description":"A powerful modern CLI and SHELL","archived":false,"fork":false,"pushed_at":"2024-12-11T23:37:03.000Z","size":74,"stargazers_count":542,"open_issues_count":19,"forks_count":56,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-04-28T08:23:13.890Z","etag":null,"topics":["cli","flags","golang","shell"],"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/desertbit.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":"AUTHORS","dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-01-02T18:13:57.000Z","updated_at":"2025-04-04T16:49:06.000Z","dependencies_parsed_at":"2024-06-18T12:39:40.116Z","dependency_job_id":"84725328-bc60-4de5-b1c0-06dc14a106fd","html_url":"https://github.com/desertbit/grumble","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/desertbit%2Fgrumble","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/desertbit%2Fgrumble/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/desertbit%2Fgrumble/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/desertbit%2Fgrumble/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/desertbit","download_url":"https://codeload.github.com/desertbit/grumble/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251455968,"owners_count":21592268,"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":["cli","flags","golang","shell"],"created_at":"2024-08-02T13:00:28.124Z","updated_at":"2025-04-29T07:32:21.384Z","avatar_url":"https://github.com/desertbit.png","language":"Go","readme":"# Grumble - A powerful modern CLI and SHELL\n\n[![GoDoc](https://godoc.org/github.com/desertbit/grumble?status.svg)](https://godoc.org/github.com/desertbit/grumble)\n[![Go Report Card](https://goreportcard.com/badge/github.com/desertbit/grumble)](https://goreportcard.com/report/github.com/desertbit/grumble)\n\nThere are a handful of powerful go CLI libraries available ([spf13/cobra](https://github.com/spf13/cobra), [urfave/cli](https://github.com/urfave/cli)).\nHowever sometimes an integrated shell interface is a great and useful extension for the actual application.\nThis library offers a simple API to create powerful CLI applications and automatically starts\nan **integrated interactive shell**, if the application is started without any command arguments.\n\n**Hint:** We do not guarantee 100% backwards compatiblity between minor versions (1.x). However, the API is mostly stable and should not change much.\n\n[![asciicast](https://asciinema.org/a/155332.png)](https://asciinema.org/a/155332?t=5)\n\n## Introduction\n\nCreate a grumble APP.\n\n```go\nvar app = grumble.New(\u0026grumble.Config{\n\tName:        \"app\",\n\tDescription: \"short app description\",\n\n\tFlags: func(f *grumble.Flags) {\n\t\tf.String(\"d\", \"directory\", \"DEFAULT\", \"set an alternative directory path\")\n\t\tf.Bool(\"v\", \"verbose\", false, \"enable verbose mode\")\n\t},\n})\n```\n\nRegister a top-level command. *Note: Sub commands are also supported...*\n\n```go\napp.AddCommand(\u0026grumble.Command{\n    Name:      \"daemon\",\n    Help:      \"run the daemon\",\n    Aliases:   []string{\"run\"},\n\n    Flags: func(f *grumble.Flags) {\n        f.Duration(\"t\", \"timeout\", time.Second, \"timeout duration\")\n    },\n\n    Args: func(a *grumble.Args) {\n        a.String(\"service\", \"which service to start\", grumble.Default(\"server\"))\n    },\n\n    Run: func(c *grumble.Context) error {\n        // Parent Flags.\n        c.App.Println(\"directory:\", c.Flags.String(\"directory\"))\n        c.App.Println(\"verbose:\", c.Flags.Bool(\"verbose\"))\n        // Flags.\n        c.App.Println(\"timeout:\", c.Flags.Duration(\"timeout\"))\n        // Args.\n        c.App.Println(\"service:\", c.Args.String(\"service\"))\n        return nil\n    },\n})\n```\n\nRun the application.\n\n```go\nerr := app.Run()\n```\n\nOr use the builtin *grumble.Main* function to handle errors automatically.\n\n```go\nfunc main() {\n\tgrumble.Main(app)\n}\n```\n\n## Shell Multiline Input\n\nBuiltin support for multiple lines.\n\n```\n\u003e\u003e\u003e This is \\\n... a multi line \\\n... command\n```\n\n## Separate flags and args specifically\nIf you need to pass a flag-like value as positional argument, you can do so by using a double dash:  \n`\u003e\u003e\u003e command --flag1=something -- --myPositionalArg`\n\n## Remote shell access with readline\nBy calling RunWithReadline() rather than Run() you can pass instance of readline.Instance. \nOne of interesting usages is having a possibility of remote access to your shell:\n\n```go\nhandleFunc := func(rl *readline.Instance) {\n\n    var app = grumble.New(\u0026grumble.Config{\n        // override default interrupt handler to avoid remote shutdown\n        InterruptHandler: func(a *grumble.App, count int) {\n            // do nothing\n        },\n\t\t\n        // your usual grumble configuration\n    })  \n    \n    // add commands\n\t\n    app.RunWithReadline(rl)\n\n}\n\ncfg := \u0026readline.Config{}\nreadline.ListenRemote(\"tcp\", \":5555\", cfg, handleFunc)\n```\n\nIn the client code just use readline built in DialRemote function:\n\n```go\nif err := readline.DialRemote(\"tcp\", \":5555\"); err != nil {\n    fmt.Errorf(\"An error occurred: %s \\n\", err.Error())\n}\n```\n\n## Samples\n\nCheck out the [sample directory](/sample) for some detailed examples.\n\n## Projects using Grumble\n\n- grml - A simple build automation tool written in Go: https://github.com/desertbit/grml\n- orbit - A RPC-like networking backend written in Go: https://github.com/desertbit/orbit\n\n## Known issues\n- Windows unicode not fully supported ([issue](https://github.com/desertbit/grumble/issues/48))\n\n## Additional Useful Packages\n\n- https://github.com/AlecAivazis/survey\n- https://github.com/tj/go-spin\n\n## Credits\n\nThis project is based on ideas from the great [ishell](https://github.com/abiosoft/ishell) library.\n\n## License\n\nMIT\n","funding_links":[],"categories":["CLI frameworks","Go"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdesertbit%2Fgrumble","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdesertbit%2Fgrumble","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdesertbit%2Fgrumble/lists"}