podman

Форк
0
/
env.go 
122 строки · 2.9 Кб
1
// Package for processing environment variables.
2
package env
3

4
// TODO: we need to add tests for this package.
5

6
import (
7
	"bufio"
8
	"fmt"
9
	"os"
10
	"strings"
11

12
	"golang.org/x/exp/maps"
13
)
14

15
const whiteSpaces = " \t"
16

17
// DefaultEnvVariables returns a default environment, with $PATH and $TERM set.
18
func DefaultEnvVariables() map[string]string {
19
	return map[string]string{
20
		"PATH":      "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
21
		"container": "podman",
22
	}
23
}
24

25
// Slice transforms the specified map of environment variables into a
26
// slice. If a value is non-empty, the key and value are joined with '='.
27
func Slice(m map[string]string) []string {
28
	env := make([]string, 0, len(m))
29
	for k, v := range m {
30
		var s string
31
		if len(v) > 0 {
32
			s = fmt.Sprintf("%s=%s", k, v)
33
		} else {
34
			s = k
35
		}
36
		env = append(env, s)
37
	}
38
	return env
39
}
40

41
// Map transforms the specified slice of environment variables into a
42
// map.
43
func Map(slice []string) map[string]string {
44
	envmap := make(map[string]string, len(slice))
45
	for _, line := range slice {
46
		key, val, _ := strings.Cut(line, "=")
47
		envmap[key] = val
48
	}
49
	return envmap
50
}
51

52
// Join joins the two environment maps with override overriding base.
53
func Join(base map[string]string, override map[string]string) map[string]string {
54
	if len(base) == 0 {
55
		return maps.Clone(override)
56
	}
57
	base = maps.Clone(base)
58
	for k, v := range override {
59
		base[k] = v
60
	}
61
	return base
62
}
63

64
// ParseFile parses the specified path for environment variables and returns them
65
// as a map.
66
func ParseFile(path string) (_ map[string]string, err error) {
67
	env := make(map[string]string)
68
	defer func() {
69
		if err != nil {
70
			err = fmt.Errorf("parsing file %q: %w", path, err)
71
		}
72
	}()
73

74
	fh, err := os.Open(path)
75
	if err != nil {
76
		return nil, err
77
	}
78
	defer fh.Close()
79

80
	scanner := bufio.NewScanner(fh)
81
	for scanner.Scan() {
82
		// trim the line from all leading whitespace first
83
		line := strings.TrimLeft(scanner.Text(), whiteSpaces)
84
		// line is not empty, and not starting with '#'
85
		if len(line) > 0 && !strings.HasPrefix(line, "#") {
86
			if err := parseEnv(env, line); err != nil {
87
				return nil, err
88
			}
89
		}
90
	}
91
	return env, scanner.Err()
92
}
93

94
func parseEnv(env map[string]string, line string) error {
95
	key, val, hasVal := strings.Cut(line, "=")
96

97
	// catch invalid variables such as "=" or "=A"
98
	if key == "" {
99
		return fmt.Errorf("invalid variable: %q", line)
100
	}
101
	// trim the front of a variable, but nothing else
102
	name := strings.TrimLeft(key, whiteSpaces)
103
	if hasVal {
104
		env[name] = val
105
	} else {
106
		if name, hasStar := strings.CutSuffix(name, "*"); hasStar {
107
			for _, e := range os.Environ() {
108
				envKey, envVal, hasEq := strings.Cut(e, "=")
109
				if !hasEq {
110
					continue
111
				}
112
				if strings.HasPrefix(envKey, name) {
113
					env[envKey] = envVal
114
				}
115
			}
116
		} else if val, ok := os.LookupEnv(name); ok {
117
			// if only a pass-through variable is given, clean it up.
118
			env[name] = val
119
		}
120
	}
121
	return nil
122
}
123

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.