From 1c9ac9e9002c8042fa3b4c310ddaa8cd7a8c7995 Mon Sep 17 00:00:00 2001 From: John Sirois Date: Thu, 12 Sep 2024 20:45:11 -0700 Subject: [PATCH] Fix `--scie-name-style platform-parent-dir`. (#2526) This required bumping our `science` floor to the just released 0.8.0 which adds support for explicitly requesting `--no-use-platform-suffix`. Fixes #2516 --- CHANGES.md | 8 ++ pex/scie/science.py | 21 ++-- pex/version.py | 2 +- scripts/create-packages.py | 2 + .../integration/scie/test_discussion_2516.py | 104 ++++++++++++++++++ tests/integration/scie/test_pex_scie.py | 24 +++- 6 files changed, 146 insertions(+), 15 deletions(-) create mode 100644 tests/integration/scie/test_discussion_2516.py diff --git a/CHANGES.md b/CHANGES.md index 06a682e66..060433304 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,13 @@ # Release Notes +## 2.18.1 + +This release fixes `--scie-name-style platform-parent-dir` introduced in +#2523. Previously the target platform name also leaked into scies +targeting foreign platforms despite using this option. + +* Fix `--scie-name-style platform-parent-dir`. (#2526) + ## 2.18.0 This release adds support for `pex3 cache {dir,info,purge}` for diff --git a/pex/scie/science.py b/pex/scie/science.py index 0a63d8fe6..62be4207c 100644 --- a/pex/scie/science.py +++ b/pex/scie/science.py @@ -64,7 +64,7 @@ def qualified_binary_name(self, binary_name): SCIENCE_RELEASES_URL = "https://github.com/a-scie/lift/releases" -MIN_SCIENCE_VERSION = Version("0.6.0") +MIN_SCIENCE_VERSION = Version("0.8.0") SCIENCE_REQUIREMENT = SpecifierSet("~={min_version}".format(min_version=MIN_SCIENCE_VERSION)) @@ -425,12 +425,13 @@ def build( pex = PEX(pex_file) naming_style = configuration.options.naming_style or PlatformNamingStyle.DYNAMIC + use_platform_suffix = None # type: Optional[bool] if PlatformNamingStyle.FILE_SUFFIX is naming_style: use_platform_suffix = True elif PlatformNamingStyle.PARENT_DIR is naming_style: use_platform_suffix = False - else: - use_platform_suffix = len(configuration.interpreters) > 1 + elif len(configuration.interpreters) > 1: + use_platform_suffix = True filenames = Filenames.avoid_collisions_with(name) @@ -459,8 +460,10 @@ def build( dest_dir, ] ) - if use_platform_suffix: - args.append("--use-platform-suffix") + if use_platform_suffix is not None: + args.append( + "--use-platform-suffix" if use_platform_suffix else "--no-use-platform-suffix" + ) for hash_algorithm in configuration.options.hash_algorithms: args.extend(["--hash", hash_algorithm]) args.append(manifest.path) @@ -487,9 +490,11 @@ def build( interpreter=manifest.interpreter, file=os.path.join( dest_dir, - manifest.qualified_binary_name(name) - if use_platform_suffix - else manifest.binary_name(name), + ( + manifest.qualified_binary_name(name) + if use_platform_suffix + else manifest.binary_name(name) + ), ), ) diff --git a/pex/version.py b/pex/version.py index 8100cb25d..5183b0cb7 100644 --- a/pex/version.py +++ b/pex/version.py @@ -1,4 +1,4 @@ # Copyright 2015 Pex project contributors. # Licensed under the Apache License, Version 2.0 (see LICENSE). -__version__ = "2.18.0" +__version__ = "2.18.1" diff --git a/scripts/create-packages.py b/scripts/create-packages.py index 92dfa6e13..f9c7a730b 100755 --- a/scripts/create-packages.py +++ b/scripts/create-packages.py @@ -240,6 +240,8 @@ def main( rev = describe_rev() sha256, size = describe_file(pex_output_file) + with (pex_output_file.parent / f"{pex_output_file.name}.sha256").open("w") as fp: + fp.write(f"{sha256} *{pex_output_file.name}") hash_table[pex_output_file] = sha256, size print(f"Built Pex PEX @ {rev}:") print(f"sha256: {sha256}") diff --git a/tests/integration/scie/test_discussion_2516.py b/tests/integration/scie/test_discussion_2516.py new file mode 100644 index 000000000..691153154 --- /dev/null +++ b/tests/integration/scie/test_discussion_2516.py @@ -0,0 +1,104 @@ +# Copyright 2024 Pex project contributors. +# Licensed under the Apache License, Version 2.0 (see LICENSE). + +from __future__ import absolute_import + +import glob +import os.path +import subprocess +from textwrap import dedent + +from pex.common import safe_open +from pex.scie import SciePlatform +from pex.typing import TYPE_CHECKING +from testing import make_env, run_pex_command + +if TYPE_CHECKING: + from typing import Any + + import colors # vendor:skip +else: + from pex.third_party import colors + + +def test_discussion_2516_op(tmpdir): + # type: (Any) -> None + + requirements = os.path.join(str(tmpdir), "requirements-pex.txt") + with open(requirements, "w") as fp: + fp.write( + dedent( + """\ + ansicolors + cowsay + """ + ) + ) + + with safe_open(os.path.join(str(tmpdir), "src", "ardia", "cli", "ardia.py"), "w") as fp: + fp.write( + dedent( + """\ + import sys + + import colors + import cowsay + + + def main() -> None: + message = " ".join(sys.argv[1:]) + cowsay.tux(colors.cyan(message)) + """ + ) + ) + + out_dir = os.path.join(str(tmpdir), "build", "pex") + for abbreviated_platform in ( + "linux_aarch64-cp-3.11.9-cp311", + "linux_x86_64-cp-3.11.9-cp311", + "macosx_11_0_arm64-cp-3.11.9-cp311", + "macosx_11_0_x86_64-cp-3.11.9-cp311", + ): + run_pex_command( + args=[ + "--no-build", + "--requirement", + "requirements-pex.txt", + "--entry-point", + "ardia.cli.ardia:main", + "--package", + "ardia@src", + "--output-file", + os.path.join(out_dir, "ardia"), + "--scie", + "eager", + "--scie-only", + "--scie-name-style", + "platform-parent-dir", + "--platform", + abbreviated_platform, + ], + cwd=str(tmpdir), + ).assert_success() + + assert sorted( + [ + "build/pex/linux-aarch64/ardia", + "build/pex/linux-x86_64/ardia", + "build/pex/macos-aarch64/ardia", + "build/pex/macos-x86_64/ardia", + ] + ) == sorted( + os.path.relpath(os.path.join(root, f), str(tmpdir)) + for root, _, files in os.walk(out_dir) + for f in files + ) + assert not glob.glob( + os.path.join(str(tmpdir), "ardia*") + ), "We expected no PEX or scie leaked in the CWD." + + native_scie = os.path.join(out_dir, SciePlatform.CURRENT.value, "ardia") + output = subprocess.check_output( + args=[native_scie, "Tux", "says", "Moo?"], env=make_env(PATH=None) + ).decode("utf-8") + assert "| {msg} |".format(msg=colors.cyan("Tux says Moo?")) in output, output diff --git a/tests/integration/scie/test_pex_scie.py b/tests/integration/scie/test_pex_scie.py index 64258a1ff..3b28033af 100644 --- a/tests/integration/scie/test_pex_scie.py +++ b/tests/integration/scie/test_pex_scie.py @@ -300,7 +300,7 @@ def test_specified_science_binary(tmpdir): local_science_binary = os.path.join(str(tmpdir), "science") with open(local_science_binary, "wb") as write_fp, URLFetcher().get_body_stream( - "https://github.com/a-scie/lift/releases/download/v0.6.0/{binary}".format( + "https://github.com/a-scie/lift/releases/download/v0.8.0/{binary}".format( binary=SciePlatform.CURRENT.qualified_binary_name("science") ) ) as read_fp: @@ -344,7 +344,7 @@ def test_specified_science_binary(tmpdir): cached_science_binaries ), "Expected the local science binary to be used but not cached." assert ( - "0.6.0" + "0.8.0" == subprocess.check_output(args=[local_science_binary, "--version"]).decode("utf-8").strip() ) @@ -1114,12 +1114,24 @@ def test_scie_name_style_platform_file_suffix(tmpdir): def test_scie_name_style_platform_parent_dir(tmpdir): # type: (Any) -> None + foreign_platform = next( + plat for plat in SciePlatform.values() if SciePlatform.CURRENT is not plat + ) dist_dir = os.path.join(str(tmpdir), "dist") output_file = os.path.join(dist_dir, "app") run_pex_command( - args=["--scie", "lazy", "--scie-name-style", "platform-parent-dir", "-o", output_file] + args=[ + "--scie", + "lazy", + "--scie-platform", + str(foreign_platform), + "--scie-name-style", + "platform-parent-dir", + "-o", + output_file, + ] ).assert_success() - assert sorted(["app", SciePlatform.CURRENT.value]) == sorted(os.listdir(dist_dir)) - assert [SciePlatform.CURRENT.binary_name("app")] == os.listdir( - os.path.join(dist_dir, SciePlatform.CURRENT.value) + assert sorted(["app", foreign_platform.value]) == sorted(os.listdir(dist_dir)) + assert [foreign_platform.binary_name("app")] == os.listdir( + os.path.join(dist_dir, foreign_platform.value) )