DistScripts/dist_scripts/build_packet.py
2025-05-19 11:26:03 +03:00

151 lines
5.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import glob
import hashlib
import json
import shutil
import subprocess
from .patchers import patch_core_build
from .patchers import patch_metadata
from .config import *
product_name = "None" # Читается из metadata
icon = "" # Читается из metadata
splash = "" # Читается из metadata
def get_pyinstaller_cmd():
splash_str = ""
uac_admin = ""
dwt = ""
windows_mode = "--console"
if windowed[0]:
windows_mode = "-w"
add_data = [f'--add-data {path_fix + d}' for d in data]
if splash:
splash_str = f' --splash {path_fix + splash} '
if add_data:
add_data = f" {' '.join(add_data)}"
if disable_windowed_traceback:
dwt = " --disable-windowed-traceback "
if admin:
uac_admin = " --uac-admin "
pyinstaller_cmd = \
(f'pyinstaller --noconfirm --onedir {windows_mode} --clean '
f'--icon {path_fix + icon} --version-file {path_fix + metadata_path_txt}'
f'{splash_str}{add_data}{dwt}{uac_admin}'
f'--workpath {workpath} --distpath {distpath} --specpath {specpath} '
f'--contents-directory {contents_directory} --optimize {optimize} '
f'--name {product_name} {main}').split(" ")
pyinstaller_cmd = [x for x in pyinstaller_cmd if x]
logger.info(f"execute: {pyinstaller_cmd}")
return pyinstaller_cmd
def calculate_sha256(file_path):
sha256_hash = hashlib.sha256()
with open(file_path, "rb") as f:
for byte_block in iter(lambda: f.read(4096), b""):
sha256_hash.update(byte_block)
return sha256_hash.hexdigest()
# Функция для получения списка файлов с их хешами
def generate_file_list_with_sha256(directory):
file_list = {}
for root, dirs, files in os.walk(directory):
for file in files:
file_path = os.path.join(root, file)
file_sha256 = calculate_sha256(file_path)
file_list[file_path] = (file_sha256, os.path.getsize(file_path))
return file_list
# Функция для нахождения различий
def find_differences(old, new):
diff = {}
# Найдем файлы, которые есть в одном списке, но не в другом
for file_path, (sha256, size) in old.items():
if file_path not in new:
diff[file_path] = ('deleted', sha256)
elif sha256 != new[file_path][0]:
diff[file_path] = ('updated', sha256)
for file_path, (sha256, size) in new.items():
if file_path not in old:
diff[file_path] = ('new_file', sha256)
return diff
def save_sha256(file_list, path:str=sha_file):
with open(path, 'w') as file:
# noinspection PyTypeChecker
json.dump(file_list, file, indent=4)
def read_sha256():
with open(sha_file, 'r') as file:
return json.load(file)
def prepare_dist():
for f in glob.glob(os.path.join(distpath, "warn*.txt")):
os.remove(f)
new_shas = generate_file_list_with_sha256(distpath)
if not sha_file.exists():
save_sha256(new_shas)
return new_shas
def generate_patch(old_ver, new_ver, diff):
update_dir = patch_dir.format(old_ver=old_ver, new_ver=new_ver)
os.makedirs(update_dir, exist_ok=True)
for file_path, (status, _) in diff.copy().items():
rel_path = os.path.relpath(file_path, distpath + product_name) # Убираем лишнюю часть пути
del diff[file_path] # Удаляем из списка файлов
diff.update({rel_path: status}) # Добавляем новый путь
if status == 'deleted':
continue
target_path = os.path.join(update_dir, rel_path) # Куда копировать
os.makedirs(os.path.dirname(target_path), exist_ok=True) # Создаем папку, если её нет
shutil.copy(file_path, target_path)
save_sha256(diff, patch_file.format(old_ver=old_ver, new_ver=new_ver))
return update_dir
def zip_latest(version):
shutil.make_archive(f"{dist_dir}/{product_name}-{version}", 'zip', latest_dir)
def update_latest():
shutil.rmtree(latest_dir)
shutil.copytree(distpath + product_name, latest_dir)
def cleanup():
shutil.rmtree(build_dir)
os.makedirs(build_dir, exist_ok=True)
def build():
global product_name, icon, splash
new_ver = patch_core_build()
old_ver, product_name, icon, splash = patch_metadata(*new_ver)
logger.info("Building...")
# subprocess.run(['auto-py-to-exe', '--config', build_json_path], shell=True)
subprocess.run(get_pyinstaller_cmd())
if not os.path.exists(distpath):
logger.info("[ERR] Build unsuccessful")
return
logger.info("Build successful")
logger.info("Preparing dist")
logger.info(" - generating sha256")
new_sha = prepare_dist()
old_sha = read_sha256()
logger.info(" - comparing..")
diff = find_differences(old_sha, new_sha)
logger.info(f" - {len(diff)} differences found")
new_ver = f"{new_ver[0]}.{new_ver[1]}.{new_ver[2]}.{new_ver[3]}"
if diff:
update_dir = generate_patch(old_ver, new_ver, diff)
logger.info(f" - diffs in: {update_dir.split('/')[-1]}")
logger.info(" - saving..")
save_sha256(new_sha)
update_latest()
zip_latest(new_ver)
logger.info(" - cleaning up")
cleanup()
logger.info("Ready")
shutil.copy(log_file, log_dir / f"build_{new_ver}.log")