create_windows_installer.py 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  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 semver
  7. import shutil
  8. from datetime import datetime
  9. from pathlib import Path
  10. from jinja2 import Template
  11. def generate_nsi(source_path: str, dist_path: str, filename: str, version: str):
  12. dist_loc = Path(os.getcwd(), dist_path)
  13. source_loc = Path(os.getcwd(), source_path)
  14. instdir = Path("$INSTDIR")
  15. dist_paths = [p.relative_to(dist_loc.joinpath("UltiMaker-Cura")) for p in sorted(dist_loc.joinpath("UltiMaker-Cura").rglob("*")) if p.is_file()]
  16. parsed_version = semver.Version.parse(version)
  17. mapped_out_paths = {}
  18. for dist_path in dist_paths:
  19. if "__pycache__" not in dist_path.parts:
  20. out_path = instdir.joinpath(dist_path).parent
  21. if out_path not in mapped_out_paths:
  22. mapped_out_paths[out_path] = [(dist_loc.joinpath("UltiMaker-Cura", dist_path), instdir.joinpath(dist_path))]
  23. else:
  24. mapped_out_paths[out_path].append((dist_loc.joinpath("UltiMaker-Cura", dist_path), instdir.joinpath(dist_path)))
  25. rmdir_paths = set()
  26. for rmdir_f in mapped_out_paths.values():
  27. for _, rmdir_p in rmdir_f:
  28. for rmdir in rmdir_p.parents:
  29. rmdir_paths.add(rmdir)
  30. rmdir_paths = sorted(list(rmdir_paths), reverse = True)[:-2] # Removes the `.` and `..` from the list
  31. jinja_template_path = Path(source_loc.joinpath("packaging", "NSIS", "Ultimaker-Cura.nsi.jinja"))
  32. with open(jinja_template_path, "r") as f:
  33. template = Template(f.read())
  34. nsis_content = template.render(
  35. app_name = f"UltiMaker Cura {version}",
  36. main_app = "UltiMaker-Cura.exe",
  37. version = version,
  38. version_major = str(parsed_version.major),
  39. version_minor = str(parsed_version.minor),
  40. version_patch = str(parsed_version.patch),
  41. company = "UltiMaker",
  42. web_site = "https://ultimaker.com",
  43. year = datetime.now().year,
  44. cura_license_file = str(source_loc.joinpath("packaging", "cura_license.txt")),
  45. compression_method = "LZMA", # ZLIB, BZIP2 or LZMA
  46. cura_banner_img = str(source_loc.joinpath("packaging", "NSIS", "cura_banner_nsis.bmp")),
  47. cura_icon = str(source_loc.joinpath("packaging", "icons", "Cura.ico")),
  48. mapped_out_paths = mapped_out_paths,
  49. rmdir_paths = rmdir_paths,
  50. destination = filename
  51. )
  52. with open(dist_loc.joinpath("UltiMaker-Cura.nsi"), "w") as f:
  53. f.write(nsis_content)
  54. shutil.copy(source_loc.joinpath("packaging", "NSIS", "fileassoc.nsh"), dist_loc.joinpath("fileassoc.nsh"))
  55. def build(dist_path: str):
  56. dist_loc = Path(os.getcwd(), dist_path)
  57. command = ["makensis", "/V2", "/P4", str(dist_loc.joinpath("UltiMaker-Cura.nsi"))]
  58. subprocess.run(command)
  59. if __name__ == "__main__":
  60. parser = argparse.ArgumentParser(description = "Create Windows exe installer of Cura.")
  61. parser.add_argument("--source_path", type=str, help="Path to Conan install Cura folder.")
  62. parser.add_argument("--dist_path", type=str, help="Path to Pyinstaller dist folder")
  63. parser.add_argument("--filename", type = str, help = "Filename of the exe (e.g. 'UltiMaker-Cura-5.1.0-beta-Windows-X64.exe')")
  64. parser.add_argument("--version", type=str, help="The full cura version, e.g. 5.9.0-beta.1+24132")
  65. args = parser.parse_args()
  66. generate_nsi(args.source_path, args.dist_path, args.filename, args.version)
  67. build(args.dist_path)