Repository: pantsbuild/pants

Issue:
Filename too long when invoking PEX with --pex-verbosity >=3
Any PEX-using run of Pants at 44017419d (PEX 2.1.33) with `--pex-verbosity=3` (i.e. `./pants test --pex-verbosity=3 src/python/pants/util/::`) fails reproducibly with a line like:
```
/Users/stuhood/.cache/pants/named_caches/pex_root/venvs/34bbe9579368d3ee50226ae26ab367a6fe827866/800ae8ef047bd783543e8282c22bfdbee7b7fca8/pex: File name too long
```
Notably: `--pex-verbosity=1` does not trigger the issue.

Capturing the sandbox of the run using `--no-process-execution-cleanup-local-dirs` allows for reproducing the issue with the `__run.sh` script (have captured a repro). The complete log of `./__run.sh` is attached.

[ftl.log](https://github.com/pantsbuild/pants/files/6127740/ftl.log)

----

The content of the `pants_plugins.pex_pex_shim.sh` file (attached as [pants_plugins.pex_pex_shim.sh.txt](https://github.com/pantsbuild/pants/files/6127756/pants_plugins.pex_pex_shim.sh.txt)) seems to indicate that some of the verbose output gets accidentally embedded in the generated shim script.


Discussion:
It looks like the computed `venv_dir` is capturing the verbose stdout here, and that's getting prepended onto other paths:
https://github.com/pantsbuild/pants/blob/7781df51294b20e71859c9d5dd380d567ec5dde5/src/python/pants/backend/python/util_rules/pex.py#L792-L799
This is a Pex bug: https://github.com/pantsbuild/pex/pull/1268

Resolving patch:
diff --git a/src/python/pants/backend/python/util_rules/pex_cli.py b/src/python/pants/backend/python/util_rules/pex_cli.py
--- a/src/python/pants/backend/python/util_rules/pex_cli.py
+++ b/src/python/pants/backend/python/util_rules/pex_cli.py
@@ -37,7 +37,7 @@ class PexBinary(TemplatedExternalTool):
     name = "pex"
     help = "The PEX (Python EXecutable) tool (https://github.com/pantsbuild/pex)."
 
-    default_version = "v2.1.24"
+    default_version = "v2.1.34"
     default_url_template = "https://github.com/pantsbuild/pex/releases/download/{version}/pex"
 
     @classproperty
@@ -47,8 +47,8 @@ def default_known_versions(cls):
                 (
                     cls.default_version,
                     plat,
-                    "561da5a7c76a8a88567a306fa60dfcb5c6924bb71c18b892080d5c2b3eea7133",
-                    "2936466",
+                    "9b1a959ccb61b3deb64ffeed43a735c7115e414f4de6f96e66adc9e7fc7a757f",
+                    "3597768",
                 )
             )
             for plat in ["darwin", "linux"]
diff --git a/src/python/pants/init/plugin_resolver.py b/src/python/pants/init/plugin_resolver.py
--- a/src/python/pants/init/plugin_resolver.py
+++ b/src/python/pants/init/plugin_resolver.py
@@ -104,7 +104,7 @@ def _resolve_plugins(self) -> Iterable[str]:
             interpreter=self._interpreter,
             cache=self.plugin_cache_dir,
             allow_prereleases=PANTS_SEMVER.is_prerelease,
-            network_configuration=NetworkConfiguration.create(
+            network_configuration=NetworkConfiguration(
                 cert=self._global_options.options.ca_certs_path
             ),
         )


Test patch:
diff --git a/src/python/pants/backend/python/util_rules/pex_test.py b/src/python/pants/backend/python/util_rules/pex_test.py
--- a/src/python/pants/backend/python/util_rules/pex_test.py
+++ b/src/python/pants/backend/python/util_rules/pex_test.py
@@ -478,23 +478,38 @@ def test_resolves_dependencies(rule_runner: RuleRunner) -> None:
 
 
 def test_requirement_constraints(rule_runner: RuleRunner) -> None:
-    # This is intentionally old; a constraint will resolve us to a more modern version.
-    direct_dep = "requests==1.0.0"
-    constraints = [
-        "requests==2.23.0",
-        "certifi==2019.6.16",
-        "chardet==3.0.2",
-        "idna==2.7",
-        "urllib3==1.25.6",
-    ]
-    rule_runner.create_file("constraints.txt", "\n".join(constraints))
+    direct_deps = ["requests>=1.0.0,<=2.23.0"]
 
-    pex_info = create_pex_and_get_pex_info(
+    def assert_direct_requirements(pex_info):
+        assert set(Requirement.parse(r) for r in pex_info["requirements"]) == set(
+            Requirement.parse(d) for d in direct_deps
+        )
+
+    # Unconstrained, we should always pick the top of the range (requests 2.23.0) since the top of
+    # the range is a transitive closure over universal wheels.
+    direct_pex_info = create_pex_and_get_pex_info(
+        rule_runner, requirements=PexRequirements(direct_deps)
+    )
+    assert_direct_requirements(direct_pex_info)
+    assert {
+        "certifi-2020.12.5-py2.py3-none-any.whl",
+        "chardet-3.0.4-py2.py3-none-any.whl",
+        "idna-2.10-py2.py3-none-any.whl",
+        "requests-2.23.0-py2.py3-none-any.whl",
+        "urllib3-1.25.11-py2.py3-none-any.whl",
+    } == set(direct_pex_info["distributions"].keys())
+
+    constraints = ["requests==2.0.0"]
+    rule_runner.create_file("constraints.txt", "\n".join(constraints))
+    constrained_pex_info = create_pex_and_get_pex_info(
         rule_runner,
-        requirements=PexRequirements([direct_dep]),
+        requirements=PexRequirements(direct_deps),
         additional_pants_args=("--python-setup-requirement-constraints=constraints.txt",),
     )
-    assert set(parse_requirements(pex_info["requirements"])) == set(parse_requirements(constraints))
+    assert_direct_requirements(constrained_pex_info)
+    assert {"requests-2.0.0-py2.py3-none-any.whl"} == set(
+        constrained_pex_info["distributions"].keys()
+    )
 
 
 def test_entry_point(rule_runner: RuleRunner) -> None: