Просмотр исходного кода

Merge pull request #12767 from Ultimaker/CURA-8665_add_prerelease_tag_to_install_dir

CURA-8665 and CURA-9459 lock default install dir and use full semver for the install folder
Joey de l'Arago 2 лет назад
Родитель
Сommit
26ac80ffbf

+ 1 - 2
.github/workflows/cura-installer.yml

@@ -183,8 +183,7 @@ jobs:
             -   name: Create the Windows exe installer (Powershell)
                 if: ${{ github.event.inputs.installer == 'true' && runner.os == 'Windows' }}
                 run: |
-                    python ..\cura_inst\packaging\NSIS\nsis-configurator.py ".\Ultimaker-Cura" "..\cura_inst\packaging\NSIS\Ultimaker-Cura.nsi.jinja" "Ultimaker Cura" "Ultimaker-Cura.exe" "$Env:CURA_VERSION_MAJOR" "$Env:CURA_VERSION_MINOR" "$Env:CURA_VERSION_PATCH" "$Env:CURA_VERSION_BUILD" "Ultimaker B.V." "https://ultimaker.com" "..\cura_inst\packaging\cura_license.txt" "LZMA" "..\cura_inst\packaging\NSIS\cura_banner_nsis.bmp" "..\cura_inst\packaging\icons\Cura.ico" "Ultimaker-Cura-$Env:CURA_VERSION_FULL-${{ matrix.os_id }}-${{ runner.arch }}.exe"
-                    makensis /V2 /P4 Ultimaker-Cura.nsi
+                    python ..\cura_inst\packaging\NSIS\create_windows_installer.py ../cura_inst . "Ultimaker-Cura-$Env:CURA_VERSION_FULL-${{ matrix.os_id }}-${{ runner.arch }}.exe"
                 working-directory: dist
 
             -   name: Create the Linux AppImage (Bash)

+ 92 - 0
conandata.yml

@@ -195,6 +195,98 @@
             Macos: "./icons/cura.icns"
             Linux: "./icons/cura-128.png"
 "5.1.0-beta":
+    requirements:
+        - "arcus/5.1.0@ultimaker/stable"
+        - "curaengine/5.1.0@ultimaker/stable"
+        - "savitar/5.1.0@ultimaker/stable"
+        - "pynest2d/5.1.0@ultimaker/stable"
+        - "uranium/5.1.0@ultimaker/stable"
+        - "fdm_materials/5.1.0@ultimaker/stable"
+        - "cura_binary_data/5.1.0@ultimaker/stable"
+        - "cpython/3.10.4"
+    runinfo:
+        entrypoint: "cura_app.py"
+    pyinstaller:
+        datas:
+            cura_plugins:
+                package: "cura"
+                src: "plugins"
+                dst: "share/cura/plugins"
+            cura_resources:
+                package: "cura"
+                src: "resources"
+                dst: "share/cura/resources"
+            uranium_plugins:
+                package: "uranium"
+                src: "plugins"
+                dst: "share/uranium/plugins"
+            uranium_resources:
+                package: "uranium"
+                src: "resources"
+                dst: "share/uranium/resources"
+            uranium_um_qt_qml_um:
+                package: "uranium"
+                src: "site-packages/UM/Qt/qml/UM"
+                dst: "PyQt6/Qt6/qml/UM"
+            cura_binary_data:
+                package: "cura_binary_data"
+                src: "resources/cura/resources"
+                dst: "share/cura/resources"
+            uranium_binary_data:
+                package: "cura_binary_data"
+                src: "resources/uranium/resources"
+                dst: "share/uranium/resources"
+            windows_binary_data:
+                package: "cura_binary_data"
+                src: "windows"
+                dst: "share/windows"
+            fdm_materials:
+                package: "fdm_materials"
+                src: "materials"
+                dst: "share/cura/resources/materials"
+            tcl:
+                package: "tcl"
+                src: "lib/tcl8.6"
+                dst: "tcl"
+            tk:
+                package: "tk"
+                src: "lib/tk8.6"
+                dst: "tk"
+        binaries:
+            curaengine:
+                package: "curaengine"
+                src: "bin"
+                dst: "."
+                binary: "CuraEngine"
+        hiddenimports:
+            - "pySavitar"
+            - "pyArcus"
+            - "pynest2d"
+            - "PyQt6"
+            - "PyQt6.QtNetwork"
+            - "PyQt6.sip"
+            - "logging.handlers"
+            - "zeroconf"
+            - "fcntl"
+            - "stl"
+            - "serial"
+        collect_all:
+            - "cura"
+            - "UM"
+            - "serial"
+            - "Charon"
+            - "sqlite3"
+            - "trimesh"
+            - "win32ctypes"
+            - "PyQt6"
+            - "PyQt6.QtNetwork"
+            - "PyQt6.sip"
+            - "stl"
+        icon:
+            Windows: "./icons/Cura.ico"
+            Macos: "./icons/cura.icns"
+            Linux: "./icons/cura-128.png"
+"cura_8665":
     requirements:
         - "arcus/(latest)@ultimaker/stable"
         - "curaengine/(latest)@ultimaker/stable"

