diff --git a/news/5908.feature b/news/5908.feature new file mode 100644 index 00000000000..d8d99556929 --- /dev/null +++ b/news/5908.feature @@ -0,0 +1,2 @@ +Wheel builds will output the final filename and SHA256 hash of .whl +files as an info log entry. diff --git a/src/pip/_internal/wheel.py b/src/pip/_internal/wheel.py index 1bdbe93ab7e..cd8320edba3 100644 --- a/src/pip/_internal/wheel.py +++ b/src/pip/_internal/wheel.py @@ -68,8 +68,8 @@ def normpath(src, p): return os.path.relpath(src, p).replace(os.path.sep, '/') -def rehash(path, blocksize=1 << 20): - # type: (str, int) -> Tuple[str, str] +def hash_file(path, blocksize=1 << 20): + # type: (str, int) -> Tuple[Any, str] """Return (hash, length) for path using hashlib.sha256()""" h = hashlib.sha256() length = 0 @@ -77,6 +77,13 @@ def rehash(path, blocksize=1 << 20): for block in read_chunks(f, size=blocksize): length += len(block) h.update(block) + return (h, str(length)) # type: ignore + + +def rehash(path, blocksize=1 << 20): + # type: (str, int) -> Tuple[str, str] + """Return (encoded_digest, length) for path using hashlib.sha256()""" + h, length = hash_file(path, blocksize) digest = 'sha256=' + urlsafe_b64encode( h.digest() ).decode('latin1').rstrip('=') @@ -885,7 +892,10 @@ def _build_one_inside_env(self, req, output_dir, python_tag=None): wheel_name = os.path.basename(wheel_path) dest_path = os.path.join(output_dir, wheel_name) try: + wheel_hash, _ = hash_file(wheel_path) shutil.move(wheel_path, dest_path) + logger.info('Finished: %s sha256=%s', + wheel_name, wheel_hash.hexdigest()) logger.info('Stored in directory: %s', output_dir) return dest_path except Exception: diff --git a/tests/functional/test_wheel.py b/tests/functional/test_wheel.py index f67720f165a..83a7f92d534 100644 --- a/tests/functional/test_wheel.py +++ b/tests/functional/test_wheel.py @@ -1,5 +1,6 @@ """'pip wheel' tests""" import os +import re from os.path import exists import pytest @@ -48,6 +49,9 @@ def test_pip_wheel_success(script, data): ) wheel_file_name = 'simple-3.0-py%s-none-any.whl' % pyversion[0] wheel_file_path = script.scratch / wheel_file_name + assert re.search( + "Finished: %s sha256=[A-Fa-f0-9]{64}" % re.escape(wheel_file_name), + result.stdout) assert wheel_file_path in result.files_created, result.stdout assert "Successfully built simple" in result.stdout, result.stdout