Revert "Upgrade to go 1.19 and update dependencies (#3069)" (#3085)

This reverts commit bba7c23957.
This commit is contained in:
WithoutPants
2022-11-07 12:33:15 +11:00
committed by GitHub
parent bba7c23957
commit 2609095c7a
939 changed files with 43785 additions and 101302 deletions

View File

@@ -1,4 +1,3 @@
*.test
*.out
annotate.json
profile.cov

View File

@@ -1,7 +0,0 @@
# Options for analysis running.
run:
timeout: 1m
linters-settings:
gofmt:
simplify: true

10
vendor/github.com/subosito/gotenv/.travis.yml generated vendored Normal file
View File

@@ -0,0 +1,10 @@
language: go
go:
- 1.x
os:
- linux
- osx
script:
- go test -test.v -coverprofile=coverage.out -covermode=count
after_success:
- bash <(curl -s https://codecov.io/bash)

View File

@@ -1,26 +1,5 @@
# Changelog
## [1.4.0] - 2022-06-02
### Added
- Add `Marshal` and `Unmarshal` helpers
### Changed
- The CI will now run a linter and the tests on PRs.
## [1.3.0] - 2022-05-23
### Added
- Support = within double-quoted strings
- Add support for multiline values
### Changed
- `OverLoad` prefer environment variables over local variables
## [1.2.0] - 2019-08-03
### Added
@@ -51,7 +30,7 @@
### Added
- Supports carriage return in env
- Handle files with UTF-8 BOM
- Handle files with UTF-8 BOM
### Changed

View File

@@ -1,11 +1,12 @@
# gotenv
[![Build Status](https://github.com/subosito/gotenv/workflows/Go%20workflow/badge.svg)](https://github.com/subosito/gotenv/actions)
[![Build Status](https://travis-ci.org/subosito/gotenv.svg?branch=master)](https://travis-ci.org/subosito/gotenv)
[![Build status](https://ci.appveyor.com/api/projects/status/wb2e075xkfl0m0v2/branch/master?svg=true)](https://ci.appveyor.com/project/subosito/gotenv/branch/master)
[![Coverage Status](https://badgen.net/codecov/c/github/subosito/gotenv)](https://codecov.io/gh/subosito/gotenv)
[![Go Report Card](https://goreportcard.com/badge/github.com/subosito/gotenv)](https://goreportcard.com/report/github.com/subosito/gotenv)
[![GoDoc](https://godoc.org/github.com/subosito/gotenv?status.svg)](https://godoc.org/github.com/subosito/gotenv)
Load environment variables from `.env` or `io.Reader` in Go.
Load environment variables dynamically in Go.
## Usage
@@ -28,7 +29,7 @@ Once loaded you can use `os.Getenv()` to get the value of the variable.
Let's say you have `.env` file:
```sh
```
APP_ID=1234567
APP_SECRET=abcdef
```
@@ -78,6 +79,7 @@ Besides above functions, `gotenv` also provides another functions that overrides
- `gotenv.OverLoad`
- `gotenv.OverApply`
Here's the example of this overrides behavior:
```go
@@ -118,7 +120,7 @@ Just in case you want to parse environment variables from any `io.Reader`, goten
pairs := gotenv.Parse(strings.NewReader("FOO=test\nBAR=$FOO"))
// gotenv.Env{"FOO": "test", "BAR": "test"}
pairs, err := gotenv.StrictParse(strings.NewReader(`FOO="bar"`))
err, pairs = gotenv.StrictParse(strings.NewReader(`FOO="bar"`))
// gotenv.Env{"FOO": "bar"}
```

9
vendor/github.com/subosito/gotenv/appveyor.yml generated vendored Normal file
View File

@@ -0,0 +1,9 @@
build: off
clone_folder: c:\gopath\src\github.com\subosito\gotenv
environment:
GOPATH: c:\gopath
stack: go 1.10
before_test:
- go get -t
test_script:
- go test -v -cover -race

View File

@@ -6,10 +6,7 @@ import (
"fmt"
"io"
"os"
"path/filepath"
"regexp"
"sort"
"strconv"
"strings"
)
@@ -19,39 +16,46 @@ const (
// Pattern for detecting valid variable within a value
variablePattern = `(\\)?(\$)(\{?([A-Z0-9_]+)?\}?)`
// Byte order mark character
bom = "\xef\xbb\xbf"
)
// Env holds key/value pair of valid environment variable
type Env map[string]string
// Load is a function to load a file or multiple files and then export the valid variables into environment variables if they do not exist.
// When it's called with no argument, it will load `.env` file on the current path and set the environment variables.
// Otherwise, it will loop over the filenames parameter and set the proper environment variables.
/*
Load is a function to load a file or multiple files and then export the valid variables into environment variables if they do not exist.
When it's called with no argument, it will load `.env` file on the current path and set the environment variables.
Otherwise, it will loop over the filenames parameter and set the proper environment variables.
*/
func Load(filenames ...string) error {
return loadenv(false, filenames...)
}
// OverLoad is a function to load a file or multiple files and then export and override the valid variables into environment variables.
/*
OverLoad is a function to load a file or multiple files and then export and override the valid variables into environment variables.
*/
func OverLoad(filenames ...string) error {
return loadenv(true, filenames...)
}
// Must is wrapper function that will panic when supplied function returns an error.
/*
Must is wrapper function that will panic when supplied function returns an error.
*/
func Must(fn func(filenames ...string) error, filenames ...string) {
if err := fn(filenames...); err != nil {
panic(err.Error())
}
}
// Apply is a function to load an io Reader then export the valid variables into environment variables if they do not exist.
/*
Apply is a function to load an io Reader then export the valid variables into environment variables if they do not exist.
*/
func Apply(r io.Reader) error {
return parset(r, false)
}
// OverApply is a function to load an io Reader then export and override the valid variables into environment variables.
/*
OverApply is a function to load an io Reader then export and override the valid variables into environment variables.
*/
func OverApply(r io.Reader) error {
return parset(r, true)
}
@@ -68,10 +72,11 @@ func loadenv(override bool, filenames ...string) error {
}
err = parset(f, override)
f.Close()
if err != nil {
return err
}
f.Close()
}
return nil
@@ -79,7 +84,7 @@ func loadenv(override bool, filenames ...string) error {
// parse and set :)
func parset(r io.Reader, override bool) error {
env, err := strictParse(r, override)
env, err := StrictParse(r)
if err != nil {
return err
}
@@ -105,7 +110,7 @@ func setenv(key, val string, override bool) {
// It expands the value of a variable from the environment variable but does not set the value to the environment itself.
// This function is skipping any invalid lines and only processing the valid one.
func Parse(r io.Reader) Env {
env, _ := strictParse(r, false)
env, _ := StrictParse(r)
return env
}
@@ -113,123 +118,22 @@ func Parse(r io.Reader) Env {
// It expands the value of a variable from the environment variable but does not set the value to the environment itself.
// This function is returning an error if there are any invalid lines.
func StrictParse(r io.Reader) (Env, error) {
return strictParse(r, false)
}
// Read is a function to parse a file line by line and returns the valid Env key/value pair of valid variables.
// It expands the value of a variable from the environment variable but does not set the value to the environment itself.
// This function is skipping any invalid lines and only processing the valid one.
func Read(filename string) (Env, error) {
f, err := os.Open(filename)
if err != nil {
return nil, err
}
defer f.Close()
return strictParse(f, false)
}
// Unmarshal reads a string line by line and returns the valid Env key/value pair of valid variables.
// It expands the value of a variable from the environment variable but does not set the value to the environment itself.
// This function is returning an error if there are any invalid lines.
func Unmarshal(str string) (Env, error) {
return strictParse(strings.NewReader(str), false)
}
// Marshal outputs the given environment as a env file.
// Variables will be sorted by name.
func Marshal(env Env) (string, error) {
lines := make([]string, 0, len(env))
for k, v := range env {
if d, err := strconv.Atoi(v); err == nil {
lines = append(lines, fmt.Sprintf(`%s=%d`, k, d))
} else {
lines = append(lines, fmt.Sprintf(`%s=%q`, k, v))
}
}
sort.Strings(lines)
return strings.Join(lines, "\n"), nil
}
// Write serializes the given environment and writes it to a file
func Write(env Env, filename string) error {
content, err := Marshal(env)
if err != nil {
return err
}
// ensure the path exists
if err := os.MkdirAll(filepath.Dir(filename), 0o775); err != nil {
return err
}
// create or truncate the file
file, err := os.Create(filename)
if err != nil {
return err
}
defer file.Close()
_, err = file.WriteString(content + "\n")
if err != nil {
return err
}
return file.Sync()
}
func strictParse(r io.Reader, override bool) (Env, error) {
env := make(Env)
scanner := bufio.NewScanner(r)
firstLine := true
i := 1
bom := string([]byte{239, 187, 191})
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
line := scanner.Text()
if firstLine {
if i == 1 {
line = strings.TrimPrefix(line, bom)
firstLine = false
}
if line == "" || line[0] == '#' {
continue
}
i++
quote := ""
// look for the delimiter character
idx := strings.Index(line, "=")
if idx == -1 {
idx = strings.Index(line, ":")
}
// look for a quote character
if idx > 0 && idx < len(line)-1 {
val := strings.TrimSpace(line[idx+1:])
if val[0] == '"' || val[0] == '\'' {
quote = val[:1]
// look for the closing quote character within the same line
idx = strings.LastIndex(strings.TrimSpace(val[1:]), quote)
if idx >= 0 && val[idx] != '\\' {
quote = ""
}
}
}
// look for the closing quote character
for quote != "" && scanner.Scan() {
l := scanner.Text()
line += "\n" + l
idx := strings.LastIndex(l, quote)
if idx > 0 && l[idx-1] == '\\' {
// foud a matching quote character but it's escaped
continue
}
if idx >= 0 {
// foud a matching quote
quote = ""
}
}
if quote != "" {
return env, fmt.Errorf("missing quotes")
}
err := parseLine(line, env, override)
err := parseLine(line, env)
if err != nil {
return env, err
}
@@ -238,54 +142,47 @@ func strictParse(r io.Reader, override bool) (Env, error) {
return env, nil
}
var (
lineRgx = regexp.MustCompile(linePattern)
unescapeRgx = regexp.MustCompile(`\\([^$])`)
varRgx = regexp.MustCompile(variablePattern)
)
func parseLine(s string, env Env, override bool) error {
rm := lineRgx.FindStringSubmatch(s)
func parseLine(s string, env Env) error {
rl := regexp.MustCompile(linePattern)
rm := rl.FindStringSubmatch(s)
if len(rm) == 0 {
return checkFormat(s, env)
}
key := strings.TrimSpace(rm[1])
val := strings.TrimSpace(rm[2])
key := rm[1]
val := rm[2]
var hsq, hdq bool
// determine if string has quote prefix
hdq := strings.HasPrefix(val, `"`)
// check if the value is quoted
if l := len(val); l >= 2 {
l -= 1
// has double quotes
hdq = val[0] == '"' && val[l] == '"'
// has single quotes
hsq = val[0] == '\'' && val[l] == '\''
// determine if string has single quote prefix
hsq := strings.HasPrefix(val, `'`)
// remove quotes '' or ""
if hsq || hdq {
val = val[1:l]
}
}
// trim whitespace
val = strings.Trim(val, " ")
// remove quotes '' or ""
rq := regexp.MustCompile(`\A(['"])(.*)(['"])\z`)
val = rq.ReplaceAllString(val, "$2")
if hdq {
val = strings.ReplaceAll(val, `\n`, "\n")
val = strings.ReplaceAll(val, `\r`, "\r")
val = strings.Replace(val, `\n`, "\n", -1)
val = strings.Replace(val, `\r`, "\r", -1)
// Unescape all characters except $ so variables can be escaped properly
val = unescapeRgx.ReplaceAllString(val, "$1")
re := regexp.MustCompile(`\\([^$])`)
val = re.ReplaceAllString(val, "$1")
}
if !hsq {
fv := func(s string) string {
return varReplacement(s, hsq, env, override)
}
val = varRgx.ReplaceAllStringFunc(val, fv)
val = parseVal(val, env, hdq, override)
rv := regexp.MustCompile(variablePattern)
fv := func(s string) string {
return varReplacement(s, hsq, env)
}
val = rv.ReplaceAllStringFunc(val, fv)
val = parseVal(val, env)
env[key] = val
return nil
}
@@ -304,23 +201,18 @@ func parseExport(st string, env Env) error {
return nil
}
var varNameRgx = regexp.MustCompile(`(\$)(\{?([A-Z0-9_]+)\}?)`)
func varReplacement(s string, hsq bool, env Env, override bool) string {
if s == "" {
return s
}
if s[0] == '\\' {
// the dollar sign is escaped
return s[1:]
func varReplacement(s string, hsq bool, env Env) string {
if strings.HasPrefix(s, "\\") {
return strings.TrimPrefix(s, "\\")
}
if hsq {
return s
}
mn := varNameRgx.FindStringSubmatch(s)
sn := `(\$)(\{?([A-Z0-9_]+)\}?)`
rn := regexp.MustCompile(sn)
mn := rn.FindStringSubmatch(s)
if len(mn) == 0 {
return s
@@ -328,21 +220,18 @@ func varReplacement(s string, hsq bool, env Env, override bool) string {
v := mn[3]
if replace, ok := os.LookupEnv(v); ok && !override {
return replace
replace, ok := env[v]
if !ok {
replace = os.Getenv(v)
}
if replace, ok := env[v]; ok {
return replace
}
return os.Getenv(v)
return replace
}
func checkFormat(s string, env Env) error {
st := strings.TrimSpace(s)
if st == "" || st[0] == '#' {
if (st == "") || strings.HasPrefix(st, "#") {
return nil
}
@@ -353,14 +242,21 @@ func checkFormat(s string, env Env) error {
return fmt.Errorf("line `%s` doesn't match format", s)
}
func parseVal(val string, env Env, ignoreNewlines bool, override bool) string {
if strings.Contains(val, "=") && !ignoreNewlines {
kv := strings.Split(val, "\r")
func parseVal(val string, env Env) string {
if strings.Contains(val, "=") {
if !(val == "\n" || val == "\r") {
kv := strings.Split(val, "\n")
if len(kv) > 1 {
val = kv[0]
for _, l := range kv[1:] {
_ = parseLine(l, env, override)
if len(kv) == 1 {
kv = strings.Split(val, "\r")
}
if len(kv) > 1 {
val = kv[0]
for i := 1; i < len(kv); i++ {
parseLine(kv[i], env)
}
}
}
}