{"id":17355166,"url":"https://github.com/zephinzer/go-commander","last_synced_at":"2025-03-27T14:17:07.138Z","repository":{"id":57703777,"uuid":"494996263","full_name":"zephinzer/go-commander","owner":"zephinzer","description":"Package that wraps exec.Cmd in a useful way","archived":false,"fork":false,"pushed_at":"2022-05-30T03:02:47.000Z","size":12,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-01T18:27:16.542Z","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":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zephinzer.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":"2022-05-22T08:01:37.000Z","updated_at":"2022-05-22T08:03:12.000Z","dependencies_parsed_at":"2022-09-26T21:10:24.856Z","dependency_job_id":null,"html_url":"https://github.com/zephinzer/go-commander","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zephinzer%2Fgo-commander","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zephinzer%2Fgo-commander/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zephinzer%2Fgo-commander/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zephinzer%2Fgo-commander/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zephinzer","download_url":"https://codeload.github.com/zephinzer/go-commander/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245858881,"owners_count":20684062,"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-10-15T17:42:31.990Z","updated_at":"2025-03-27T14:17:07.117Z","avatar_url":"https://github.com/zephinzer.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Commander\n\nThis library wraps the `exec.Cmd` for readability and usability purposes. Some use cases I had when developing this:\n\n1. I want to execute a shell command from a Go application\n2. I want to get the output of the shell command to do some data transformations on it (eg. with the `aws` CLI command tool to list out infrastructure or with `kubectl` to get a list of pods/deployments *et cetera*)\n3. I want to be able to inject the user's current environment into the command\n4. I want the option to decide if the output to be printed to the default `stdout` or `stderr`\n\nThe purpose of this package is as an underlying library for a CLI tool that codifies contextual DevOps knowledge in an organisation. This means things like what commands should be run and in what order to achieve a certain desired outcome.\n\nSince this can vary from organisation to organisation, it's usually not easy to pick up on the conventions and it's not useful to internalise this since different projects can have different conventions. Therefore, I write a CLI tooling around conventions, and this library helps with that.\n\n# Usage\n\nTo use this library, import it:\n\n```go\nimport \"github.com/zephinzer/go-commander\"\n```\n\n## Basic/universal usage\n\nCreate a new command via the `NewCommand(...)` function:\n\n```go\nfunc main() {\n  // ...\n  command := commander.NewCommand(\"ls\").\n    AddParam(\"-al\")\n  // ...\n}\n```\n\nFinally, whenever you want, you can execute it:\n\n```go\n// ...\n  output := command.Execute()\n// ...\n```\n\nTo get the output of the command, you can use the `.Stderr` and `.Stdout` properties of the output object:\n\n```go\n// ...\n  // to get the stderr\n  fmt.Println(output.Stderr.String())\n  // to get the stdout\n  fmt.Println(output.Stdout.String())\n// ...\n```\n\n## Setting custom environment variables\n\nIt's usually useful to be able to inject environment variables into a custom command you wish to run. For example, if the user's `AWS_PROFILE` is set to `\"production\"` but you want it set to `\"staging\"`, you can inject environment variables using the `SetEnvironment` method. These will overwrite the global environment if the global environment is not disabled.\n\n```go\n// ...\n  command := commander.NewCommand(\"aws\").\n    SetEnvironment(\"AWS_PROFILE\", \"staging\").\n    AddParam(\"sts\")\n    AddParam(\"get-caller-identity\")\n// ...\n```\n\n## Executing from a different directory\n\nBy default, the current working directory is used. If you would like to run the command from a different directory, use the `SetWorkingDirectory` method to set the path to the directory where you would like the command to run from\n\n```go\n// ...\n  command := commander.NewCommand(\"ls\").\n    SetWorkingDirectory(\"./tests\")\n// ...\n```\n\n## Printing the command\n\nFor people who don't know what they're going to run, it can be useful to see the command they're running. This also gives you a better idea on how to debug things if things go wrong. To print the command as a string, you can use the `GetAsString` method\n\n```go\n// ...\n  command := commander.NewCommand(\"ls\").\n    SetWorkingDirectory(\"./tests\")\n\n  fmt.Println(command.GetAsString())\n// ...\n```\n\n## Enable `stdout`/`stderr` mirroring\n\nTo print the `stdout`/`stderr` output as it comes in, you can use the `EnableStdout` or `EnableStderr` chainable methods\n\n```go\n// ...\n  command := commander.NewCommand(\"ls\").\n    SetWorkingDirectory(\"./tests\").\n    EnableStdout(). // and/or\n    EnableStderr()\n// ...\n```\n\n## Setting custom `stdout`/`stderr` streams\n\nOccassionally it could be useful to stream the standard output/error to another buffer. To do this, you can use the `SetStderr` or `SetStdout` methods:\n\n```go\n// ...\n  otherBuffer := bytes.NewBuffer(nil)\n  otherBufferWriter := bufio.NewWriter(otherBuffer)\n\n  command := commander.NewCommand(\"ls\").\n    SetWorkingDirectory(\"./tests\").\n    SetStderr(otherBufferWriter). // and/or\n    SetStdout(otherBufferWriter)\n// ...\n```\n\n## Disable environment variable injection\n\nSometimes it's useful to disable the global environment from polluting a command's environment. To do that, use the `.DisableGlobalEnvironment` method.\n\n```go\n// ...\n  command := commander.NewCommand(\"ls\").\n    DisableGlobalEnvironment()\n// ...\n```\n\n# Contribution\n\n1. Run `go mod tidy` or `go mod vendor` to bring in the dependencies\n2. Run `go test ./...` to test this package\n3. When pushed to Gitlab, this repository will trigger a pipeline to run tests, see the [`./.gitlab-ci.yml` file](./.gitlab-ci.yml) for more information\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzephinzer%2Fgo-commander","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzephinzer%2Fgo-commander","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzephinzer%2Fgo-commander/lists"}