mock_env.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. // package mock_env -- обеспечивает мок-окружение для тестов.
  2. package mock_env
  3. import (
  4. "os"
  5. "strings"
  6. "gitp78su.ipnodns.ru/svi/kern/v4/d0"
  7. "gitp78su.ipnodns.ru/svi/kern/v4/d0/helpers"
  8. )
  9. type IMockEnv interface {
  10. // Pwd -- возвращает текущий рабочий каталог процесса
  11. Pwd() *d0.LTxt
  12. }
  13. // MockEnv -- объект мок-окружения.
  14. type MockEnv struct {
  15. owner *d0.LOwner // Владелец мок-окружения
  16. dictEnv map[d0.Txt]*d0.LTxt // Словарь переменных окружения
  17. pwd *d0.LTxt // Текущий путь процесса
  18. fileName *d0.LTxt // Полный путь к .env файлу
  19. strEnv *d0.LTxt // Фактическое содержимое .env файла
  20. }
  21. // MakeEnv -- возвращает новое мок-окружение.
  22. func MakeEnv(owner *d0.LOwner) *MockEnv {
  23. sf := &MockEnv{
  24. owner: owner,
  25. dictEnv: map[d0.Txt]*d0.LTxt{},
  26. }
  27. sf.setPath()
  28. sf.readEnv()
  29. sf.parseEnv()
  30. sf.SetAll()
  31. return sf
  32. }
  33. // Парсит полученный текст .env для установки переменных окружения.
  34. func (sf *MockEnv) parseEnv() {
  35. lstStr := strings.SplitSeq(sf.strEnv.String(), "\n")
  36. for val := range lstStr {
  37. pair := strings.TrimSuffix(val, "\r")
  38. if pair == "" {
  39. continue
  40. }
  41. if strings.HasPrefix(val, "#") {
  42. continue
  43. }
  44. sf.parseEnvStr(d0.LetTxt(pair))
  45. }
  46. }
  47. // Парсит строку окружения.
  48. func (sf *MockEnv) parseEnvStr(pair *d0.LTxt) {
  49. lstPair := strings.Split(pair.String(), "=")
  50. d0.If(len(lstPair) < 2).Hassert("MockEnv.parseEnvStr(): pair(%v) not have =", []any{pair})
  51. key := lstPair[0]
  52. d0.If(key == "").Hassert("MockEnv.parseEnvStr(): in pair(%v) key is empty", []any{pair})
  53. lstVal := lstPair[1:]
  54. val := ""
  55. for _, val_ := range lstVal {
  56. val += val_ + "="
  57. }
  58. val = strings.TrimSuffix(val, "=")
  59. d0.If(val == "").Hassert("MockEnv.parseEnvStr(): in pair(%v) val is empty", []any{pair})
  60. sf.dictEnv[d0.Txt(key)] = d0.LetTxt(val)
  61. }
  62. // Читает файл переменных окружения.
  63. func (sf *MockEnv) readEnv() {
  64. binEnv, err := os.ReadFile(sf.fileName.String())
  65. d0.If(err != nil).
  66. Hassert("MockEnv.readEnv(): in read %v, err=\n\t%v", []any{sf.fileName,
  67. err})
  68. sf.strEnv = d0.LetTxt(d0.Txt(binEnv))
  69. }
  70. // Устанавливает текущий путь относительно проекта в dev.
  71. func (sf *MockEnv) setPath() {
  72. dir, err := os.Getwd()
  73. helpers.If(err != nil).Hassert("MockEnv.setPath(): in get PWD, err=\n\t%v", []any{err})
  74. lstDir := strings.Split(dir, "/")
  75. var pwd strings.Builder
  76. fileName := ""
  77. isFind := d0.Bool(false)
  78. for _, point := range lstDir {
  79. _, _ = pwd.WriteString(point + "/")
  80. fileName = pwd.String() + ".env"
  81. _, err := os.ReadFile(fileName)
  82. if err == nil {
  83. isFind = true
  84. break
  85. }
  86. }
  87. helpers.If(!isFind).Hassert("MockEnv.setPath(): not find file .env", []any{})
  88. sf.pwd = d0.LetTxt(pwd.String() + "/bin_dev/" + string(sf.owner.Name()))
  89. err = os.MkdirAll(sf.pwd.String(), 0750)
  90. helpers.If(err != nil).Hassert("MockEnv.setPath(): in create PWD, err=\n\t%v", []any{err})
  91. err = os.Chdir(sf.pwd.String())
  92. helpers.If(err != nil).Hassert("MockEnv.setPath(): in set cwd(%v), err=\n\t%v", []any{sf.pwd, err})
  93. sf.fileName = d0.LetTxt(fileName)
  94. }
  95. // Pwd -- возвращает текущий рабочий каталог процесса.
  96. func (sf *MockEnv) Pwd() *d0.LTxt {
  97. return sf.pwd
  98. }
  99. // SetAll -- поднимает все переменные окружения.
  100. func (sf *MockEnv) SetAll() {
  101. sf.ResetAll()
  102. for key, val := range sf.dictEnv {
  103. sf.Reset(d0.LetTxt("key"))
  104. err := os.Setenv(string(key), val.String())
  105. d0.If(err != nil).
  106. Hassert("MockEnv.SetAll(): in set env %v on key %v, err=\n\t%v",
  107. []any{key, val, err})
  108. }
  109. }
  110. // ResetAll -- сбрасывает все переменные окружения.
  111. func (sf *MockEnv) ResetAll() {
  112. for key := range sf.dictEnv {
  113. sf.Reset(d0.LetTxt(key))
  114. }
  115. }
  116. // Reset -- сбрасывает конкретный ключ.
  117. func (sf *MockEnv) Reset(key *d0.LTxt) {
  118. d0.If(key.Get() == "").
  119. Hassert("MockEnv.Reset(): key is empty",
  120. []any{})
  121. err := os.Unsetenv(key.String())
  122. d0.If(err != nil).
  123. Hassert("MockEnv.Reset(): in reset env %v, err=\n\t%v",
  124. []any{key, err})
  125. }