import os import sys import subprocess def run_build(): """ Automates compiling the Streamlit application into a single-file executable using PyInstaller. Ensures that PyInstaller points to the isolated library dependencies within the .venv environment. """ print("==============================================================") print("NetBackup Log Insights - Portable Compilation (PyInstaller)") print("==============================================================") # 1. Resolve workspace paths base_dir = os.path.dirname(os.path.abspath(__file__)) venv_dir = os.path.join(base_dir, ".venv") if not os.path.exists(venv_dir): print(f"Erro: O ambiente virtual '.venv' nao foi encontrado em: {venv_dir}") print("Certifique-se de ter criado o ambiente virtual (.venv) e instalado as dependencias.") sys.exit(1) # Resolve binaries and site-packages locations based on OS if sys.platform.startswith("win"): venv_python = os.path.join(venv_dir, "Scripts", "python.exe") venv_pyinstaller = os.path.join(venv_dir, "Scripts", "pyinstaller.exe") site_packages = os.path.join(venv_dir, "Lib", "site-packages") data_sep = ";" else: venv_python = os.path.join(venv_dir, "bin", "python") venv_pyinstaller = os.path.join(venv_dir, "bin", "pyinstaller") # Find Python version folder py_ver = f"python{sys.version_info.major}.{sys.version_info.minor}" site_packages = os.path.join(venv_dir, "lib", py_ver, "site-packages") data_sep = ":" if not os.path.exists(venv_pyinstaller): print(f"Erro: PyInstaller nao foi encontrado no .venv em: {venv_pyinstaller}") print("Instalando pyinstaller no ambiente virtual...") subprocess.run([venv_python, "-m", "pip", "install", "pyinstaller"], check=True) print(f"-> Root: {base_dir}") # Normalize paths to use double backslashes on Windows for PyInstaller argument safety site_packages = os.path.abspath(site_packages) print(f"-> Usando site-packages do .venv: {site_packages}") print(f"-> Executavel PyInstaller: {venv_pyinstaller}") # 2. Build the PyInstaller command arguments # - --onefile: Bundles everything into a single portable executable # - --paths: Forces PyInstaller to search for modules inside our virtual env # - --add-data: Bundles app.py, parser.py, and database.py into the root structure # - --collect-all: Gathers all python submodules, metadata, and static assets for streamlit, pandas, and plotly cmd = [ venv_pyinstaller, "--onefile", "--name=NetBackup_Log_Insights", "--paths", site_packages, "--add-data", f"app.py{data_sep}.", "--add-data", f"parser.py{data_sep}.", "--add-data", f"database.py{data_sep}.", "--collect-all", "streamlit", "--collect-all", "pandas", "--collect-all", "plotly", "app.py" ] print(f"\nComando executado:\n{' '.join(cmd)}\n") try: # Run PyInstaller compilation process result = subprocess.run(cmd, check=True, cwd=base_dir) if result.returncode == 0: print("\n==============================================================") print("SUCESSO: Executavel portable compilado com sucesso!") exe_ext = ".exe" if sys.platform.startswith("win") else "" output_path = os.path.join(base_dir, "dist", f"NetBackup_Log_Insights{exe_ext}") print(f"Caminho do arquivo gerado: {output_path}") print("==============================================================") except subprocess.CalledProcessError as e: print(f"\nErro ocorrido durante a compilacao via PyInstaller: {e}") sys.exit(1) if __name__ == "__main__": run_build()