make.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. #!/usr/bin/env python3
  2. import sys
  3. import os
  4. import subprocess
  5. build = "go build -o ./bin/gostore ./cmd/gostore/main.go"
  6. build_dev = "go build -race -o " +\
  7. "./bin_dev/gostore_dev ./cmd/gostore/main.go"
  8. def help() -> None:
  9. """Выводит справку по использованию"""
  10. s = """
  11. СПРАВКА
  12. ./make.py
  13. ./make.py --help
  14. Выводит справку по использованию
  15. ./make.py build
  16. Сборка проекта
  17. ./make.py dev.run
  18. Отладка проекта
  19. ./make.py mod
  20. Обновление модулей/вендринга
  21. ./make.py test.run
  22. Тестирование
  23. ./make.py lint
  24. Запуск линтеров
  25. """
  26. print(s)
  27. class TBuild:
  28. """Класс для сборки проекта"""
  29. def __init__(self):
  30. pass
  31. def run(self) -> None:
  32. print("Сборка проекта")
  33. os.system("go fmt ./...")
  34. t = TTest()
  35. t.run()
  36. linter = TLint()
  37. linter.run()
  38. os.system(build)
  39. os.system("strip -s ./bin/notify_service")
  40. os.system("upx -f ./bin/notify_service")
  41. os.system("cp -rf ./web ./bin")
  42. class TDev:
  43. """Класс для отладки проекта"""
  44. def __init__(self):
  45. pass
  46. def run(self) -> None:
  47. print("Сборка отладки проекта")
  48. print('Установка перменных окружения')
  49. os.unsetenv("STAGE")
  50. os.environ['STAGE'] = "local"
  51. print('Зачистка путей')
  52. os.system('rm -frd ./bin_dev')
  53. os.system('mkdir -p ./bin_dev/web')
  54. os.system('cp -r ./web ./bin_dev')
  55. os.system("go fmt ./...")
  56. os.system(build_dev)
  57. os.chdir('./bin_dev')
  58. os.system('./gostore_dev')
  59. class TMod:
  60. """Класс для обновления модулей"""
  61. def __init__(self):
  62. pass
  63. def run(self) -> None:
  64. print("Обновление модулей (режим совместимости с Go 1.22)")
  65. os.system("go get -u ./...")
  66. os.system("go mod tidy -compat=1.22.0")
  67. os.system("go mod vendor")
  68. os.system("go fmt ./...")
  69. class TTest:
  70. """Класс для тестирования"""
  71. def __init__(self):
  72. pass
  73. def run(self) -> None:
  74. print("Тестирование...")
  75. lst_cmd = ['go', 'test', '-shuffle=on', '-vet=all',
  76. '-race', '-timeout', '30s', '-coverprofile',
  77. 'cover.out', './...']
  78. _result = subprocess.run(
  79. lst_cmd, stdout=subprocess.PIPE)
  80. result = _result.stdout.decode('utf-8')
  81. lst_cmd = ['go', 'tool', 'cover', '-func=cover.out']
  82. _result_cover = subprocess.run(
  83. lst_cmd, stdout=subprocess.PIPE)
  84. result_cover = _result_cover.stdout.decode('utf-8')
  85. result += result_cover
  86. out = ''
  87. out += self.cover_packet(result)
  88. out += self.cover_func(result)
  89. out += self.control_fail(result)
  90. result = result.replace('\t', ' ')
  91. result = result.replace(' ', ' ')
  92. result = result.replace(' ', ' ')
  93. out = out.replace("\t", " ")
  94. out = out.replace(" ", " ")
  95. print(f'==========[ OUT ]==========\n{result}\n')
  96. total = self.cover_total(result_cover)
  97. if total < '85.0%':
  98. out += f'Слишком низкое прокрытие тестами({total})\n'
  99. print(f'==========[ ANALIZE ]==========\n{out}\n')
  100. if out != '':
  101. print('==========[ FINAL FAIL ]==========\n')
  102. print(f'Покрытие примерно: {total}')
  103. sys.exit(100)
  104. print('==========[ FINAL OK ]==========\n')
  105. print(f'Покрытие тестами: {total}')
  106. def cover_total(self, result_cover: str) -> str:
  107. """Проверяет, достаточный уровень покрытия тестами
  108. """
  109. lst_cover = result_cover.split('\n')
  110. cover_total = lst_cover[-2]
  111. lst_cover = cover_total.split('\t')
  112. total = lst_cover[-1]
  113. return total
  114. def control_fail(self, result: str) -> str:
  115. """Проверяет, что тест провален
  116. """
  117. lst_str = result.split('\n')
  118. out = ''
  119. for _str in lst_str:
  120. if 'FAIL' in _str:
  121. if _str == 'FAIL':
  122. continue
  123. out += 'TTest.control_fail(): тест провален'
  124. out += '\n'+_str+'\n\n'
  125. return out
  126. def cover_func(self, result: str) -> str:
  127. """Проверяет, что функция покрыта тестами
  128. """
  129. lst_str = result.split('\n')
  130. out = ''
  131. for _str in lst_str:
  132. if ('%' in _str) and\
  133. (_str.find('cover') == -1) and\
  134. (_str.find('\t%v') == -1):
  135. substr1 = _str.split('\t')[-1]
  136. _s = substr1[:-1]
  137. if len(_s) > 2 and float(_s) < 40.0:
  138. out += 'TTest.cover_func(): функция плохо покрыта тестами'
  139. out += '\n'+_str+'\n\n'
  140. return out
  141. def cover_packet(self, result: str) -> str:
  142. """Проверяет, что пакет покрыт тестами
  143. """
  144. lst_str = result.split('\n')
  145. out = ''
  146. for _str in lst_str:
  147. if '?' in _str:
  148. out += 'TTest.cover_packet(): пакет не покрыт тестами'
  149. out += '\n'+_str+'\n'
  150. return out
  151. class TLint:
  152. """Класс для запуска динтеров"""
  153. def __init__(self):
  154. pass
  155. def run(self) -> None:
  156. print("Проверка кода")
  157. os.system("go fmt ./...")
  158. os.system("golangci-lint run ./...")
  159. os.system("gocyclo -over 12 ./cmd/")
  160. os.system("gocyclo -over 12 ./internal/")
  161. os.system("gocyclo -over 12 ./pkg/")
  162. os.system("gosec ./...")
  163. if __name__ == '__main__':
  164. os.system("clear")
  165. args = sys.argv
  166. if len(args) < 2:
  167. help()
  168. sys.exit(1)
  169. cmd = args[1]
  170. if cmd == "help":
  171. help()
  172. sys.exit(2)
  173. elif cmd == "build":
  174. b = TBuild()
  175. b.run()
  176. elif cmd == "mod":
  177. m = TMod()
  178. m.run()
  179. elif cmd == "test.run":
  180. t = TTest()
  181. t.run()
  182. elif cmd == "lint":
  183. linter = TLint()
  184. linter.run()
  185. elif cmd == "dev.run":
  186. d = TDev()
  187. d.run()
  188. elif cmd == "":
  189. help()
  190. sys.exit(3)
  191. sys.exit(0)