make.py 6.5 KB

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