+ 14 - 14
packaging/NSIS/Ultimaker-Cura.nsi.jinja

@@ -1,10 +1,11 @@
 # Copyright (c) 2022 Ultimaker B.V.
 # Cura's build system is released under the terms of the AGPLv3 or higher.
 
-!define APP_NAME "{{ app_name }} {{ version_major }}.{{ version_minor }}.{{ version_patch }}"
+!define APP_NAME "{{ app_name }}"
 !define COMP_NAME "{{ company }}"
 !define WEB_SITE "{{ web_site }}"
-!define VERSION "{{ version_major }}.{{ version_minor }}.{{ version_patch }}.{{ version_build }}"
+!define VERSION "{{ version }}"
+!define VIVERSION "{{ version_major }}.{{ version_minor }}.{{ version_patch }}.0"
 !define COPYRIGHT "Copyright (c) {{ year }} {{ company }}"
 !define DESCRIPTION "Application"
 !define LICENSE_TXT "{{ cura_license_file }}"
@@ -12,7 +13,7 @@
 !define MAIN_APP_EXE "{{ main_app }}"
 !define INSTALL_TYPE "SetShellVarContext all"
 !define REG_ROOT "HKCU"
-!define REG_APP_PATH "Software\Microsoft\Windows\CurrentVersion\App Paths\${MAIN_APP_EXE}"
+!define REG_APP_PATH "Software\Microsoft\Windows\CurrentVersion\App Paths\${APP_NAME}"
 !define UNINSTALL_PATH "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_NAME}"
 
 !define REG_START_MENU "Start Menu Folder"
@@ -24,12 +25,12 @@ var SM_Folder
 
 ######################################################################
 
-VIProductVersion  "${VERSION}"
-VIAddVersionKey "ProductName"  "${APP_NAME}"
+VIProductVersion  "${VIVERSION}"
+VIAddVersionKey "ProductName"  "{{ app_name }}"
 VIAddVersionKey "CompanyName"  "${COMP_NAME}"
 VIAddVersionKey "LegalCopyright"  "${COPYRIGHT}"
 VIAddVersionKey "FileDescription"  "${DESCRIPTION}"
-VIAddVersionKey "FileVersion"  "${VERSION}"
+VIAddVersionKey "FileVersion"  "${VIVERSION}"
 
 ######################################################################
 
@@ -38,7 +39,6 @@ Name "${APP_NAME}"
 Caption "${APP_NAME}"
 OutFile "${INSTALLER_NAME}"
 BrandingText "${APP_NAME}"
-InstallDirRegKey "${REG_ROOT}" "${REG_APP_PATH}" ""
 InstallDir "$PROGRAMFILES64\${APP_NAME}"
 
 ######################################################################
@@ -64,7 +64,7 @@ InstallDir "$PROGRAMFILES64\${APP_NAME}"
 
 !ifdef REG_START_MENU
 !define MUI_STARTMENUPAGE_NODISABLE
