github.com/nektos/act@v0.2.83/pkg/container/parse_env_file.go (about)

     1  package container
     2  
     3  import (
     4  	"archive/tar"
     5  	"bufio"
     6  	"context"
     7  	"fmt"
     8  	"io"
     9  	"strings"
    10  
    11  	"github.com/nektos/act/pkg/common"
    12  )
    13  
    14  func parseEnvFile(e Container, srcPath string, env *map[string]string) common.Executor {
    15  	localEnv := *env
    16  	return func(ctx context.Context) error {
    17  		envTar, err := e.GetContainerArchive(ctx, srcPath)
    18  		if err != nil {
    19  			return nil
    20  		}
    21  		defer envTar.Close()
    22  		reader := tar.NewReader(envTar)
    23  		_, err = reader.Next()
    24  		if err != nil && err != io.EOF {
    25  			return err
    26  		}
    27  		s := bufio.NewScanner(reader)
    28  		s.Buffer(nil, 1024*1024*1024) // increase buffer to 1GB to avoid scanner buffer overflow
    29  		firstLine := true
    30  		for s.Scan() {
    31  			line := s.Text()
    32  			if firstLine {
    33  				firstLine = false
    34  				// skip utf8 bom, powershell 5 legacy uses it for utf8
    35  				if len(line) >= 3 && line[0] == 239 && line[1] == 187 && line[2] == 191 {
    36  					line = line[3:]
    37  				}
    38  			}
    39  			singleLineEnv := strings.Index(line, "=")
    40  			multiLineEnv := strings.Index(line, "<<")
    41  			if singleLineEnv != -1 && (multiLineEnv == -1 || singleLineEnv < multiLineEnv) {
    42  				localEnv[line[:singleLineEnv]] = line[singleLineEnv+1:]
    43  			} else if multiLineEnv != -1 {
    44  				multiLineEnvContent := ""
    45  				multiLineEnvDelimiter := line[multiLineEnv+2:]
    46  				delimiterFound := false
    47  				for s.Scan() {
    48  					content := s.Text()
    49  					if content == multiLineEnvDelimiter {
    50  						delimiterFound = true
    51  						break
    52  					}
    53  					if multiLineEnvContent != "" {
    54  						multiLineEnvContent += "\n"
    55  					}
    56  					multiLineEnvContent += content
    57  				}
    58  				if !delimiterFound {
    59  					return fmt.Errorf("invalid format delimiter '%v' not found before end of file", multiLineEnvDelimiter)
    60  				}
    61  				localEnv[line[:multiLineEnv]] = multiLineEnvContent
    62  			} else {
    63  				return fmt.Errorf("invalid format '%v', expected a line with '=' or '<<'", line)
    64  			}
    65  		}
    66  		env = &localEnv
    67  		return s.Err()
    68  	}
    69  }