Skip to content

Commit

Permalink
Use zipfile.ZipFile for packaging
Browse files Browse the repository at this point in the history
  • Loading branch information
MarkusPiotrowski committed Apr 17, 2023
1 parent fdbcb92 commit f280921
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 26 deletions.
2 changes: 1 addition & 1 deletion docs/reference/platforms/windows/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ The default output format for Windows is an :doc:`app <./app>`.
Briefcase also supports creating a :doc:`Visual Studio project <./visualstudio>`
which in turn can be used to build an app.

Both output formats support packaging as a Microsoft software installer (MSI) or
Both output formats support packaging as a Microsoft Software Installer (MSI) or
as a ZIP file.

.. toctree::
Expand Down
31 changes: 18 additions & 13 deletions src/briefcase/platforms/windows/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import uuid
from pathlib import Path
from typing import List
from zipfile import ZIP_DEFLATED, ZipFile

from briefcase.commands import CreateCommand, PackageCommand, RunCommand
from briefcase.config import AppConfig, parsed_version
Expand Down Expand Up @@ -278,6 +279,8 @@ def package_app(

if app.packaging_format == "zip":
self._package_zip(app)
# The zip can't be signed, so:
return
else:
self._package_msi(app)

Expand Down Expand Up @@ -376,16 +379,18 @@ def _package_zip(self, app):

self.logger.info("Building zip file...", prefix=app.app_name)
with self.input.wait_bar("Packing..."):
zip_root_path = self.bundle_path(app) / f"{app.formal_name}-{app.version}"
self.tools.shutil.copytree(
self.bundle_path(app) / self.packaging_root,
zip_root_path,
dirs_exist_ok=True,
)
self.tools.shutil.make_archive(
self.distribution_path(app).with_suffix(""),
"zip",
self.bundle_path(app),
f"{app.formal_name}-{app.version}",
)
self.tools.shutil.rmtree(zip_root_path)
source = self.bundle_path(app) / self.packaging_root # /src
try:
os.mkdir(self.dist_path) # /dist
except FileExistsError:
pass

with ZipFile(self.distribution_path(app), "w", ZIP_DEFLATED) as archive:
for path, _, files in os.walk(source):
for file in files:
src_path = os.path.join(path, file)
rel_path = src_path.replace(str(source), "")
archive.write(
src_path,
f"{app.formal_name}-{app.version}\\{rel_path}",
)
19 changes: 7 additions & 12 deletions tests/platforms/windows/app/test_package.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,9 @@ def package_command_with_files(package_command):
src_path.mkdir(parents=True)

# Mock some typical folders and files in the src folder:
package_command.paths = (
"app/",
"app/first-app/",
paths = (
"app/first-app/resources/",
"app/first-app-0.0.1.dist-info/",
"app_packages/",
"app_packages/toga_winforms/",
)
package_command.files = (
Expand All @@ -65,8 +62,8 @@ def package_command_with_files(package_command):
"app_packages/clr.py",
"app_packages/toga_winforms/command.py",
)
for path in package_command.paths:
(src_path / path).mkdir()
for path in paths:
(src_path / path).mkdir(parents=True)
for file in package_command.files:
open(f"{src_path}/{file}", "x").close()
return package_command
Expand Down Expand Up @@ -256,9 +253,7 @@ def test_package_zip(package_command_with_files, first_app_config, tmp_path):
package_command_with_files.package_app(first_app_config)

archive_file = tmp_path / "base_path" / "dist" / "First App-0.0.1.zip"
src_files_and_paths = (
package_command_with_files.paths + package_command_with_files.files + ("",)
)
source_files = package_command_with_files.files

# The zip file exists
assert archive_file.exists()
Expand All @@ -269,10 +264,10 @@ def test_package_zip(package_command_with_files, first_app_config, tmp_path):
# All files in zip are from source
for name in archive.namelist():
# name.removeprefix(f'{root}/') will only work in Python > 3.8
assert name[16:] in (src_files_and_paths)
assert name[16:] in source_files
# All files from source are in zip
for entity in src_files_and_paths:
assert f"{root}/{entity}" in archive.namelist()
for file in source_files:
assert f"{root}/{file}" in archive.namelist()


@pytest.mark.parametrize(
Expand Down

0 comments on commit f280921

Please # to comment.