refac: removed 7 direct and 12 indirect go modules for custom code instead

This commit is contained in:
Florian Sylvain committed 2026-10-21 23:13:46 +02:00
1 parent cfcf108488
commit c68e9a7858
73 files changed
+2455 -428

No files matched your search

+142
View File
@@ -0,0 +1,142 @@
package config
import (
"bufio"
"fmt"
"io"
"os"
"strings"
)
const (
dotenvExportPrefix = "export "
dotenvCommentMarker = "#"
dotenvInlineComment = " #"
dotenvByteOrderMark = "\xef\xbb\xbf"
dotenvMaxLineBytes = 1 << 20
dotenvAssignment = "="
dotenvDoubleQuote = '"'
dotenvSingleQuote = '\''
dotenvEscapeBackslash = '\\'
)
var dotenvDoubleQuoteEscapes = map[byte]byte{
'n': '\n',
'r': '\r',
't': '\t',
'"': '"',
'\\': '\\',
}
func LoadDotenv(path string) error {
file, err := os.Open(path)
if err != nil {
return err
}
defer func() { _ = file.Close() }()
values, err := ParseDotenv(file)
if err != nil {
return fmt.Errorf("%s: %w", path, err)
}
for name, value := range values {
if _, isSet := os.LookupEnv(name); !isSet {
if err := os.Setenv(name, value); err != nil {
return err
}
}
}
return nil
}
func ParseDotenv(reader io.Reader) (map[string]string, error) {
scanner := bufio.NewScanner(reader)
scanner.Buffer(make([]byte, 0, bufio.MaxScanTokenSize), dotenvMaxLineBytes)
values := map[string]string{}
for lineNumber := 1; scanner.Scan(); lineNumber++ {
line := strings.TrimSpace(strings.TrimPrefix(scanner.Text(), dotenvByteOrderMark))
if line == "" || strings.HasPrefix(line, dotenvCommentMarker) {
continue
}
name, value, err := parseDotenvAssignment(line)
if err != nil {
return nil, fmt.Errorf("line %d: %w", lineNumber, err)
}
values[name] = value
}
return values, scanner.Err()
}
func parseDotenvAssignment(line string) (string, string, error) {
line = strings.TrimSpace(strings.TrimPrefix(line, dotenvExportPrefix))
name, raw, found := strings.Cut(line, dotenvAssignment)
name = strings.TrimSpace(name)
if !found || !isDotenvName(name) {
return "", "", fmt.Errorf("expected NAME=value")
}
value, err := parseDotenvValue(strings.TrimSpace(raw))
return name, value, err
}
func isDotenvName(name string) bool {
if name == "" {
return false
}
for _, r := range name {
isLetter := r >= 'a' && r <= 'z' || r >= 'A' && r <= 'Z'
isDigit := r >= '0' && r <= '9'
if !isLetter && !isDigit && r != '_' && r != '.' {
return false
}
}
return true
}
func parseDotenvValue(raw string) (string, error) {
if raw == "" {
return "", nil
}
switch raw[0] {
case dotenvDoubleQuote:
return parseDoubleQuoted(raw)
case dotenvSingleQuote:
return parseSingleQuoted(raw)
}
if comment := strings.Index(raw, dotenvInlineComment); comment >= 0 {
raw = raw[:comment]
}
return strings.TrimSpace(raw), nil
}
func parseSingleQuoted(raw string) (string, error) {
end := strings.IndexByte(raw[1:], dotenvSingleQuote)
if end < 0 {
return "", fmt.Errorf("unterminated single quote")
}
return raw[1 : 1+end], nil
}
func parseDoubleQuoted(raw string) (string, error) {
var value strings.Builder
for i := 1; i < len(raw); i++ {
switch raw[i] {
case dotenvDoubleQuote:
return value.String(), nil
case dotenvEscapeBackslash:
i++
if i >= len(raw) {
return "", fmt.Errorf("unterminated double quote")
}
if unescaped, known := dotenvDoubleQuoteEscapes[raw[i]]; known {
value.WriteByte(unescaped)
} else {
value.WriteByte(dotenvEscapeBackslash)
value.WriteByte(raw[i])
}
default:
value.WriteByte(raw[i])
}
}
return "", fmt.Errorf("unterminated double quote")
}