diff --git a/cmd/cmd.go b/cmd/cmd.go new file mode 100644 index 0000000..555dc1e --- /dev/null +++ b/cmd/cmd.go @@ -0,0 +1,54 @@ +package main + +import ( + "flag" + "fmt" + "log" + + "strings" + + "github.com/joho/godotenv" +) + +func main() { + var showHelp bool + flag.BoolVar(&showHelp, "h", false, "show help") + var rawEnvFilenames string + flag.StringVar(&rawEnvFilenames, "f", "", "comma separated paths to .env files") + + flag.Parse() + + usage := ` +Run a process with a env setup from a .env file + +godotenv [-f ENV_FILE_PATHS] COMMAND_ARGS + +ENV_FILE_PATHS: comma separated paths to .env files +COMMAND_ARGS: command and args you want to run + +example + godotenv -f /path/to/something/.env,/another/path/.env fortune +` + // if no args or -h flag + // print usage and return + args := flag.Args() + if showHelp || len(args) == 0 { + fmt.Println(usage) + return + } + + // load env + var envFilenames []string + if rawEnvFilenames != "" { + envFilenames = strings.Split(rawEnvFilenames, ",") + } + + // take rest of args and "exec" them + cmd := args[0] + cmdArgs := args[1:len(args)] + + err := godotenv.Exec(envFilenames, cmd, cmdArgs) + if err != nil { + log.Fatal(err) + } +} diff --git a/godotenv.go b/godotenv.go index 6b643f3..816e759 100644 --- a/godotenv.go +++ b/godotenv.go @@ -19,6 +19,7 @@ import ( "bufio" "errors" "os" + "os/exec" "strings" ) @@ -45,6 +46,10 @@ func Load(filenames ...string) (err error) { return } +/* + Read all env (with same file loading semantics as Load) but return values as + a map rather than automatically writing values into env +*/ func Read(filenames ...string) (envMap map[string]string, err error) { filenames = filenamesOrDefault(filenames) envMap = make(map[string]string) @@ -65,6 +70,25 @@ func Read(filenames ...string) (envMap map[string]string, err error) { return } +/* + Loads env vars from the specified filenames (empty map falls back to default) + then executes the cmd specified. + + Simply hooks up os.Stdin/err/out to the command and calls Run() + + If you want more fine grained control over your command it's recommended + that you use `Load()` or `Read()` and the `os/exec` package yourself. +*/ +func Exec(filenames []string, cmd string, cmdArgs []string) error { + Load(filenames...) + + command := exec.Command(cmd, cmdArgs...) + command.Stdin = os.Stdin + command.Stdout = os.Stdout + command.Stderr = os.Stderr + return command.Run() +} + func filenamesOrDefault(filenames []string) []string { if len(filenames) == 0 { return []string{".env"}