add backup ini and json file before create exec, add flag no-clean for pyinstaller

This commit is contained in:
VALLONGOL 2025-05-14 14:42:12 +02:00
parent 8a3de711e8
commit f3a77fb7df
5 changed files with 394 additions and 442 deletions

View File

@ -2,7 +2,6 @@
block_cipher = None
import os
a = Analysis(scripts=['pyinstallerguiwrapper\\__main__.py'],
pathex=['pyinstallerguiwrapper'],
binaries=[],
@ -21,26 +20,17 @@ pyz = PYZ(a.pure, a.zipped_data, cipher=None)
exe = EXE(pyz,
a.scripts,
[], # Binaries/Datas usually handled by Analysis/COLLECT
exclude_binaries=True, # Let COLLECT handle binaries in one-dir
[],
exclude_binaries=True,
name='PyInstallerGUIWrapper',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True, # Use UPX based on config
upx=True,
runtime_tmpdir=None,
console=False, # Set console based on GUI checkbox
console=False,
disable_windowed_traceback=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
icon='pyinstallerguiwrapper.ico')
coll = COLLECT(exe,
a.binaries,
a.zipfiles,
a.datas,
strip=False,
upx=True, # Match UPX setting
upx_exclude=[],
name='PyInstallerGUIWrapper')

View File

@ -8,10 +8,10 @@ import re
# --- Version Data (Generated) ---
# This section is automatically generated by the build process.
__version__ = "v.0.0.0.3-4-gf671da0-dirty"
GIT_COMMIT_HASH = "f671da08f3066a1f5d2ff877ebc28a9155903477"
__version__ = "v.0.0.0.3-5-g9061dcf-dirty"
GIT_COMMIT_HASH = "9061dcfb502fe1838aff1553f1efb80816f57c8c"
GIT_BRANCH = "master"
BUILD_TIMESTAMP = "2025-05-08T08:56:28Z"
BUILD_TIMESTAMP = "2025-05-14T12:40:23Z"
IS_GIT_REPO = True
# --- Default Values (for comparison or fallback) ---
@ -42,11 +42,10 @@ def get_version_string(format_string=None):
str: The formatted version string, or an error message if formatting fails.
"""
if format_string is None:
format_string = "{version} ({branch}/{commit_short})" # Sensible default
format_string = "{version} ({branch}/{commit_short})"
replacements = {}
try:
# Prepare data dictionary for substitution
replacements['version'] = __version__ if __version__ else DEFAULT_VERSION
replacements['commit'] = GIT_COMMIT_HASH if GIT_COMMIT_HASH else DEFAULT_COMMIT
replacements['commit_short'] = GIT_COMMIT_HASH[:7] if GIT_COMMIT_HASH and len(GIT_COMMIT_HASH) >= 7 else DEFAULT_COMMIT
@ -56,35 +55,23 @@ def get_version_string(format_string=None):
replacements['is_git'] = "Git" if IS_GIT_REPO else "Unknown"
replacements['dirty'] = "-dirty" if __version__ and __version__.endswith('-dirty') else ""
# Extract clean tag using regex (handles versions like v1.0.0, 1.0.0)
tag = DEFAULT_VERSION
if __version__ and IS_GIT_REPO:
# Match optional 'v' prefix, then major.minor.patch
match = re.match(r'^(v?([0-9]+)\.([0-9]+)\.([0-9]+))', __version__)
if match:
tag = match.group(1) # Get the full tag (e.g., 'v1.0.0')
tag = match.group(1)
replacements['tag'] = tag
# Perform substitution using regex to find placeholders {placeholder}
output_string = format_string
# Iterate through placeholders and replace them in the format string
for placeholder, value in replacements.items():
# Compile regex pattern for {placeholder}, allowing for whitespace inside braces
pattern = re.compile(r'{\s*' + re.escape(placeholder) + r'\s*}')
# Substitute found patterns with the corresponding string value
output_string = pattern.sub(str(value), output_string)
# Optional: Check if any placeholders remain unsubstituted (could indicate typo)
if re.search(r'{\s*[\w_]+\s*}', output_string):
# You might want to log this or handle it, for now, we return the string as is
# print(f"Warning: Unsubstituted placeholders remain in version string: {output_string}")
pass
return output_string
except Exception as e:
# Return a simple error message in case of unexpected formatting issues
# Avoid printing directly from this generated function
return f"[Formatting Error: {e}]"

View File

@ -7,61 +7,109 @@ import queue
import os
import traceback # For logging exceptions
# NO CHANGES NEEDED in this file for the restructuring
# NO CHANGES NEEDED in this file for the restructuring - EXCEPT FOR THE DEBUG LOG LINE ADDED BELOW
def run_build_in_thread(command, working_dir, output_queue, logger_func, output_dir_name, environment=None):
"""
Executes the PyInstaller command using subprocess.Popen in the background.
... (docstring remains the same) ...
Streams stdout/stderr to the output_queue for display in the GUI.
Notifies the main thread of success, failure, or completion via the queue.
Args:
command (list): The PyInstaller command and its arguments as a list of strings.
working_dir (str): The directory from which to run the command (project root).
output_queue (queue.Queue): Queue to send log messages and status updates.
logger_func (function): Function from the GUI to log messages (also used by this thread).
output_dir_name (str): The name of the dist/output directory (e.g., '_dist').
environment (dict, optional): A custom environment for the subprocess. Defaults to None (inherited).
"""
# ... (Function body remains the same as the previously translated version) ...
build_process = None
try:
logger_func("Build thread starting execution...", level="INFO")
# --- MODIFICA INIZIO ---
# Loggare il comando esatto che sta per essere eseguito per debugging
# Questo ci aiuterà a vedere se --clean è presente o meno.
# Usiamo una formattazione che gestisca gli spazi negli argomenti per una migliore leggibilità del log.
command_str_for_log = " ".join([f'"{c}"' if " " in c else c for c in command])
logger_func(f"PyInstaller command to be executed: {command_str_for_log}", level="DEBUG")
logger_func(f"Working directory: {working_dir}", level="DEBUG")
# --- MODIFICA FINE ---
env_log_msg = f"Using {'custom' if environment else 'inherited'} environment."
if environment: pass
if environment: pass # Placeholder, si potrebbe loggare di più sull'ambiente se necessario
logger_func(f"PyInstaller process starting. {env_log_msg}", level="INFO")
build_process = subprocess.Popen(
command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=working_dir,
text=True, encoding='utf-8', errors='replace', bufsize=1, env=environment )
command,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, # Redirect stderr to stdout
cwd=working_dir,
text=True, # Decode output as text
encoding='utf-8',
errors='replace', # Handle potential decoding errors gracefully
bufsize=1, # Line-buffered
env=environment # Pass the custom or inherited environment
)
logger_func(f"PyInstaller process launched (PID: {build_process.pid}).", level="INFO")
# Stream output
while True:
try:
line = build_process.stdout.readline()
if not line:
# Check if process has ended
if build_process.poll() is not None:
logger_func("End of PyInstaller output stream.", level="DEBUG")
break
else: pass
else: output_queue.put(("LOG", line))
else:
# Process might still be running but not producing output momentarily
# Could add a small sleep here if CPU usage is a concern,
# but for typical PyInstaller builds, continuous checking is fine.
pass
else:
output_queue.put(("LOG", line)) # Send line to GUI for display
except Exception as read_err:
# This might happen if the stream is closed unexpectedly
logger_func(f"Error reading PyInstaller output stream: {read_err}\n{traceback.format_exc()}", level="ERROR")
break
return_code = build_process.wait()
return_code = build_process.wait() # Wait for the process to complete
logger_func(f"PyInstaller process finished with exit code: {return_code}", level="INFO")
if return_code == 0:
dist_path_abs = os.path.join(working_dir, output_dir_name)
if os.path.exists(dist_path_abs):
# Check if the expected output directory/file exists
dist_path_abs = os.path.join(working_dir, output_dir_name) # output_dir_name is like '_dist'
# Note: For one-file, the output is a file, not a directory directly under dist_path_abs
# For one-dir, the output is a directory.
# We check for the existence of the dist_path_abs itself.
# A more robust check might involve looking for the executable name inside dist_path_abs.
if os.path.exists(dist_path_abs): # This checks if '_dist' (or equivalent) exists
success_msg = f"Build completed successfully!\nOutput Directory: {dist_path_abs}"
output_queue.put(("BUILD_SUCCESS", success_msg))
else:
# This case might be rare if PyInstaller exits with 0, but good for robustness
warn_msg = (f"Build finished with exit code 0, but output directory not found:\n"
f"{dist_path_abs}\nCheck the full log for potential issues.")
logger_func(warn_msg, level="WARNING")
output_queue.put(("BUILD_ERROR", warn_msg))
output_queue.put(("BUILD_ERROR", warn_msg)) # Treat as error if output dir is missing
else:
error_msg = f"Build failed! (Exit Code: {return_code})\nCheck the log for details."
output_queue.put(("BUILD_ERROR", error_msg))
except FileNotFoundError:
# This occurs if 'pyinstaller' command itself is not found
error_msg = ("Error: 'pyinstaller' command not found.\n"
"Ensure PyInstaller is installed correctly and in the system PATH.")
output_queue.put(("BUILD_ERROR", error_msg))
logger_func(error_msg, level="CRITICAL")
logger_func(error_msg, level="CRITICAL") # Logged via logger_func as well
except Exception as e:
# Catch any other unexpected errors during process execution
error_msg = f"Unexpected error during build process execution: {e}"
output_queue.put(("BUILD_ERROR", error_msg))
logger_func(error_msg, level="CRITICAL")
logger_func(traceback.format_exc(), level="DEBUG")
logger_func(error_msg, level="CRITICAL") # Logged via logger_func
logger_func(traceback.format_exc(), level="DEBUG") # Log full traceback for debugging
finally:
# Always signal that the build attempt (successful or not) has finished
output_queue.put(("BUILD_FINISHED", None))
logger_func("Build thread finished.", level="INFO")

View File

@ -3,8 +3,6 @@
Configuration constants for the PyInstaller GUI Wrapper application.
"""
# NO CHANGES NEEDED in this file for the restructuring
# Default values for PyInstaller options managed by the GUI
DEFAULT_SPEC_OPTIONS = {
'onefile': False,
@ -14,7 +12,7 @@ DEFAULT_SPEC_OPTIONS = {
'add_data': [],
'hidden_imports': [],
'log_level': 'INFO',
'clean_build': True, # Corresponds to --clean
'clean_build': False, # MODIFIED: Default is now False. Corresponds to --clean
'confirm_overwrite': False,# Corresponds to --noconfirm (True means --noconfirm is active)
'output_dir_name': '_dist', # Default name for the output directory
'work_dir_name': '_build', # Default name for the temporary build directory

File diff suppressed because it is too large Load Diff