vendor/github.com/subosito/gotenv/gotenv.go
changeset 265 05c40b36d3b2
parent 260 445e01aede7e
equal deleted inserted replaced
264:8f478162d991 265:05c40b36d3b2
     1 // Package gotenv provides functionality to dynamically load the environment variables
     1 // Package gotenv provides functionality to dynamically load the environment variables
     2 package gotenv
     2 package gotenv
     3 
     3 
     4 import (
     4 import (
     5 	"bufio"
     5 	"bufio"
       
     6 	"bytes"
     6 	"fmt"
     7 	"fmt"
     7 	"io"
     8 	"io"
     8 	"os"
     9 	"os"
     9 	"path/filepath"
    10 	"path/filepath"
    10 	"regexp"
    11 	"regexp"
   172 	}
   173 	}
   173 
   174 
   174 	return file.Sync()
   175 	return file.Sync()
   175 }
   176 }
   176 
   177 
       
   178 // splitLines is a valid SplitFunc for a bufio.Scanner. It will split lines on CR ('\r'), LF ('\n') or CRLF (any of the three sequences).
       
   179 // If a CR is immediately followed by a LF, it is treated as a CRLF (one single line break).
       
   180 func splitLines(data []byte, atEOF bool) (advance int, token []byte, err error) {
       
   181 	if atEOF && len(data) == 0 {
       
   182 		return 0, nil, bufio.ErrFinalToken
       
   183 	}
       
   184 
       
   185 	idx := bytes.IndexAny(data, "\r\n")
       
   186 	switch {
       
   187 	case atEOF && idx < 0:
       
   188 		return len(data), data, bufio.ErrFinalToken
       
   189 
       
   190 	case idx < 0:
       
   191 		return 0, nil, nil
       
   192 	}
       
   193 
       
   194 	// consume CR or LF
       
   195 	eol := idx + 1
       
   196 	// detect CRLF
       
   197 	if len(data) > eol && data[eol-1] == '\r' && data[eol] == '\n' {
       
   198 		eol++
       
   199 	}
       
   200 
       
   201 	return eol, data[:idx], nil
       
   202 }
       
   203 
   177 func strictParse(r io.Reader, override bool) (Env, error) {
   204 func strictParse(r io.Reader, override bool) (Env, error) {
   178 	env := make(Env)
   205 	env := make(Env)
   179 	scanner := bufio.NewScanner(r)
   206 	scanner := bufio.NewScanner(r)
       
   207 	scanner.Split(splitLines)
   180 
   208 
   181 	firstLine := true
   209 	firstLine := true
   182 
   210 
   183 	for scanner.Scan() {
   211 	for scanner.Scan() {
   184 		line := strings.TrimSpace(scanner.Text())
   212 		line := strings.TrimSpace(scanner.Text())
   281 	if !hsq {
   309 	if !hsq {
   282 		fv := func(s string) string {
   310 		fv := func(s string) string {
   283 			return varReplacement(s, hsq, env, override)
   311 			return varReplacement(s, hsq, env, override)
   284 		}
   312 		}
   285 		val = varRgx.ReplaceAllStringFunc(val, fv)
   313 		val = varRgx.ReplaceAllStringFunc(val, fv)
   286 		val = parseVal(val, env, hdq, override)
       
   287 	}
   314 	}
   288 
   315 
   289 	env[key] = val
   316 	env[key] = val
   290 	return nil
   317 	return nil
   291 }
   318 }
   350 		return err
   377 		return err
   351 	}
   378 	}
   352 
   379 
   353 	return fmt.Errorf("line `%s` doesn't match format", s)
   380 	return fmt.Errorf("line `%s` doesn't match format", s)
   354 }
   381 }
   355 
       
   356 func parseVal(val string, env Env, ignoreNewlines bool, override bool) string {
       
   357 	if strings.Contains(val, "=") && !ignoreNewlines {
       
   358 		kv := strings.Split(val, "\r")
       
   359 
       
   360 		if len(kv) > 1 {
       
   361 			val = kv[0]
       
   362 			for _, l := range kv[1:] {
       
   363 				_ = parseLine(l, env, override)
       
   364 			}
       
   365 		}
       
   366 	}
       
   367 
       
   368 	return val
       
   369 }