commit dec206e9646943f8d2cb683f939ba492595f0514 Author: Timon Ringwald Date: Wed Jul 13 11:48:12 2022 +0200 initial commit diff --git a/.env b/.env new file mode 100644 index 0000000..b89676f --- /dev/null +++ b/.env @@ -0,0 +1 @@ +MY_VAR="hello world" diff --git a/asd b/asd new file mode 100644 index 0000000..2598229 --- /dev/null +++ b/asd @@ -0,0 +1 @@ +MY_VAR="bye world" diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..96d8c76 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module git.tordarus.net/Tordarus/loadenv + +go 1.18 diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..e69de29 diff --git a/loadenv b/loadenv new file mode 100755 index 0000000..5c10b4d Binary files /dev/null and b/loadenv differ diff --git a/main.go b/main.go new file mode 100644 index 0000000..b5783d7 --- /dev/null +++ b/main.go @@ -0,0 +1,75 @@ +package main + +import ( + "bufio" + "flag" + "fmt" + "io" + "os" + "os/exec" + "regexp" +) + +var ( + EnvFilePath = flag.String("f", ".env", "environment file") + + EnvVarRegex = regexp.MustCompile(`^(.*?)=(.*?)$`) + EnvCommentRegex = regexp.MustCompile(`^[ \t]*#.*?$`) +) + +func main() { + flag.Parse() + + envFile, err := os.Open(*EnvFilePath) + if err != nil { + panic(err) + } + defer envFile.Close() + + envVars := parseEnvFile(envFile) + args := flag.Args() + + newEnv := append(os.Environ(), envVars...) + + if len(args) == 0 { + for _, envVar := range newEnv { + fmt.Println(envVar) + } + return + } + + cmd := exec.Command(args[0], args[1:]...) + cmd.Env = newEnv + + cmd.Stdin = os.Stdin + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + + if err := cmd.Run(); err != nil { + if exitErr, ok := err.(*exec.ExitError); ok { + os.Exit(exitErr.ExitCode()) + return + } else { + panic(err) + } + } +} + +func parseEnvFile(r io.Reader) []string { + env := make([]string, 0) + s := bufio.NewScanner(r) + l := 0 + for s.Scan() { + l++ + + matches := EnvVarRegex.FindStringSubmatch(s.Text()) + if len(matches) != 0 { + key, value := matches[1], os.ExpandEnv(matches[2]) + env = append(env, fmt.Sprintf("%s=%s", key, value)) + } else if !EnvCommentRegex.MatchString(s.Text()) { + panic(fmt.Sprintf("invalid env syntax on line %d", l)) + } + } + + return env +}