Passed
Push — main ( 9a8ae7...547f28 )
by Andreas
01:18
created

builder.BuildConfig.__init__()   A

Complexity

Conditions 3

Size

Total Lines 26
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 19
nop 2
dl 0
loc 26
rs 9.45
c 0
b 0
f 0
1
"""Сборщик Python программ в исполняемые файлы Windows."""
2
# pylint: disable=import-error
3
# Какой-то баг линтера гитхаб с yaml
4
from __future__ import annotations
5
import zipfile
6
from os import path
7
from os import system as run_cmd
8
from sys import argv
9
from sys import exit as sysexit
10
from datetime import datetime
11
from yaml import full_load as loadyaml
12
from functions.log import Log
13
# from functions.man import manpage as man
14
15
class BuildConfig:
16
    """Класс динамической конфигурации
17
    """
18
    # pylint: disable=too-many-instance-attributes
19
    # Может быть будет оптимизировано. А может и нет.
20
    def __init__(self, build_config: str = 'configs/config.yaml') -> None:
21
        # Тут нужно точно сделать оптимальнее
22
        config_file = f'./configs/{build_config}.yaml'
23
        try:
24
            with open(config_file, 'r', encoding = 'utf8') as build_config_file:
25
                self.config_file = loadyaml(build_config_file)
26
        except FileNotFoundError:
27
            sysexit(f'[Err.:6] Файл не найден или не указан: {config_file}')
28
        # Cекция source конфига
29
        # Есть идея, но потом (забить на переменные для каждой секции конфига.)
30
        self.mainfile, self.outfile, self.workdir = [
31
            self.config_file['source']['mainfile'],
32
            self.config_file['source']['outputfile'],
33
            self.config_file['source']['workdir']
34
        ]
35
        # Секция main конфига
36
        self.version, self.author, self.authorlink = [
37
            self.config_file['main']['version'],
38
            self.config_file['main']['author'],
39
            self.config_file['main']['authorlink']
40
            ]
41
        # Прочие детали конфига
42
        self.plugins = self.config_file['plugins']
43
        self.params: list = self.config_file['params']
44
        self.addition_files = self.config_file['files']
45
        self.product_name: str = self.config_file['main']['product_name']
46
    # Запуск сборки
47
    def build(self) -> None:
48
        parameters_string = '--' + ' --'.join(self.params)
