package mockenv import ( "fmt" "io/ioutil" "os" "strings" ) /* Мок-объект для инициализации переменных окружения */ var ( vars = []string{ "STAGE", } path, _ = os.Getwd() selfPath = `/wartank/` // Путь к своему проекту fileEnv = ".env" ) // MockEnv -- мок-объект для переменных окружения type MockEnv struct { dict map[string]string } // NewMockEnv -- возвращает новый *MockEnv func NewMockEnv() *MockEnv { сам := &MockEnv{ dict: make(map[string]string), } return сам } // InitFake -- инициализация фейковыми данными func (сам *MockEnv) InitFake() { сам.dict = make(map[string]string) i := 0 for _, var_ := range vars { os.Unsetenv(var_) strVal := fmt.Sprint(i) os.Setenv(var_, strVal) if var_ == "STAGE" { os.Unsetenv(var_) os.Setenv(var_, "local") } сам.dict[var_] = strVal i++ } } // InitLocal -- читает из локального окружения файл, заполняет переменные func (сам *MockEnv) InitLocal() error { strData, err := сам.readFile() if err != nil { return fmt.Errorf("MockEnv.InitLocal(): при чтении файла, err=\n\t%w", err) } dict, err := сам.getPairs(strData) if err != nil { return fmt.Errorf("MockEnv.InitLocal(): при получении пар ключ:значение, err=\n\t%w", err) } сам.initEnv(dict) сам.dict = dict сам.checkStage() return nil } // Проверяет наличие поля STAGE func (сам *MockEnv) checkStage() { stage, ok := сам.dict["STAGE"] if !ok { panic(fmt.Errorf("MockEnv.checkStage(): не установлена переменная STAGE")) } if stage != "local" { panic(fmt.Errorf("MockEnv.checkStage(): не локальное окружение, STAGE=%q", stage)) } } // Инициализирует все заданные переменные окружения func (сам *MockEnv) initEnv(mapEnv map[string]string) { // Здесь не должен быть nil НИКОГДА for key, value := range mapEnv { os.Unsetenv(key) os.Setenv(key, value) } } // Готовит словарь значений func (сам *MockEnv) getPairs(strData string) (map[string]string, error) { lstData := strings.Split(strData, "\n") mapEnv := make(map[string]string) for _, line := range lstData { if line == "" { continue } lstPart := strings.Split(line, `="`) if len(lstPart) != 2 { return nil, fmt.Errorf("MockEnv.getPairs(): в параметре %q неправильный формат", line) } key := lstPart[0] if key == "" { return nil, fmt.Errorf("MockEnv.getPairs(): пустой ключ в строке %q", line) } value := lstPart[1] value = value[:len(value)-1] if value == "" { return nil, fmt.Errorf("MockEnv.getPairs(): пустое значение в строке %q", line) } mapEnv[key] = value } if len(mapEnv) == 0 { return nil, fmt.Errorf("MockEnv.getPairs(): len dict == 0") } return mapEnv, nil } // Читает файл окружения func (сам *MockEnv) readFile() (string, error) { if !strings.Contains(path, selfPath) { return "", fmt.Errorf("MockEnv.readFile(): неправильный путь проекта") } pt := path lstPath := strings.Split(pt, selfPath) if len(lstPath) != 2 { return "", fmt.Errorf("MockEnv.readFile(): плохой путь к файлу окружения %q", path) } pt = lstPath[0] fileName := pt + selfPath + fileEnv binData, err := ioutil.ReadFile(fileName) if err != nil { return "", fmt.Errorf("MockEnv.readFile(): при чтении файла %q .env, err=%w", fileName, err) } return string(binData), nil } // Unset -- удаляет все переменные окружения сервиса func (сам *MockEnv) Unset() { for key := range сам.dict { os.Unsetenv(key) } }