Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions src/auditwheel/main_repair.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

import argparse
import logging
import zlib
from pathlib import Path

from auditwheel.patcher import Patchelf

from . import tools
from .policy import WheelPolicies
from .tools import EnvironmentDefault

Expand Down Expand Up @@ -40,6 +42,18 @@ def configure_parser(sub_parsers) -> None: # type: ignore[no-untyped-def]
formatter_class=argparse.RawDescriptionHelpFormatter,
)
parser.add_argument("WHEEL_FILE", type=Path, help="Path to wheel file.", nargs="+")
parser.add_argument(
"-z",
"--zip-level",
action=EnvironmentDefault,
metavar="zip",
env="AUDITWHEEL_ZIP_LEVEL",
dest="zip",
type=int,
help="Compress level to be used to create zip file.",
choices=list(range(zlib.Z_NO_COMPRESSION, zlib.Z_BEST_COMPRESSION + 1)),
default=zlib.Z_DEFAULT_COMPRESSION,
)
parser.add_argument(
"--plat",
action=EnvironmentDefault,
Expand Down Expand Up @@ -119,6 +133,7 @@ def execute(args: argparse.Namespace, parser: argparse.ArgumentParser) -> int:
wheel_dir: Path = args.WHEEL_DIR.absolute()
wheel_files: list[Path] = args.WHEEL_FILE
wheel_policy = WheelPolicies()
tools._COMPRESS_LEVEL = args.zip

for wheel_file in wheel_files:
if not wheel_file.is_file():
Expand Down
24 changes: 23 additions & 1 deletion src/auditwheel/tools.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,27 @@
from __future__ import annotations

import argparse
import logging
import os
import subprocess
import zipfile
import zlib
from collections.abc import Generator, Iterable
from datetime import datetime, timezone
from pathlib import Path
from typing import Any, TypeVar

_T = TypeVar("_T")

logger = logging.getLogger(__name__)

# Default: zlib.Z_DEFAULT_COMPRESSION (-1 aka. level 6) balances speed and size.
# Maintained for typical builds where iteration speed outweighs distribution savings.
# Override via AUDITWHEEL_ZIP_LEVEL/--zip-level for:
# - some test builds that needs no compression at all (0)
# - bandwidth-constrained or large amount of downloads (9)
_COMPRESS_LEVEL = zlib.Z_DEFAULT_COMPRESSION


def unique_by_index(sequence: Iterable[_T]) -> list[_T]:
"""unique elements in `sequence` in the order in which they occur
Expand Down Expand Up @@ -90,6 +101,7 @@
out_dir : str
Directory path containing files to go in the zip archive
"""
start = datetime.now()
with zipfile.ZipFile(zip_fname, "r") as z:
for name in z.namelist():
member = z.getinfo(name)
Expand All @@ -102,6 +114,9 @@
attr &= 511 # only keep permission bits
attr |= 6 << 6 # at least read/write for current user
os.chmod(extracted_path, attr)
logger.debug(
"zip2dir from %s to %s takes %s", zip_fname, out_dir, datetime.now() - start
)


def dir2zip(in_dir: Path, zip_fname: Path, date_time: datetime | None = None) -> None:
Expand All @@ -120,6 +135,7 @@
date_time : Optional[datetime]
Time stamp to set on each file in the archive
"""
start = datetime.now()
in_dir = in_dir.resolve(strict=True)
if date_time is None:
st = in_dir.stat()
Expand All @@ -140,7 +156,10 @@
zinfo.date_time = date_time_args
zinfo.compress_type = compression
with open(fname, "rb") as fp:
z.writestr(zinfo, fp.read())
z.writestr(zinfo, fp.read(), compresslevel=_COMPRESS_LEVEL)
logger.debug(
"dir2zip from %s to %s takes %s", in_dir, zip_fname, datetime.now() - start
)


def tarbz2todir(tarbz2_fname: Path, out_dir: Path) -> None:
Expand All @@ -157,11 +176,14 @@
required: bool = True,
default: str | None = None,
choices: Iterable[str] | None = None,
type: type | None = None,
**kwargs: Any,
) -> None:
self.env_default = os.environ.get(env)
self.env = env
if self.env_default:
if type:
self.env_default = type(self.env_default)

Check warning on line 186 in src/auditwheel/tools.py

View check run for this annotation

Codecov / codecov/patch

src/auditwheel/tools.py#L186

Added line #L186 was not covered by tests
default = self.env_default
if default:
required = False
Expand Down
1 change: 1 addition & 0 deletions tests/integration/test_bundled_wheels.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ def test_wheel_source_date_epoch(tmp_path, monkeypatch):
func=Mock(),
prog="auditwheel",
verbose=1,
zip=None,
)
monkeypatch.setenv("SOURCE_DATE_EPOCH", "650203200")
# patchelf might not be available as we aren't running in a manylinux container
Expand Down