#! /usr/bin/env python # -*- coding: utf-8 -*- # # This file is part of npbackup __intname__ = "npbackup.compile-and-package-for-windows" __author__ = "Orsiris de Jong" __copyright__ = "Copyright (C) 2023 NetInvent" __license__ = "GPL-3.0-only" __build__ = "2023012801" __version__ = "1.4.0" import sys import os from command_runner import command_runner # Insert parent dir as path se we get to use npbackup as package sys.path.insert(0, os.path.normpath(os.path.join(os.path.dirname(__file__), ".."))) from npbackup import __version__ as npbackup_version from bin.NPBackupInstaller import __version__ as installer_version from npbackup.customization import ( COMPANY_NAME, TRADEMARKS, PRODUCT_NAME, FILE_DESCRIPTION, COPYRIGHT, LICENSE_FILE, ) from npbackup.core.restic_source_binary import get_restic_internal_binary from npbackup.path_helper import BASEDIR del sys.path[0] def check_private_build(): private = False try: import npbackup._private_secret_keys print("WARNING: Building with private secret key") private = True except ImportError: try: import npbackup.secret_keys print("Building with default secret key") except ImportError: print("Cannot find secret keys") sys.exit() dist_conf_file_path = get_private_conf_dist_file() if "_private" in dist_conf_file_path: print("WARNING: Building with a private conf.dist file") private = True return private def get_private_conf_dist_file(): private_dist_conf_file = "_private_npbackup.conf.dist" dist_conf_file = "npbackup.conf.dist" dist_conf_file_path = os.path.join(BASEDIR, os.pardir, "examples", private_dist_conf_file) if os.path.isfile(dist_conf_file_path): print("Building with private dist config file") else: print("Building with default dist config file") dist_conf_file_path = os.path.join(BASEDIR, os.pardir, "examples", dist_conf_file) return dist_conf_file_path def have_nuitka_commercial(): try: import nuitka.plugins.commercial print("Running with nuitka commercial") return True except ImportError: print("Running with nuitka open source") return False def compile(arch="64"): if os.name == "nt": program_executable = "npbackup.exe" restic_executable = "restic.exe" else: program_executable = "npbackup" restic_executable = "restic" PACKAGE_DIR = 'npbackup' is_private = check_private_build() OUTPUT_DIR = os.path.abspath(os.path.join(BASEDIR, os.pardir, "BUILD" + "-PRIVATE" if is_private else "")) if not os.path.isdir(OUTPUT_DIR): os.makedirs(OUTPUT_DIR) PYTHON_EXECUTABLE = sys.executable # npbackup compilation # Strip possible version suffixes '-dev' _npbackup_version = npbackup_version.split("-")[0] PRODUCT_VERSION = _npbackup_version + ".0" FILE_VERSION = _npbackup_version + ".0" file_description = "{} P{}-{}{}".format( FILE_DESCRIPTION, sys.version_info[1], arch, "priv" if is_private else "" ) restic_source_file = get_restic_internal_binary(arch) if not restic_source_file: print("Cannot find restic source file.") return restic_dest_file = os.path.join(PACKAGE_DIR, restic_executable) output_arch_dir = os.path.join( OUTPUT_DIR, "win-p{}{}-{}".format(sys.version_info[0], sys.version_info[1], arch), ) program_executable_path = os.path.join(output_arch_dir, program_executable) translations_dir = "translations" translations_dir_source = os.path.join(BASEDIR, translations_dir) translations_dir_dest = os.path.join(PACKAGE_DIR, translations_dir) license_dest_file = os.path.join(PACKAGE_DIR, os.path.basename(LICENSE_FILE)) icon_file = os.path.join(PACKAGE_DIR, 'npbackup_icon.ico') # Installer specific files, no need for a npbackup package directory here dist_conf_file_source = get_private_conf_dist_file() dist_conf_file_dest = os.path.basename(dist_conf_file_source) excludes_dir = "excludes" excludes_dir_source = os.path.join(BASEDIR, os.pardir, excludes_dir) excludes_dir_dest = excludes_dir r""" C:\GIT\npbackup>C:\GIT\NPBACKUP\venv\scripts\python.exe -m nuitka --python-flag=no_docstrings --python-flag=-O --onefile --plugin-enable=tk-inter --include-data-dir="C:\GIT\npbackup\npbackup\translations"="npbackup\translations" --include-data-file="C:\GIT\npbackup\npbackup\LICENSE.md"="npbackup\LICENSE.md" --include-data-file=npbackup\RESTIC_SOURCE_FILES\restic_0.15.0_windows_amd64.exe="restic.exe" --windows-icon-from-ico=npbackup\npbackup_icon.ico --company-name="NetInvent" --product-name="NPBackup Network Backup Client" --file-version="2.1.0.0" --product-version="2.1.0.0" --copyright="NetInvent 2022-2023" --file-description="Network Backup Client P10-x64priv" --trademarks="NetInvent (C)" --output-dir="C:\GIT\npbackup\npbackup\BUILD-PRIVATE\win-p310-x64" bin\npbackup """ EXE_OPTIONS = '--company-name="{}" --product-name="{}" --file-version="{}" --product-version="{}" --copyright="{}" --file-description="{}" --trademarks="{}"'.format( COMPANY_NAME, PRODUCT_NAME, FILE_VERSION, PRODUCT_VERSION, COPYRIGHT, file_description, TRADEMARKS, ) NUITKA_OPTIONS = '--enable-plugin=data-hiding' if have_nuitka_commercial() else '' CMD = '{} -m nuitka --python-flag=no_docstrings --python-flag=-O {} {} --onefile --plugin-enable=tk-inter --include-data-dir="{}"="{}" --include-data-file="{}"="{}" --include-data-file="{}"="{}" --windows-icon-from-ico="{}" --output-dir="{}" bin/npbackup'.format( PYTHON_EXECUTABLE, NUITKA_OPTIONS, EXE_OPTIONS, translations_dir_source, translations_dir_dest, LICENSE_FILE, license_dest_file, restic_source_file, restic_dest_file, icon_file, output_arch_dir, ) print(CMD) errors = False exit_code, output = command_runner(CMD, timeout=0, live_output=True) if exit_code != 0: errors = True # installer compilation _installer_version = installer_version.split("-")[0] PRODUCT_VERSION = _installer_version + ".0" FILE_VERSION = _installer_version + ".0" EXE_OPTIONS = '--company-name="{}" --product-name="{}" --file-version="{}" --product-version="{}" --copyright="{}" --file-description="{}" --trademarks="{}"'.format( COMPANY_NAME, PRODUCT_NAME, FILE_VERSION, PRODUCT_VERSION, COPYRIGHT, file_description, TRADEMARKS, ) CMD = '{} -m nuitka --python-flag=no_docstrings --python-flag=-O {} {} --onefile --plugin-enable=tk-inter --include-data-file="{}"="{}" --include-data-file="{}"="{}" --include-data-dir="{}"="{}" --windows-icon-from-ico="{}" --windows-uac-admin --output-dir="{}" bin/NPBackupInstaller.py'.format( PYTHON_EXECUTABLE, NUITKA_OPTIONS, EXE_OPTIONS, program_executable_path, program_executable, dist_conf_file_source, dist_conf_file_dest, excludes_dir_source, excludes_dir_dest, icon_file, output_arch_dir, ) print(CMD) exit_code, output = command_runner(CMD, timeout=0, live_output=True) if exit_code != 0: errors = True print("COMPILE ERRORS", errors) if __name__ == "__main__": # I know, I could improve UX here compile(arch=sys.argv[1]) check_private_build()