-!define MUI_STARTMENUPAGE_DEFAULTFOLDER "{{ app_name }}"
+!define MUI_STARTMENUPAGE_DEFAULTFOLDER "Ultimaker Cura"
 !define MUI_STARTMENUPAGE_REGISTRY_ROOT "${REG_ROOT}"
 !define MUI_STARTMENUPAGE_REGISTRY_KEY "${UNINSTALL_PATH}"
 !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "${REG_START_MENU}"
@@ -113,8 +113,8 @@ CreateShortCut "$SMPROGRAMS\$SM_Folder\${APP_NAME}.lnk" "$INSTDIR\${MAIN_APP_EXE
 CreateShortCut "$SMPROGRAMS\$SM_Folder\Uninstall ${APP_NAME}.lnk" "$INSTDIR\uninstall.exe"
 
 !ifdef WEB_SITE
-WriteIniStr "$INSTDIR\${APP_NAME} website.url" "InternetShortcut" "URL" "${WEB_SITE}"
-CreateShortCut "$SMPROGRAMS\$SM_Folder\${APP_NAME} Website.lnk" "$INSTDIR\${APP_NAME} website.url"
+WriteIniStr "$INSTDIR\Ultimaker Cura website.url" "InternetShortcut" "URL" "${WEB_SITE}"
+CreateShortCut "$SMPROGRAMS\$SM_Folder\Ultimaker Cura website.lnk" "$INSTDIR\Ultimaker Cura website.url"
 !endif
 !insertmacro MUI_STARTMENU_WRITE_END
 !endif
@@ -125,8 +125,8 @@ CreateShortCut "$SMPROGRAMS\{{ app_name }}\${APP_NAME}.lnk" "$INSTDIR\${MAIN_APP
 CreateShortCut "$SMPROGRAMS\{{ app_name }}\Uninstall ${APP_NAME}.lnk" "$INSTDIR\uninstall.exe"
 
 !ifdef WEB_SITE
-WriteIniStr "$INSTDIR\${APP_NAME} website.url" "InternetShortcut" "URL" "${WEB_SITE}"
-CreateShortCut "$SMPROGRAMS\{{ app_name }}\${APP_NAME} Website.lnk" "$INSTDIR\${APP_NAME} website.url"
+WriteIniStr "$INSTDIR\Ultimaker Cura website.url" "InternetShortcut" "URL" "${WEB_SITE}"
+CreateShortCut "$SMPROGRAMS\{{ app_name }}\Ultimaker Cura website.lnk" "$INSTDIR\Ultimaker Cura website.url"
 !endif
 !endif
 
@@ -170,7 +170,7 @@ RmDir "$INSTDIR"
 Delete "$SMPROGRAMS\$SM_Folder\${APP_NAME}.lnk"
 Delete "$SMPROGRAMS\$SM_Folder\Uninstall ${APP_NAME}.lnk"
 !ifdef WEB_SITE
-Delete "$SMPROGRAMS\$SM_Folder\${APP_NAME} Website.lnk"
+Delete "$SMPROGRAMS\$SM_Folder\Ultimaker Cura website.lnk"
 !endif
 RmDir "$SMPROGRAMS\$SM_Folder"
 !endif
@@ -179,7 +179,7 @@ RmDir "$SMPROGRAMS\$SM_Folder"
 Delete "$SMPROGRAMS\{{ app_name }}\${APP_NAME}.lnk"
 Delete "$SMPROGRAMS\{{ app_name }}\Uninstall ${APP_NAME}.lnk"
 !ifdef WEB_SITE
-Delete "$SMPROGRAMS\{{ app_name }}\${APP_NAME} Website.lnk"
+Delete "$SMPROGRAMS\{{ app_name }}\Ultimaker Cura website.lnk"
 !endif
 RmDir "$SMPROGRAMS\{{ app_name }}"
 !endif

+ 80 - 0
packaging/NSIS/create_windows_installer.py

