// ParseEnvironment takes a slice of strings in key=value format and transforms // them into a map. List of duplicate keys is returned in the second return // value. func ParseEnvironment(vals ...string) (Environment, []string, []error) { errs := []error{} duplicates := []string{} env := make(Environment) for _, s := range vals { valid := cmdutil.IsValidEnvironmentArgument(s) p := strings.SplitN(s, "=", 2) if !valid || len(p) != 2 { errs = append(errs, fmt.Errorf("invalid parameter assignment in %q", s)) continue } key, val := p[0], p[1] if _, exists := env[key]; exists { duplicates = append(duplicates, key) continue } env[key] = val } return env, duplicates, errs }
// LoadEnvironmentFile accepts filename of a file containing key=value pairs // and puts these pairs into a map. If filename is "-" the file contents are // read from the stdin argument, provided it is not nil. func LoadEnvironmentFile(filename string, stdin io.Reader) (Environment, error) { errorFilename := filename if filename == "-" && stdin != nil { //once https://github.com/joho/godotenv/pull/20 is merged we can get rid of using tempfile temp, err := ioutil.TempFile("", "origin-env-stdin") if err != nil { return nil, fmt.Errorf("Cannot create temporary file: %s", err) } filename = temp.Name() errorFilename = "stdin" defer os.Remove(filename) if _, err = io.Copy(temp, stdin); err != nil { return nil, fmt.Errorf("Cannot write to temporary file %q: %s", filename, err) } temp.Close() } // godotenv successfuly returns empty map when given path to a directory, // remove this once https://github.com/joho/godotenv/pull/22 is merged if info, err := os.Stat(filename); err == nil && info.IsDir() { return nil, fmt.Errorf("Cannot read varaiables from %q: is a directory", filename) } else if err != nil { return nil, fmt.Errorf("Cannot stat %q: %s", filename, err) } env, err := godotenv.Read(filename) if err != nil { return nil, fmt.Errorf("Cannot read variables from file %q: %s", errorFilename, err) } for k, v := range env { if !cmdutil.IsValidEnvironmentArgument(fmt.Sprintf("%s=%s", k, v)) { return nil, fmt.Errorf("invalid parameter assignment in %s=%s", k, v) } } return env, nil }