create_windows_installer.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. # Copyright (c) 2022 UltiMaker
  2. # Cura is released under the terms of the LGPLv3 or higher.
  3. import os
  4. import argparse # Command line arguments parsing and help.
  5. import subprocess
  6. import shutil
  7. from datetime import datetime
  8. from pathlib import Path
  9. from jinja2 import Template
  10. def generate_nsi(source_path: str, dist_path: str, filename: str, sign_secret: str):
  11. dist_loc = Path(os.getcwd(), dist_path)
  12. source_loc = Path(os.getcwd(), source_path)
  13. instdir = Path("$INSTDIR")
  14. dist_paths = [p.relative_to(dist_loc.joinpath("UltiMaker-Cura")) for p in sorted(dist_loc.joinpath("UltiMaker-Cura").rglob("*")) if p.is_file()]
  15. mapped_out_paths = {}
  16. for dist_path in dist_paths:
  17. if "__pycache__" not in dist_path.parts:
  18. out_path = instdir.joinpath(dist_path).parent
  19. if out_path not in mapped_out_paths:
  20. mapped_out_paths[out_path] = [(dist_loc.joinpath("UltiMaker-Cura", dist_path), instdir.joinpath(dist_path))]
  21. else:
  22. mapped_out_paths[out_path].append((dist_loc.joinpath("UltiMaker-Cura", dist_path), instdir.joinpath(dist_path)))
  23. rmdir_paths = set()
  24. for rmdir_f in mapped_out_paths.values():
  25. for _, rmdir_p in rmdir_f:
  26. for rmdir in rmdir_p.parents:
  27. rmdir_paths.add(rmdir)
  28. rmdir_paths = sorted(list(rmdir_paths), reverse = True)[:-2] # Removes the `.` and `..` from the list
  29. jinja_template_path = Path(source_loc.joinpath("packaging", "NSIS", "Ultimaker-Cura.nsi.jinja"))
  30. with open(jinja_template_path, "r") as f:
  31. template = Template(f.read())
  32. nsis_content = template.render(
  33. app_name = f"UltiMaker Cura {os.getenv('CURA_VERSION_FULL')}",
  34. main_app = "UltiMaker-Cura.exe",
  35. version = os.getenv('CURA_VERSION_FULL'),
  36. version_major = os.environ.get("CURA_VERSION_MAJOR"),
  37. version_minor = os.environ.get("CURA_VERSION_MINOR"),
  38. version_patch = os.environ.get("CURA_VERSION_PATCH"),
  39. company = "UltiMaker",
  40. web_site = "https://ultimaker.com",
  41. year = datetime.now().year,
  42. cura_license_file = str(source_loc.joinpath("packaging", "cura_license.txt")),
  43. compression_method = "LZMA", # ZLIB, BZIP2 or LZMA
  44. cura_banner_img = str(source_loc.joinpath("packaging", "NSIS", "cura_banner_nsis.bmp")),
  45. cura_icon = str(source_loc.joinpath("packaging", "icons", "Cura.ico")),
  46. mapped_out_paths = mapped_out_paths,
  47. rmdir_paths = rmdir_paths,
  48. destination = filename,
  49. sign_secret = sign_secret,
  50. )
  51. with open(dist_loc.joinpath("UltiMaker-Cura.nsi"), "w") as f:
  52. f.write(nsis_content)
  53. shutil.copy(source_loc.joinpath("packaging", "NSIS", "fileassoc.nsh"), dist_loc.joinpath("fileassoc.nsh"))
  54. def build(dist_path: str):
  55. dist_loc = Path(os.getcwd(), dist_path)
  56. command = ["makensis", "/V2", "/P4", str(dist_loc.joinpath("UltiMaker-Cura.nsi"))]
  57. subprocess.run(command)
  58. if __name__ == "__main__":
  59. parser = argparse.ArgumentParser(description = "Create Windows exe installer of Cura.")
  60. parser.add_argument("source_path", type=str, help="Path to Conan install Cura folder.")
  61. parser.add_argument("dist_path", type=str, help="Path to Pyinstaller dist folder")
  62. parser.add_argument("filename", type = str, help = "Filename of the exe (e.g. 'UltiMaker-Cura-5.1.0-beta-Windows-X64.exe')")
  63. parser.add_argument("sign_secret", type = str, help = "Supply secret for signing (the uninstaller, as the rest is already signed before).")
  64. args = parser.parse_args()
  65. generate_nsi(args.source_path, args.dist_path, args.filename, args.sign_secret)
  66. build(args.dist_path)