Repository: pantsbuild/pants

Issue:
Pants Pex releases broke w/ venv mode
They originally worked when added for 2.4.0.dev0 in https://github.com/pantsbuild/pants/pull/11591, but broke somewhere in between there and 2.4.0.0rc1 (no PEX releases between then, which was unintentional).

```
❯ wget https://github.com/pantsbuild/pants/releases/download/release_2.4.0rc1/pants.2.4.0rc1.pex
❯ mv pants.2.4.0rc1.pex dist
❯ cd dist
❯ ./pants.2.4.0rc1.pex --print-stacktrace
15:46:51.05 [INFO] initializing scheduler...
15:46:51.14 [ERROR] no path specified
Traceback (most recent call last):
  File "/data/home/eric/.pex/venvs/short/d02a7ea7/lib/python3.7/site-packages/pants/bin/daemon_pants_runner.py", line 125, in single_daemonized_run
    scheduler, options_initializer = self._core.prepare(options_bootstrapper, complete_env)
  File "/data/home/eric/.pex/venvs/short/d02a7ea7/lib/python3.7/site-packages/pants/pantsd/pants_daemon_core.py", line 129, in prepare
    self._initialize(options_fingerprint, options_bootstrapper, env)
  File "/data/home/eric/.pex/venvs/short/d02a7ea7/lib/python3.7/site-packages/pants/pantsd/pants_daemon_core.py", line 104, in _initialize
    raise e
  File "/data/home/eric/.pex/venvs/short/d02a7ea7/lib/python3.7/site-packages/pants/pantsd/pants_daemon_core.py", line 98, in _initialize
    self._services = self._services_constructor(bootstrap_options_values, self._scheduler)
  File "/data/home/eric/.pex/venvs/short/d02a7ea7/lib/python3.7/site-packages/pants/pantsd/pants_daemon.py", line 91, in _setup_services
    bootstrap_options,
  File "/data/home/eric/.pex/venvs/short/d02a7ea7/lib/python3.7/site-packages/pants/option/global_options.py", line 1386, in compute_pantsd_invalidation_globs
    glob_relpath = os.path.relpath(glob, buildroot)
  File "/data/home/eric/.pyenv/versions/3.7.9/lib/python3.7/posixpath.py", line 457, in relpath
    raise ValueError("no path specified")
ValueError: no path specified
```

I time boxed myself investigating this, so am not sure why this is happening yet. However, using `--unzip` mode fixes the issue.

--

Beyond the underlying Pex issue this might reveal, it shows the need for our release process to add a smoke test to building PEXes, something as simple as running `--version`.


Discussion:
The issue is a sys.path entry of `""` - i.e.: cwd.
https://github.com/pantsbuild/pants/blob/d401cc5f790e2a5444379c24e70079de909f4d53/src/python/pants/option/global_options.py#L1364-L1374

Changing the relpath line to `glob_relpath = os.path.relpath(glob or os.getcwd(), buildroot)` fixes.
More generally, the relpath should only be attempted for globs that are absolute paths in the first place.

Resolving patch:
diff --git a/src/python/pants/option/global_options.py b/src/python/pants/option/global_options.py
--- a/src/python/pants/option/global_options.py
+++ b/src/python/pants/option/global_options.py
@@ -1519,13 +1519,16 @@ def compute_pantsd_invalidation_globs(
         for glob in potentially_absolute_globs:
             # NB: We use `relpath` here because these paths are untrusted, and might need to be
             # normalized in addition to being relativized.
-            glob_relpath = os.path.relpath(glob, buildroot)
+            glob_relpath = (
+                os.path.relpath(glob, buildroot) if os.path.isabs(glob) else os.path.normpath(glob)
+            )
             if glob_relpath == "." or glob_relpath.startswith(".."):
                 logger.debug(
                     f"Changes to {glob}, outside of the buildroot, will not be invalidated."
                 )
-            else:
-                invalidation_globs.update([glob_relpath, glob_relpath + "/**"])
+                continue
+
+            invalidation_globs.update([glob_relpath, glob_relpath + "/**"])
 
         # Explicitly specified globs are already relative, and are added verbatim.
         invalidation_globs.update(


Test patch:
diff --git a/src/python/pants/option/global_options_test.py b/src/python/pants/option/global_options_test.py
--- a/src/python/pants/option/global_options_test.py
+++ b/src/python/pants/option/global_options_test.py
@@ -130,9 +130,12 @@ def test_execution_options_remote_addresses() -> None:
 
 
 def test_invalidation_globs() -> None:
-    # Confirm that an un-normalized relative path in the pythonpath is filtered out.
+    # Confirm that an un-normalized relative path in the pythonpath is filtered out, and that an
+    # empty entry (i.e.: a relative path for the current directory) doesn't cause an error.
     suffix = "something-ridiculous"
-    ob = OptionsBootstrapper.create(env={}, args=[f"--pythonpath=../{suffix}"], allow_pantsrc=False)
+    ob = OptionsBootstrapper.create(
+        env={}, args=[f"--pythonpath=../{suffix}", "--pythonpath="], allow_pantsrc=False
+    )
     globs = GlobalOptions.compute_pantsd_invalidation_globs(
         get_buildroot(), ob.bootstrap_options.for_global_scope()
     )