49
        run_cmd(f'nuitka {parameters_string} \
50
            --plugin-enable={self.plugins}\
51
            --windows-icon-from-ico={self.config_file["main"]["icon"]}\
52
                {self.config_file["source"]["mainfile"]}')
53
#             --include-data-files=../ui/imgs/*.png=imgs/\
54
    # Вывод параметров конфига, в случае необходимости
55
    def outprint(self) -> None:
56
        """Вывод параметров конфига
57
        """
58
        today = datetime.today().strftime('%d-%m-%Y  %H:%M:%S')
59
        print('-' * 10, f'\n{today}\n', '-' * 10)
60
        print('Config directives\n'
61
              # Секция предварительных настроек
62
              f'WorkDir: {self.workdir}\n'
63
              f'Main File: {self.mainfile}\n'
64
              f'Output File: {self.outfile}\n'
65
              # Секция продукта / сборки
66
              '\nProdut info\n'
67
              f'Version: {self.version}\n'
68
              f'Author: {self.author}\n'
69
              f'Authorlink: {self.authorlink}\n'
70
              f'Product Name: {self.product_name}\n'
71
              # Секция плагинов
72
              '\nBuild Plugins\n'
73
              f'Plugins: {self.plugins}'
74
              # Секция параметров
75
              '\nBuild parameters\n'
76
              'Parameters:\n'
77
              )
78
        for parameter in self.params:
79
            print(parameter)
80
        print('-' * 10)
81
    # Упаковка сборки в архив
82
    def zip_output(self) -> None:
83
        """Упаковывает собранные файлы в архив
84
        """
85
        with zipfile.ZipFile(f'{self.product_name}.zip',
86
                             'w',
87
                             compression=zipfile.ZIP_DEFLATED,
88
                             compresslevel=9) as zip_arch:
89
            zip_arch.write(self.outfile)
90
            if len(self.addition_files) > 0: # Протестировать бы, но потом...
91
                for other_files in self.addition_files:
92
                    secondpth = f'{path.basename(path.dirname(path.abspath(other_files)))}\
93
                        /{path.basename(other_files)}'
94
                    zip_arch.write(path.abspath(other_files), secondpth)
95
        zip_arch.close() # Но это не точно...
96
# Получение основного конфига (не тестировалось)
97
def get_core_config() -> dict:
98
    """Читает конфиг сборщка
99
100
    Returns:
101
        dict: Словарь с параметрами конфигурации сборщика
102
    """
103
    try:
104
        with open('configs/core.yaml', 'r', encoding = 'utf8') as core_c:
105
            core_config = loadyaml(core_c)
106
    except FileNotFoundError:
107
        print('File not found')
108
        sysexit(6) # Потому что 42, вот почему!
109
    return core_config
0 ignored issues
show
introduced by
The variable core_config does not seem to be defined for all execution paths.
Loading history...
110
# Получение конфига сборки (не тестировалось)
111
def get_build_config(conf_path: str) -> dict | None:
112
    """Читает конфиг сборки
113
114
    Args:
115
        conf_path (str): Путь до персонализированного конфига сборки
116
117
    Returns:
118
        dict: Словарь с параметрами конфигурации определенной сборки
119
    """
120
    if conf_path == '':
121
        print(
122
            'Не указан файл конфигурации сборки.\n'
123
            f'Необходимо запускать "{argv[0]} <путь до конфига>"')
124
    else:
125
        with open(conf_path, 'r', encoding = 'utf8') as build_conf_yaml:
126
            build_config = loadyaml(build_conf_yaml)
127
            return build_config
128
    return None
129
# Запуск алгоритма сборки
130
def build_start(config_input: str) -> None:
131
    """Запуск алгоритма сборки
132
133
    Args:
134
        config_input (str): Путь к файлу конфига сборки
135
    """
136
    config = BuildConfig(config_input)
137
    config.outprint()
138
    config.build()
139
    log = Log(config_input)
140
    log.start()
141
    log.write(f'Используется основной файл: {config.config_file["source"]["mainfile"]}')
142
# Запуск скрипта
143
if __name__ == '__main__':
144
    # man()
145
    try:
146
        build_start(argv[1])
147
    except IndexError:
148
        print('Конфиг сборки не указан')
149
        set_build_config = input('Укажите файл сборки конфига: ')
150
        if set_build_config is None or set_build_config == '':
151
            print('Конфиг сборки не указан')
152
        else:
153
            build_start(set_build_config)
154
### Старые наработки, они будут понемногу переноситься в основной код,
155
### Но в нормальном виде. После переноса и тестирования они должны быть удалены.
156
#
157
# def getconfig() -> dict:
158
#     """Загружает данные из конфига сборки.
159
#
160
#     Returns:
161
#         dict: Список переменных конфига
162
#     """
163
#     try:
164
#         with open('./config.yaml', 'r') as confFile:
165
#             conf: dict = loadyaml(confFile)
166
#     except FileNotFoundError:
167
#         print('File not found')
168
#     return conf
169
#
170
# def zipOutput():
171
#     """Упаковывает готовый файл в архив.
172
#     """
173
#     with zipfile.ZipFile('SimpleTester.zip', 'w',
174
#                          compression=zipfile.ZIP_DEFLATED,
175
#                          compresslevel=9) as zipArch:
176
#         zipArch.write('SimpleTester.exe')
177
#
178
# def makeParamStr(getconfig) -> str:
179
#     """Создает строку параметров сборки из данных конфига.
180
#
181
#     Args:
182
#         getconfig (function): Принимает на вход функцию парсинга конфига
183
#
184
#     Returns:
185
#         str: Строка с набором параметров сборки
186
#     """
187
#     paramList = []
188
#     for param in getconfig['params']:
189
#         if param == 'windows-product-version':
190
#             param = '{}="{}"'.format(param, getconfig['main']['version'])
191
#         paramList.append(param)
192
#     paramStr = '--' + ' --'.join(paramList)
193
#     return paramStr
194
#
195
# if __name__ == '__main__':
196
#     """Запуск сборки бинарного файла и его упаковка в архив.
197
#     """
198
#     paramsStr = makeParamStr(getconfig())
199
#     plugins = getconfig()['plugins']
200
#     icon = getconfig()['main']['icon']
201
    # runCommand(
202
    #     f'nuitka {paramsStr} \
203
    #         --plugin-enable={plugins}\
204
    #         --windows-icon-from-ico={icon}\
205
    #         --include-data-files=../ui/imgs/*.png=imgs/\
206
    #             ../SimpleTester.py')
207
#     zipOutput()
208