@@ -0,0 +1,80 @@
+# Copyright (c) 2022 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+import os
+import argparse  # Command line arguments parsing and help.
+import subprocess
+
+import shutil
+from datetime import datetime
+
+from pathlib import Path
+
+from jinja2 import Template
+
+
+def generate_nsi(source_path: str, dist_path: str, filename: str):
+    dist_loc = Path(os.getcwd(), dist_path)
+    source_loc = Path(os.getcwd(), source_path)
+    instdir = Path("$INSTDIR")
+    dist_paths = [p.relative_to(dist_loc.joinpath("Ultimaker-Cura")) for p in sorted(dist_loc.joinpath("Ultimaker-Cura").rglob("*")) if p.is_file()]
+    mapped_out_paths = {}
+    for dist_path in dist_paths:
+        if "__pycache__" not in dist_path.parts:
+            out_path = instdir.joinpath(dist_path).parent
+            if out_path not in mapped_out_paths:
+                mapped_out_paths[out_path] = [(dist_loc.joinpath("Ultimaker-Cura", dist_path), instdir.joinpath(dist_path))]
+            else:
+                mapped_out_paths[out_path].append((dist_loc.joinpath("Ultimaker-Cura", dist_path), instdir.joinpath(dist_path)))
+
+    rmdir_paths = set()
+    for rmdir_f in mapped_out_paths.values():
+        for _, rmdir_p in rmdir_f:
+            for rmdir in rmdir_p.parents:
+                rmdir_paths.add(rmdir)
+
+    rmdir_paths = sorted(list(rmdir_paths), reverse = True)[:-2]  # Removes the `.` and `..` from the list
+
+    jinja_template_path = Path(source_loc.joinpath("packaging", "NSIS", "Ultimaker-Cura.nsi.jinja"))
+    with open(jinja_template_path, "r") as f:
+        template = Template(f.read())
+
+
+    nsis_content = template.render(
+        app_name = f"Ultimaker Cura {os.getenv('CURA_VERSION_FULL')}",
+        main_app = "Ultimaker-Cura.exe",
+        version = os.getenv('CURA_VERSION_FULL'),
+        version_major = os.environ.get("CURA_VERSION_MAJOR"),
+        version_minor = os.environ.get("CURA_VERSION_MINOR"),
+        version_patch = os.environ.get("CURA_VERSION_PATCH"),
+        company = "Ultimaker B.V.",
+        web_site = "https://ultimaker.com",
+        year = datetime.now().year,
+        cura_license_file = str(source_loc.joinpath("packaging", "cura_license.txt")),
+        compression_method = "LZMA",  # ZLIB, BZIP2 or LZMA
+        cura_banner_img = str(source_loc.joinpath("packaging", "NSIS", "cura_banner_nsis.bmp")),
+        cura_icon = str(source_loc.joinpath("packaging", "icons", "Cura.ico")),
+        mapped_out_paths = mapped_out_paths,
+        rmdir_paths = rmdir_paths,
+        destination = filename
+    )
+
+    with open(dist_loc.joinpath("Ultimaker-Cura.nsi"), "w") as f:
+        f.write(nsis_content)
+
+    shutil.copy(source_loc.joinpath("packaging", "NSIS", "fileassoc.nsh"), dist_loc.joinpath("fileassoc.nsh"))
+
+
+def build(dist_path: str):
+    dist_loc = Path(os.getcwd(), dist_path)
+    command = ["makensis", "/V2", "/P4", str(dist_loc.joinpath("Ultimaker-Cura.nsi"))]
+    subprocess.run(command)
+
+
+if __name__ == "__main__":
+    parser = argparse.ArgumentParser(description = "Create Windows exe installer of Cura.")
+    parser.add_argument("source_path", type=str, help="Path to Conan install Cura folder.")
+    parser.add_argument("dist_path", type=str, help="Path to Pyinstaller dist folder")
+    parser.add_argument("filename", type = str, help = "Filename of the exe (e.g. 'Ultimaker-Cura-5.1.0-beta-Windows-X64.exe')")
+    args = parser.parse_args()
+    generate_nsi(args.source_path, args.dist_path, args.filename)
+    build(args.dist_path)

+ 0 - 78
packaging/NSIS/nsis-configurator.py

