github.com/ddev/ddev@v1.23.2-0.20240519125000-d824ffe36ff3/pkg/ddevapp/envfile.go (about) 1 package ddevapp 2 3 import ( 4 "fmt" 5 "regexp" 6 "strings" 7 8 "github.com/ddev/ddev/pkg/fileutil" 9 "github.com/joho/godotenv" 10 ) 11 12 // ReadProjectEnvFile reads the .env in the project root into a envText and envMap 13 // The map has the envFile content, but without comments 14 func ReadProjectEnvFile(envFilePath string) (envMap map[string]string, envText string, err error) { 15 // envFilePath := filepath.Join(app.AppRoot, ".env") 16 envText, _ = fileutil.ReadFileIntoString(envFilePath) 17 envMap, err = godotenv.Read(envFilePath) 18 19 return envMap, envText, err 20 } 21 22 // WriteProjectEnvFile writes the passed envText into the project-root .env file 23 // with all items in envMap changed in envText there 24 func WriteProjectEnvFile(envFilePath string, envMap map[string]string, envText string) error { 25 // envFilePath := filepath.Join(app.AppRoot, ".env") 26 for k, v := range envMap { 27 // If the item is already in envText, use regex to replace it 28 // otherwise, append it to the envText. 29 // (^|[\r\n]+) - first group $1 matches the start of a line or newline characters 30 // #*\s* - matches optional comments with whitespaces, i.e. find lines like '# FOO=BAR' 31 // (%s) - second group $2 matches the variable name 32 exp := regexp.MustCompile(fmt.Sprintf(`(^|[\r\n]+)#*\s*(%s)=(.*)`, k)) 33 if exp.MatchString(envText) { 34 // Remove comments with whitespaces here using only $1 and $2 groups 35 envText = exp.ReplaceAllString(envText, fmt.Sprintf(`$1$2="%s"`, v)) 36 } else { 37 envText = strings.TrimSuffix(envText, "\n") 38 envText = fmt.Sprintf("%s\n%s=%s\n", envText, k, v) 39 } 40 } 41 err := fileutil.TemplateStringToFile(envText, nil, envFilePath) 42 if err != nil { 43 return err 44 } 45 return nil 46 }