From 352e593d8d1798b10c7304bf15b33d7130aeb72a Mon Sep 17 00:00:00 2001 From: Knut Ahlers Date: Sat, 6 Feb 2016 16:23:11 +0100 Subject: [PATCH] Initial version --- .gobuilder.yml | 4 +++ README.md | 47 ++++++++++++++++++++++++++ main.go | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 141 insertions(+) create mode 100644 .gobuilder.yml create mode 100644 README.md create mode 100644 main.go diff --git a/.gobuilder.yml b/.gobuilder.yml new file mode 100644 index 0000000..4f00758 --- /dev/null +++ b/.gobuilder.yml @@ -0,0 +1,4 @@ +build_matrix: + general: + ldflags: + - "-X main.version $(git describe --tags)" diff --git a/README.md b/README.md new file mode 100644 index 0000000..0faf7ab --- /dev/null +++ b/README.md @@ -0,0 +1,47 @@ +# Luzifer / envrun + +`envrun` is a small helper utility I wrote for myself to debug programs and scripts during their development expecting environment variables to be set to special values. Sure there is [gin]() for go webservers doing the same but I wanted something also for commandline utilities. + +It reads a `.env` file (configurable) from the current directory and then either takes its own environment variables or a clean set and adds the env variables found in `.env` to it. The resulting set is passed to the command you put as arguments to `envrun`. + +## Examples + +To visualize the effect of the utility the test command is `python test.py` with this simple python script: + +```python +import os + +for k in os.environ.keys(): + print "{} = {}".format(k, os.environ[k]) +``` + +It just prints the current environment to `STDOUT` and exits. + +```bash +# cat .env +MY_TEST_VAR=hello world +ANOTHER_VAR=foo + +# python test.py | grep MY_TEST_VAR +## No output on this command + +# envrun --help +Usage of envrun: + --clean[=false]: Do not pass current environment to child process + --env-file=".env": Location of the environment file + --q[=false]: Suppress informational messages from envrun + +# envrun python test.py | grep MY_TEST_VAR +MY_TEST_VAR = hello world + +# envrun python test.py | wc -l + 45 + +# envrun --clean python test.py | wc -l + 3 + +# envrun --clean python test.py +__CF_USER_TEXT_ENCODING = 0x1F5:0x0:0x0 +ANOTHER_VAR = foo +MY_TEST_VAR = hello world +``` diff --git a/main.go b/main.go new file mode 100644 index 0000000..7fa68a7 --- /dev/null +++ b/main.go @@ -0,0 +1,90 @@ +package main + +import ( + "io/ioutil" + "log" + "os" + "os/exec" + "strings" + + "github.com/Luzifer/rconfig" +) + +var ( + version = "dev" + cfg = struct { + EnvFile string `flag:"env-file" default:".env" description:"Location of the environment file"` + Silent bool `flag:"q" default:"false" description:"Suppress informational messages from envrun"` + CleanEnv bool `flag:"clean" default:"false" description:"Do not pass current environment to child process"` + }{} +) + +func init() { + rconfig.Parse(&cfg) +} + +func infoLog(message string, args ...interface{}) { + if !cfg.Silent { + log.Printf(message, args...) + } +} + +func envListToMap(list []string) map[string]string { + out := map[string]string{} + for _, entry := range list { + if len(entry) == 0 { + continue + } + + parts := strings.SplitN(entry, "=", 2) + out[parts[0]] = parts[1] + } + return out +} + +func envMapToList(envMap map[string]string) []string { + out := []string{} + for k, v := range envMap { + out = append(out, k+"="+v) + } + return out +} + +func main() { + body, err := ioutil.ReadFile(cfg.EnvFile) + if err != nil { + log.Fatalf("Could not read env-file: %s", err) + } + + var childenv map[string]string + if cfg.CleanEnv { + childenv = map[string]string{} + } else { + childenv = envListToMap(os.Environ()) + } + + pairs := envListToMap(strings.Split(string(body), "\n")) + for k, v := range pairs { + childenv[k] = v + } + + c := exec.Command(rconfig.Args()[1], rconfig.Args()[2:]...) + c.Env = envMapToList(childenv) + c.Stdout = os.Stdout + c.Stderr = os.Stderr + c.Stdin = os.Stdin + + err = c.Run() + + switch err.(type) { + case nil: + infoLog("Process exitted with code 0") + os.Exit(0) + case *exec.ExitError: + infoLog("Unclean exit with exit-code != 0") + os.Exit(1) + default: + log.Printf("An unknown error ocurred: %s", err) + os.Exit(2) + } +}