#!/usr/bin/env python3 import sys import os import subprocess build = "go build -o ./bin/gostore ./cmd/gostore/main.go" build_dev = "go build -race -o " +\ "./bin_dev/gostore_dev ./cmd/gostore/main.go" def help() -> None: """Выводит справку по использованию""" s = """ СПРАВКА ./make.py ./make.py --help Выводит справку по использованию ./make.py build Сборка проекта ./make.py dev.run Отладка проекта ./make.py mod Обновление модулей/вендринга ./make.py test.run Тестирование ./make.py lint Запуск линтеров """ print(s) class TBuild: """Класс для сборки проекта""" def __init__(self): pass def run(self) -> None: print("Сборка проекта") os.system("go fmt ./...") t = TTest() t.run() linter = TLint() linter.run() os.system(build) os.system("strip -s ./bin/notify_service") os.system("upx -f ./bin/notify_service") os.system("cp -rf ./web ./bin") class TDev: """Класс для отладки проекта""" def __init__(self): pass def run(self) -> None: print("Сборка отладки проекта") print('Установка перменных окружения') os.unsetenv("STAGE") os.environ['STAGE'] = "local" print('Зачистка путей') os.system('rm -frd ./bin_dev') os.system('mkdir -p ./bin_dev/web') os.system('cp -r ./web ./bin_dev') os.system("go fmt ./...") os.system(build_dev) os.chdir('./bin_dev') os.system('./gostore_dev') class TMod: """Класс для обновления модулей""" def __init__(self): pass def run(self) -> None: print("Обновление модулей (режим совместимости с Go 1.22)") os.system("go get -u ./...") os.system("go mod tidy -compat=1.22.0") os.system("go mod vendor") os.system("go fmt ./...") class TTest: """Класс для тестирования""" def __init__(self): pass def run(self) -> None: print("Тестирование...") lst_cmd = ['go', 'test', '-shuffle=on', '-vet=all', '-race', '-timeout', '30s', '-coverprofile', 'cover.out', './...'] _result = subprocess.run( lst_cmd, stdout=subprocess.PIPE) result = _result.stdout.decode('utf-8') lst_cmd = ['go', 'tool', 'cover', '-func=cover.out'] _result_cover = subprocess.run( lst_cmd, stdout=subprocess.PIPE) result_cover = _result_cover.stdout.decode('utf-8') result += result_cover out = '' out += self.cover_packet(result) out += self.cover_func(result) out += self.control_fail(result) result = result.replace('\t', ' ') result = result.replace(' ', ' ') result = result.replace(' ', ' ') out = out.replace("\t", " ") out = out.replace(" ", " ") print(f'==========[ OUT ]==========\n{result}\n') total = self.cover_total(result_cover) if total < '85.0%': out += f'Слишком низкое прокрытие тестами({total})\n' print(f'==========[ ANALIZE ]==========\n{out}\n') if out != '': print('==========[ FINAL FAIL ]==========\n') print(f'Покрытие примерно: {total}') sys.exit(100) print('==========[ FINAL OK ]==========\n') print(f'Покрытие тестами: {total}') def cover_total(self, result_cover: str) -> str: """Проверяет, достаточный уровень покрытия тестами """ lst_cover = result_cover.split('\n') cover_total = lst_cover[-2] lst_cover = cover_total.split('\t') total = lst_cover[-1] return total def control_fail(self, result: str) -> str: """Проверяет, что тест провален """ lst_str = result.split('\n') out = '' for _str in lst_str: if 'FAIL' in _str: if _str == 'FAIL': continue out += 'TTest.control_fail(): тест провален' out += '\n'+_str+'\n\n' return out def cover_func(self, result: str) -> str: """Проверяет, что функция покрыта тестами """ lst_str = result.split('\n') out = '' for _str in lst_str: if ('%' in _str) and\ (_str.find('cover') == -1) and\ (_str.find('\t%v') == -1): substr1 = _str.split('\t')[-1] _s = substr1[:-1] if len(_s) > 2 and float(_s) < 40.0: out += 'TTest.cover_func(): функция плохо покрыта тестами' out += '\n'+_str+'\n\n' return out def cover_packet(self, result: str) -> str: """Проверяет, что пакет покрыт тестами """ lst_str = result.split('\n') out = '' for _str in lst_str: if '?' in _str: out += 'TTest.cover_packet(): пакет не покрыт тестами' out += '\n'+_str+'\n' return out class TLint: """Класс для запуска динтеров""" def __init__(self): pass def run(self) -> None: print("Проверка кода") os.system("go fmt ./...") os.system("golangci-lint run ./...") os.system("gocyclo -over 12 ./cmd/") os.system("gocyclo -over 12 ./internal/") os.system("gocyclo -over 12 ./pkg/") os.system("gosec ./...") if __name__ == '__main__': os.system("clear") args = sys.argv if len(args) < 2: help() sys.exit(1) cmd = args[1] if cmd == "help": help() sys.exit(2) elif cmd == "build": b = TBuild() b.run() elif cmd == "mod": m = TMod() m.run() elif cmd == "test.run": t = TTest() t.run() elif cmd == "lint": linter = TLint() linter.run() elif cmd == "dev.run": d = TDev() d.run() elif cmd == "": help() sys.exit(3) sys.exit(0)