add backup ini and json file before create exec, add flag no-clean for pyinstaller
This commit is contained in:
parent
8a3de711e8
commit
f3a77fb7df
@ -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')
|
||||
|
||||
@ -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}]"
|
||||
|
||||
|
||||
|
||||
@ -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")
|
||||
@ -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
Loading…
Reference in New Issue
Block a user