github.com/akashshinde/docker@v1.9.1/opts/envfile.go (about)

     1  package opts
     2  
     3  import (
     4  	"bufio"
     5  	"fmt"
     6  	"os"
     7  	"strings"
     8  )
     9  
    10  // ParseEnvFile reads a file with environment variables enumerated by lines
    11  //
    12  // ``Environment variable names used by the utilities in the Shell and
    13  // Utilities volume of IEEE Std 1003.1-2001 consist solely of uppercase
    14  // letters, digits, and the '_' (underscore) from the characters defined in
    15  // Portable Character Set and do not begin with a digit. *But*, other
    16  // characters may be permitted by an implementation; applications shall
    17  // tolerate the presence of such names.''
    18  // -- http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html
    19  //
    20  // As of #16585, it's up to application inside docker to validate or not
    21  // environment variables, that's why we just strip leading whitespace and
    22  // nothing more.
    23  func ParseEnvFile(filename string) ([]string, error) {
    24  	fh, err := os.Open(filename)
    25  	if err != nil {
    26  		return []string{}, err
    27  	}
    28  	defer fh.Close()
    29  
    30  	lines := []string{}
    31  	scanner := bufio.NewScanner(fh)
    32  	for scanner.Scan() {
    33  		// trim the line from all leading whitespace first
    34  		line := strings.TrimLeft(scanner.Text(), whiteSpaces)
    35  		// line is not empty, and not starting with '#'
    36  		if len(line) > 0 && !strings.HasPrefix(line, "#") {
    37  			data := strings.SplitN(line, "=", 2)
    38  
    39  			// trim the front of a variable, but nothing else
    40  			variable := strings.TrimLeft(data[0], whiteSpaces)
    41  			if strings.ContainsAny(variable, whiteSpaces) {
    42  				return []string{}, ErrBadEnvVariable{fmt.Sprintf("variable '%s' has white spaces", variable)}
    43  			}
    44  
    45  			if len(data) > 1 {
    46  
    47  				// pass the value through, no trimming
    48  				lines = append(lines, fmt.Sprintf("%s=%s", variable, data[1]))
    49  			} else {
    50  				// if only a pass-through variable is given, clean it up.
    51  				lines = append(lines, fmt.Sprintf("%s=%s", strings.TrimSpace(line), os.Getenv(line)))
    52  			}
    53  		}
    54  	}
    55  	return lines, scanner.Err()
    56  }
    57  
    58  var whiteSpaces = " \t"
    59  
    60  // ErrBadEnvVariable typed error for bad environment variable
    61  type ErrBadEnvVariable struct {
    62  	msg string
    63  }
    64  
    65  func (e ErrBadEnvVariable) Error() string {
    66  	return fmt.Sprintf("poorly formatted environment: %s", e.msg)
    67  }