YouTubeDownloader v1.1.2
YouTube content downloader
Loading...
Searching...
No Matches
generate_executable.py
Go to the documentation of this file.
1"""!
2********************************************************************************
3@file generate_executable.py
4@brief Generate executable file
5********************************************************************************
6"""
7
8# autopep8: off
9import sys
10import os
11import logging
12import subprocess
13import shutil
14
15sys.path.append(os.path.join(os.path.dirname(__file__), ".."))
16from Executable.generate_git_version import generate_git_version_file # pylint: disable=wrong-import-position
17from Executable.generate_version_file import generate_version_file # pylint: disable=wrong-import-position
18from Executable.check_included_packages import check_included_packages # pylint: disable=wrong-import-position
19
20from Source.version import __title__ # pylint: disable=wrong-import-position
21from Source.Util.colored_log import init_console_logging # pylint: disable=wrong-import-position
22# autopep8: on
23
24log = logging.getLogger("GenerateExecutable")
25init_console_logging(logging.INFO)
26
27WORKPATH = "build"
28GIT_VERSION_PATH = "../Source/Util"
29VERSION_FILE_NAME = "version_info.txt"
30WARNING_FILE = "PyInstaller_warnings.txt"
31
32L_EXCLUDE_MODULES = [
33 "PIL",
34 "charset_normalizer",
35 "numpy",
36 "pkg_resources",
37 "typing_extensions",
38 "darkdetect._mac_detect",
39 # actual not used
40 "moviepy",
41]
42
43TOLERATED_WARNINGS = [
44 "No backend available" # possible on CI
45]
46
47add_data = [
48 "..\\Resources\\app.ico;Resources\\"
49]
50
51
52L_HIDDEN_IMPORT = [
53]
54
55
56def get_type_list(type_name: str, l_type_values: list[str]) -> list[str]:
57 """!
58 @brief get type list
59 @param type_name : type name
60 @param l_type_values : type values
61 @return type list
62 """
63 type_list = []
64 for type_value in l_type_values:
65 type_list.extend([f"--{type_name}", type_value])
66 return type_list
67
68
69if __name__ == "__main__":
70 result_report = []
71
72 command = [r"..\.venv\Scripts\python", "-m", "PyInstaller", "--clean"]
73 command.extend(["--paths", "..\\"])
74 command.extend(get_type_list("add-data", add_data))
75 command.extend(["--icon", "..\\Resources\\app.ico"])
76 command.extend(["--version-file", f"{WORKPATH}\\{VERSION_FILE_NAME}"])
77 command.extend(get_type_list("hidden-import", L_HIDDEN_IMPORT))
78 command.extend(get_type_list("exclude-module", L_EXCLUDE_MODULES))
79 command.extend(["--name", __title__])
80 command.extend(["--onefile", "--noconsole", "--noupx",])
81 command.extend(["--distpath", "bin"])
82 command.extend(["--workpath", WORKPATH])
83 command.extend(["../Source/app.py"])
84
85 generate_git_version_file(GIT_VERSION_PATH)
86 generate_version_file(VERSION_FILE_NAME, WORKPATH)
87
88 result = subprocess.run(command, stderr=subprocess.PIPE, text=True, shell=True, check=False)
89 if result.returncode != 0:
90 result_report.append("Build executable failed!")
91 result_report.append(result.stderr)
92 else:
93 possible_build_warnings = [line for line in result.stderr.split("\n") if "WARNING" in line]
94 build_warnings = []
95 for warning in possible_build_warnings:
96 b_tolerate = False
97 for tolerate in TOLERATED_WARNINGS:
98 if tolerate in warning:
99 b_tolerate = True
100 break
101 if not b_tolerate:
102 build_warnings.append(warning)
103 if build_warnings:
104 result_report.extend(build_warnings)
105 else:
106 l_not_allowed_packages = check_included_packages()
107 if l_not_allowed_packages:
108 result_report.extend(l_not_allowed_packages)
109 log.info(result.stderr)
110
111 with open(WARNING_FILE, mode="w", encoding="utf-8") as file:
112 report = "\n".join(result_report)
113 if report:
114 log.warning(report)
115 file.write(report)
116 if result_report:
117 log.error("FAILED build of executable")
118 ret_value = 1
119 else:
120 s_spec_file = f"{__title__}.spec"
121 if os.path.exists(s_spec_file):
122 os.remove(s_spec_file)
123 if os.path.exists(WORKPATH):
124 shutil.rmtree(WORKPATH)
125 log.info("SUCCESS build of executable")
126 ret_value = 0
127 sys.exit(ret_value)
list[str] get_type_list(str type_name, list[str] l_type_values)
get type list