{"id":19156301,"url":"https://github.com/ess/keylargo","last_synced_at":"2025-09-02T11:08:34.342Z","repository":{"id":66321324,"uuid":"109095104","full_name":"ess/keylargo","owner":"ess","description":"A minimal Aruba-like experience for godog","archived":false,"fork":false,"pushed_at":"2017-11-01T08:20:42.000Z","size":18,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"develop","last_synced_at":"2025-02-22T21:41:55.272Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ess.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":"2017-11-01T06:23:25.000Z","updated_at":"2017-11-01T06:23:42.000Z","dependencies_parsed_at":"2024-04-20T12:02:58.681Z","dependency_job_id":null,"html_url":"https://github.com/ess/keylargo","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/ess/keylargo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ess%2Fkeylargo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ess%2Fkeylargo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ess%2Fkeylargo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ess%2Fkeylargo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ess","download_url":"https://codeload.github.com/ess/keylargo/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ess%2Fkeylargo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273272598,"owners_count":25075996,"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","status":"online","status_checked_at":"2025-09-02T02:00:09.530Z","response_time":77,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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-09T08:34:02.330Z","updated_at":"2025-09-02T11:08:34.322Z","avatar_url":"https://github.com/ess.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"Keylargo is a set of [godog](https://github.com/DATA-DOG/godog) helpers for in-process CLI application testing. In essence, it is a minimal [Aruba](https://github.com/cucumber/aruba)-like experience.\n\n## Why? ##\n\nBecause I work on a lot of CLI apps, and I drank the Cucumber/Aruba special punch to such a degree that it's my preferred way to work.\n\nAlso, since it is an in-process tester, it's fairly trivial to mock external REST APIs and the like (for better or for worse).\n\n## Installation ##\n\nI suggest the use of [dep](https://github.com/golang/dep) for managing your Go deps, but you should be able to install it directly without issues:\n\n```\ngo get github.com/ess/keylargo\n```\n\nAs mentioned, though, it's probably better to use a package manager that supports SemVer.\n\n## Usage ###\n\nLet's talk about the `echo` command for a second. By default, it just prints its arguments to STDOUT, followed by a newline. If you provide the `-n` flag, it still does that, but it does not print the newline.\n\n### The Command ###\n\nIn order for keylargo to run a command, it must implement the `keylargo.Command` interface:\n\n```go\ntype Command interface {\n\tSetArgs([]string)\n\tExecute() error\n}\n```\n\nYou can use any CLI framework you like (or just roll your own implementation), but a great example of an object that already implements this interface is `*cobra.Command` from [cobra](https://github.com/spf13/cobra).\n\nAlso, in order for keylargo to actually run your command, you'll need to set it as the root command via `keylargo.SetRootCmd(yourCommand)`, most likely in your godog suite setup (see `main_test.go` below).\n\nFinally, it is worth pointing out that this whole thing falls apart if the command (or any of its dependencies) should call `os.Exit()` (or more or less anything else that would normally cause program termination). Instead, it's expected that the command will bubble any and all errors up to the top level.\n\n### Keylargo Steps ###\n\nKeylargo adds the following steps to the suite:\n\n* `When I run \"command and its args\"` is used to actually run the command\n* `Then the command succeeds` is used to indicate that we expect the command to return no error\n* `Then the command fails` is used to indicate that we expect the command to return an error\n\n### Keylargo Helpers ###\n\nKeylargo containst he following helper functions that can be used to compose your own steps:\n\n* `keylargo.LastCommandOutput()` is a string that contains the captured output for the last command ran via the `When I run` step.\n\n### features/echo.feature ###\n\n```gherkin\nFeature: echo\n  In order to print stuff to the terminal\n  As a user\n  I want to be able to echo some text\n  And I want for this stanza to be less awkward, but that's what examples are like.\n\n  Scenario: default behavior\n    When I run \"echo ohai tharrrrrrr\"\n    Then the output contains \"ohai tharrrrrrr\"\n    And the output ends with a newline\n    And the command succeeds\n\n  Scenario: suppress newline\n    When I run \"echo -n sup duder\"\n    Then the output contains \"sup duder\"\n    But the output has no newlines\n    And the command succeeds\n```\n\n### main_test.go ###\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/DATA-DOG/godog\"\n\t\"github.com/ess/keylargo\"\n)\n\nfunc theOutputContains(expected string) error {\n\tif !strings.Contains(keylargo.LastCommandOutput(), expected) {\n\t\treturn fmt.Errorf(\"Expected output to contain '%s'\", expected)\n\t}\n\n\treturn nil\n}\n\nfunc terminatingNewline() error {\n\tif !strings.HasSuffix(keylargo.LastCommandOutput(), \"\\n\") {\n\t\treturn fmt.Errorf(\"Expected output to have a newline terminator\")\n\t}\n\n\treturn nil\n}\n\nfunc noNewline() error {\n\tif strings.Contains(keylargo.LastCommandOutput(), \"\\n\") {\n\t\treturn fmt.Errorf(\"Expected output to contain no newlines\")\n\t}\n\n\treturn nil\n}\n\nfunc TestMain(m *testing.M) {\n\t// Set up the command that is actually run via keylargo. The object passed in\n\t// must implement the following interface:\n\t//\n\t//   type Command interface{\n\t//     SetArgs([]string)\n\t//     Execute() error\n\t//   }\n\n\tkeylargo.SetRootCmd(echoCmd)\n\n\tstatus := godog.RunWithOptions(\"godog\",\n\t\tfunc(s *godog.Suite) {\n\t\t\t// Add the keylargo steps to the suite\n\t\t\tkeylargo.StepUp(s)\n\n\t\t\t// Add your own custom steps\n\n\t\t\ts.Step(`^the output contains \"([^\"]*)\"$`, theOutputContains)\n\t\t\ts.Step(`the output ends with a newline`, terminatingNewline)\n\t\t\ts.Step(`the output has no newlines`, noNewline)\n\n\t\t\ts.BeforeScenario(func(interface{}) {\n\t\t\t\tskipNewline = false\n\t\t\t})\n\n\t\t},\n\n\t\tgodog.Options{\n\t\t\tFormat:    \"pretty\",\n\t\t\tPaths:     []string{\"features\"},\n\t\t\tRandomize: time.Now().UTC().UnixNano(),\n\t\t},\n\t)\n\n\tif st := m.Run(); st \u003e status {\n\t\tstatus = st\n\t}\n\n\tos.Exit(status)\n}\n```\n\n### main.go ###\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/spf13/cobra\"\n)\n\nvar skipNewline bool\n\nvar echoCmd = \u0026cobra.Command{\n\tUse:   \"echo\",\n\tShort: \"what did i just say?\",\n\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\toutput := strings.Join(args, \" \")\n\n\t\tfmt.Printf(\"%s\"+terminator(), output)\n\n\t\treturn nil\n\t},\n}\n\nfunc init() {\n\techoCmd.Flags().BoolVarP(\u0026skipNewline, \"no-newline\", \"n\", false,\n\t\t\"Suppress the terminating newline\")\n}\n\nfunc main() {\n\terr := echoCmd.Execute()\n\tif err != nil {\n\t\tfmt.Println(err)\n\t\tos.Exit(1)\n\t}\n}\n\nfunc terminator() string {\n\tif skipNewline {\n\t\treturn \"\"\n\t}\n\n\treturn \"\\n\"\n}\n```\n\n## History ##\n\n* v0.1.0 - No hard godog dependencies\n* v0.0.1 - Initial release\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fess%2Fkeylargo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fess%2Fkeylargo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fess%2Fkeylargo/lists"}