@@ -1,78 +0,0 @@
-import shutil
-import sys
-from datetime import datetime
-
-from pathlib import Path
-
-from jinja2 import Template
-
-if __name__ == "__main__":
-    """
-    - dist_loc: Location of distribution folder, as output by pyinstaller
-    - nsi_jinja_loc: Jinja2 template to use
-    - app_name: Should be "Ultimaker Cura".
-    - main_app: Name of executable, e.g. Ultimaker-Cura.exe?
-    - version_major: Major version number of Semver (e.g. 5).
-    - version_minor: Minor version number of Semver (e.g. 0).
-    - version_patch: Patch version number of Semver (e.g. 0).
-    - version_build: A version number that gets manually incremented at each build.
-    - company: Publisher of the application. Should be "Ultimaker B.V."
-    - web_site: Website to find more information. Should be "https://ultimaker.com".
-    - cura_license_file: Path to a license file in Cura. Should point to packaging/cura_license.txt in this repository.
-    - compression_method: Compression algorithm to use to compress the data inside the executable. Should be ZLIB, ZBIP2 or LZMA.
-    - cura_banner_img: Path to an image shown on the left in the installer. Should point to packaging/cura_banner_nsis.bmp in this repository.
-    - icon_path: Path to the icon to use on the installer
-    - destination: Where to put the installer after it's generated.
-`    """
-    for i, v in enumerate(sys.argv):
-        print(f"{i} = {v}")
-    dist_loc = Path(sys.argv[1])
-    instdir = Path("$INSTDIR")
-    dist_paths = [p.relative_to(dist_loc) for p in sorted(dist_loc.rglob("*")) if p.is_file()]
-    mapped_out_paths = {}
-    for dist_path in dist_paths:
-        if "__pycache__" not in dist_path.parts:
-            out_path = instdir.joinpath(dist_path).parent
-            if out_path not in mapped_out_paths:
-                mapped_out_paths[out_path] = [(dist_loc.joinpath(dist_path), instdir.joinpath(dist_path))]
-            else:
-                mapped_out_paths[out_path].append((dist_loc.joinpath(dist_path), instdir.joinpath(dist_path)))
-
-    rmdir_paths = set()
-    for rmdir_f in mapped_out_paths.values():
-        for _, rmdir_p in rmdir_f:
-            for rmdir in rmdir_p.parents:
-                rmdir_paths.add(rmdir)
-
-    rmdir_paths = sorted(list(rmdir_paths), reverse = True)[:-2]
-
-    jinja_template_path = Path(sys.argv[2])
-    with open(jinja_template_path, "r") as f:
-        template = Template(f.read())
-
-    nsis_content = template.render(
-        app_name = sys.argv[3],
-        main_app = sys.argv[4],
-        version_major = sys.argv[5],
-        version_minor = sys.argv[6],
-        version_patch = sys.argv[7],
-        version_build = sys.argv[8],
-        company = sys.argv[9],
-        web_site = sys.argv[10],
-        year = datetime.now().year,
-        cura_license_file = Path(sys.argv[11]),
-        compression_method = sys.argv[12],  # ZLIB, BZIP2 or LZMA
-        cura_banner_img = Path(sys.argv[13]),
-        cura_icon = Path(sys.argv[14]),
-        mapped_out_paths = mapped_out_paths,
-        rmdir_paths = rmdir_paths,
-        destination = Path(sys.argv[15])
-    )
-
-    with open(dist_loc.parent.joinpath(jinja_template_path.stem), "w") as f:
-        f.write(nsis_content)
-
-    shutil.copy(Path(__file__).absolute().parent.joinpath("fileassoc.nsh"), dist_loc.parent.joinpath("fileassoc.nsh"))
-    icon_path = Path(sys.argv[14])
-    shutil.copy(icon_path, dist_loc.joinpath(icon_path.name))
-

+ 1 - 0
requirements-dev.txt

@@ -2,3 +2,4 @@ pytest
 pyinstaller
 pyinstaller-hooks-contrib
 sip==6.5.1
+jinja2