Skip to content

Commit

Permalink
Merge pull request #76 from facundobatista/refactor-install-dir-name
Browse files Browse the repository at this point in the history
Refactor the project's install directory name.
  • Loading branch information
facundobatista authored Jul 8, 2023
2 parents 1c30fdb + 56277dd commit e695fb8
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 3 deletions.
32 changes: 29 additions & 3 deletions pyempaq/unpacker.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

"""Unpacking functionality.."""

import hashlib
import importlib
import json
import logging
import os
Expand All @@ -12,7 +14,6 @@
import shutil
import subprocess
import sys
import time
import venv
import zipfile
from types import ModuleType
Expand All @@ -33,6 +34,10 @@
"restrictions_not_met": 64
}

# the real magic number is a byte sequence with "\r\n" at the end; it's built here
# so it's easily patchable by tests
MAGIC_NUMBER = importlib.util.MAGIC_NUMBER[:-2].hex()

# setup logging
logger = logging.getLogger()
handler = logging.StreamHandler()
Expand Down Expand Up @@ -160,6 +165,28 @@ def restrictions_ok(version: ModuleType, restrictions: Dict[str, Any]) -> bool:
return True


def build_project_install_dir(zip_path: pathlib.Path, metadata: Dict[str, str]):
"""Build the name of the directory where everything will be extracted."""
project_name = metadata["project_name"]

# get the first part of the hash of the file
hasher = hashlib.sha256()
with open(zip_path, "rb") as fh:
while True:
data = fh.read(65536)
hasher.update(data)
if not data:
break
file_hash_partial = hasher.hexdigest()[:20]

# Python details
py_impl = platform.python_implementation().lower()
py_version = ".".join(platform.python_version_tuple()[:2])

name = f"{project_name}-{file_hash_partial}-{py_impl}.{py_version}.{MAGIC_NUMBER}"
return name


def run():
"""Run the unpacker."""
log("PyEmpaq start")
Expand All @@ -184,8 +211,7 @@ def run():
log("Temp base dir: %r", str(pyempaq_dir))

# create a temp dir and extract the project there
timestamp = time.strftime("%Y%m%d%H%M%S", time.gmtime(pyempaq_filepath.stat().st_ctime))
project_dir = pyempaq_dir / "{}-{}".format(metadata["project_name"], timestamp)
project_dir = pyempaq_dir / build_project_install_dir(pyempaq_filepath, metadata)
original_project_dir = project_dir / "orig"
venv_requirements = [original_project_dir / fname for fname in metadata["requirement_files"]]
setup_project_directory(zf, project_dir, venv_requirements)
Expand Down
1 change: 1 addition & 0 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ logassert
packaging
pydocstyle
pytest
pytest-mock
pytest-subprocess
23 changes: 23 additions & 0 deletions tests/test_unpacker.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

"""Unpacker tests."""

import hashlib
import os
import platform
import zipfile
Expand All @@ -19,6 +20,7 @@
from pyempaq.unpacker import (
PROJECT_VENV_DIR,
build_command,
build_project_install_dir,
restrictions_ok,
run_command,
setup_project_directory,
Expand Down Expand Up @@ -291,3 +293,24 @@ def test_enforcerestrictions_pythonversion_good_comparison(logs):
"""Enforce minimum python version using a proper comparison, not strings."""
ok = restrictions_ok(version, {"minimum_python_version": "3.0009"})
assert ok is True


# --- tests for the project install dir name


def test_installdirname_complete(mocker, tmp_path):
"""Check the name is properly built."""
mocker.patch("platform.python_implementation", return_value="PyPy")
mocker.patch("platform.python_version_tuple", return_value=("3", "18", "7alpha"))
mocker.patch("pyempaq.unpacker.MAGIC_NUMBER", "xyz")

zip_path = tmp_path / "somestuff.zip"
content = b"some content to be hashed"
zip_path.write_bytes(content)
content_hash = hashlib.sha256(content).hexdigest()

fake_metadata = {"foo": "bar", "project_name": "testproj"}

dirname = build_project_install_dir(zip_path, fake_metadata)

assert dirname == f"testproj-{content_hash[:20]}-pypy.3.18.xyz"

0 comments on commit e695fb8

Please sign in to comment.