mirror of
https://github.com/hanzoai/pack.git
synced 2026-09-30 23:43:13 +00:00
* fix: drop empty env entries instead of keeping explicit empty values NAME= entries are now dropped from the environment entirely. Hosted builders pass every variable as NAME=value including empties, and BuildKit cannot mount an empty env secret, so keeping empty variables produced plans referencing secrets the builder never registers (failed to solve: secret X not found). Bare NAME entries still inherit from the process environment for local CLI use. NAME= must never inherit: variable names are user-controlled and would read values out of the build daemon's environment. * trim comments * docs: reword empty-value comment to describe behavior only * single-line comment
106 lines
2.6 KiB
Go
106 lines
2.6 KiB
Go
package app
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"regexp"
|
|
"strings"
|
|
)
|
|
|
|
type Environment struct {
|
|
Variables map[string]string
|
|
}
|
|
|
|
func NewEnvironment(variables *map[string]string) *Environment {
|
|
if variables == nil {
|
|
variables = &map[string]string{}
|
|
}
|
|
|
|
return &Environment{Variables: *variables}
|
|
}
|
|
|
|
// FromEnvs collects variables from the given environment variable names
|
|
func FromEnvs(envs []string) (*Environment, error) {
|
|
env := NewEnvironment(nil)
|
|
re := regexp.MustCompile(`(?s)([A-Za-z0-9_+\-]*)(?:=?)(.*)`)
|
|
|
|
for _, e := range envs {
|
|
matches := re.FindStringSubmatch(e)
|
|
if len(matches) < 3 {
|
|
continue
|
|
}
|
|
|
|
name := matches[1]
|
|
value := matches[2]
|
|
|
|
if value == "" {
|
|
// A bare NAME inherits from the process env; NAME= is skipped.
|
|
if !strings.Contains(e, "=") {
|
|
if v, ok := os.LookupEnv(name); ok {
|
|
env.SetVariable(name, v)
|
|
}
|
|
}
|
|
} else {
|
|
env.SetVariable(name, value)
|
|
}
|
|
}
|
|
|
|
return env, nil
|
|
}
|
|
|
|
// GetVariable returns the value of the given variable name
|
|
func (e *Environment) GetVariable(name string) string {
|
|
return e.Variables[name]
|
|
}
|
|
|
|
// SetVariable stores a variable in the Environment
|
|
func (e *Environment) SetVariable(name, value string) {
|
|
e.Variables[name] = value
|
|
}
|
|
|
|
// ConfigVariable returns the RAILPACK_ prefixed version of a variable name
|
|
func (e *Environment) ConfigVariable(name string) string {
|
|
return fmt.Sprintf("RAILPACK_%s", name)
|
|
}
|
|
|
|
// returns the value of a RAILPACK_ prefixed variable with newlines removed
|
|
// Returns both the value and the name of the config variable
|
|
func (e *Environment) GetConfigVariable(name string) (string, string) {
|
|
configVar := e.ConfigVariable(name)
|
|
|
|
if val, exists := e.Variables[configVar]; exists {
|
|
return strings.TrimSpace(val), configVar
|
|
}
|
|
return "", ""
|
|
}
|
|
|
|
// GetConfigVariableList returns a space-separated config variable as a list
|
|
// Returns both the list and the name of the config variable
|
|
func (e *Environment) GetConfigVariableList(name string) ([]string, string) {
|
|
val, configVar := e.GetConfigVariable(name)
|
|
if val == "" {
|
|
return nil, ""
|
|
}
|
|
return strings.Split(val, " "), configVar
|
|
}
|
|
|
|
// checks if a RAILPACK_ prefixed variable is set to "1" or "true"
|
|
func (e *Environment) IsConfigVariableTruthy(name string) bool {
|
|
if val, _ := e.GetConfigVariable(name); val != "" {
|
|
lowerVal := strings.ToLower(val)
|
|
return lowerVal == "1" || lowerVal == "true"
|
|
}
|
|
return false
|
|
}
|
|
|
|
// GetSecretsWithPrefix returns all secrets that have the given prefix
|
|
func (e *Environment) GetSecretsWithPrefix(prefix string) []string {
|
|
secrets := []string{}
|
|
for secretName := range e.Variables {
|
|
if strings.HasPrefix(secretName, prefix) {
|
|
secrets = append(secrets, secretName)
|
|
}
|
|
}
|
|
return secrets
|
|
}
|