114 lines
4 KiB
Python
114 lines
4 KiB
Python
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
# SPDX-FileCopyrightText: 2011-2024 Blender Authors
|
|
# <pep8 compliant>
|
|
|
|
import pathlib
|
|
import zipfile
|
|
|
|
import worker.utils
|
|
|
|
|
|
def pack(
|
|
# Version string in the form of 2.83.3.0, this is used in the Store package name
|
|
version: str,
|
|
# Input file path
|
|
input_file_path: pathlib.Path,
|
|
# A string in the form of 'CN=PUBLISHER'
|
|
publisher: str,
|
|
# If set this MSIX is for an LTS release
|
|
lts: bool = False,
|
|
# If set remove Content folder if it already exists
|
|
overwrite: bool = False,
|
|
# Don't actually execute commands
|
|
dry_run: bool = False,
|
|
) -> pathlib.Path:
|
|
LTSORNOT = ""
|
|
PACKAGETYPE = ""
|
|
if lts:
|
|
versionparts = version.split(".")
|
|
LTSORNOT = f" {versionparts[0]}.{versionparts[1]} LTS"
|
|
PACKAGETYPE = f"{versionparts[0]}.{versionparts[1]}LTS"
|
|
|
|
output_package_file_name = f"{input_file_path.stem}.msix"
|
|
output_package_file_path = pathlib.Path(".", output_package_file_name)
|
|
content_folder = pathlib.Path(".", "Content")
|
|
content_blender_folder = pathlib.Path(content_folder, "Blender")
|
|
content_assets_folder = pathlib.Path(content_folder, "Assets")
|
|
assets_original_folder = pathlib.Path(".", "Assets")
|
|
|
|
pri_config_file = pathlib.Path(".", "priconfig.xml")
|
|
pri_resources_file = pathlib.Path(content_folder, "resources.pri")
|
|
|
|
pri_command = [
|
|
"makepri",
|
|
"new",
|
|
"/pr",
|
|
f"{content_folder.absolute()}",
|
|
"/cf",
|
|
f"{pri_config_file.absolute()}",
|
|
"/of",
|
|
f"{pri_resources_file.absolute()}",
|
|
]
|
|
|
|
msix_command = [
|
|
"makeappx",
|
|
"pack",
|
|
"/h",
|
|
"sha256",
|
|
"/d",
|
|
f"{content_folder.absolute()}",
|
|
"/p",
|
|
f"{output_package_file_path.absolute()}",
|
|
]
|
|
|
|
if overwrite:
|
|
if content_folder.joinpath("Assets").exists():
|
|
worker.utils.remove_dir(content_folder)
|
|
content_folder.mkdir(exist_ok=True)
|
|
worker.utils.copy_dir(assets_original_folder, content_assets_folder)
|
|
|
|
manifest_text = pathlib.Path("AppxManifest.xml.template").read_text()
|
|
manifest_text = manifest_text.replace("[VERSION]", version)
|
|
manifest_text = manifest_text.replace("[PUBLISHER]", publisher)
|
|
manifest_text = manifest_text.replace("[LTSORNOT]", LTSORNOT)
|
|
manifest_text = manifest_text.replace("[PACKAGETYPE]", PACKAGETYPE)
|
|
pathlib.Path(content_folder, "AppxManifest.xml").write_text(manifest_text)
|
|
|
|
worker.utils.info(
|
|
f"Extracting files from [{input_file_path}] to [{content_blender_folder.absolute()}]"
|
|
)
|
|
|
|
# Extract the files from the ZIP archive, but skip the leading part of paths
|
|
# in the ZIP. We want to write the files to the content_blender_folder where
|
|
# blender.exe ends up as ./Content/Blender/blender.exe, and not
|
|
# ./Content/Blender/blender-2.83.3-windows64/blender.exe
|
|
with zipfile.ZipFile(input_file_path, "r") as blender_zip:
|
|
for entry in blender_zip.infolist():
|
|
if entry.is_dir():
|
|
continue
|
|
entry_location = pathlib.Path(entry.filename)
|
|
target_location = content_blender_folder.joinpath(*entry_location.parts[1:])
|
|
pathlib.Path(target_location.parent).mkdir(parents=True, exist_ok=True)
|
|
extracted_entry = blender_zip.read(entry)
|
|
target_location.write_bytes(extracted_entry)
|
|
|
|
worker.utils.info("... extraction complete.")
|
|
|
|
worker.utils.info("Generating Package Resource Index (PRI) file")
|
|
worker.utils.call(pri_command, dry_run=dry_run)
|
|
|
|
worker.utils.info(f"Creating MSIX package using command: {' '.join(msix_command)}")
|
|
|
|
# Remove MSIX file if it already exists. Otherwise the MakeAppX tool
|
|
# will hang.
|
|
worker.utils.remove_file(output_package_file_path)
|
|
worker.utils.call(msix_command, dry_run=dry_run)
|
|
|
|
if dry_run:
|
|
output_package_file_path.write_text("Dry run dummy package file")
|
|
|
|
worker.utils.remove_dir(content_folder)
|
|
|
|
worker.utils.info("Done.")
|
|
|
|
return output_package_file_path
|