Repository: pantsbuild/pants

Issue:
Target visibility rules fail to handle dependency on a target in the root of the repo
**Describe the bug**

With this patch in the https://github.com/pantsbuild/example-python

```diff
diff --git a/BUILD b/BUILD
index fca77e4..f25009f 100644
--- a/BUILD
+++ b/BUILD
@@ -5,3 +5,5 @@
 # `python_requirement_library` target. Refer to
 # https://www.pantsbuild.org/docs/python-third-party-dependencies.
 python_requirements(name="reqs")
+
+file(name="license-file", source="LICENSE")
diff --git a/helloworld/greet/BUILD b/helloworld/greet/BUILD
index 6dcc65e..3376617 100644
--- a/helloworld/greet/BUILD
+++ b/helloworld/greet/BUILD
@@ -13,6 +13,7 @@ python_sources(
 # This target sets the metadata for all the Python test files in this directory.
 python_tests(
     name="tests",
+    dependencies=["//:license-file"],
 )
 
 # This target teaches Pants about our JSON file, which allows other targets to depend on it.
@@ -20,3 +21,12 @@ resource(
     name="translations",
     source="translations.json",
 )
+
+__dependencies_rules__(
+    (
+        (python_tests, python_test),
+        "?../*/**",
+    ),
+    # Catch all, allow all.
+    ("*", "*"),
+)
diff --git a/pants.toml b/pants.toml
index 59bdbc4..a357db2 100644
--- a/pants.toml
+++ b/pants.toml
@@ -11,6 +11,7 @@ backend_packages.add = [
   "pants.backend.python.lint.flake8",
   "pants.backend.python.lint.isort",
   "pants.backend.python.typecheck.mypy",
+  "pants.backend.experimental.visibility",
 ]
 
 [anonymous-telemetry]
```

running

```
$ pants --print-stacktrace dependencies helloworld/greet/greeting_test.py
```

fails with

```
20:51:19.46 [ERROR] 1 Exception encountered:

Engine traceback:
  in select
    ..
  in pants.backend.project_info.dependencies.dependencies
    `dependencies` goal

(truncated)

    path = os.path.relpath(path, base + "/.." * self.uplvl)
  File "/home/alexey.tereshenkov/.cache/nce/2b6e146234a4ef2a8946081fc3fbfffe0765b80b690425a49ebe40b47c33445b/cpython-3.9.16+20230507-x86_64-unknown-linux-gnu-install_only.tar.gz/python/lib/python3.9/posixpath.py", line 454, in relpath
    raise ValueError("no path specified")
ValueError: no path specified
```

I have been able to pinpoint this to the usage of `"?../*/**"` in the visibility ruleset; the parser doesn't seem to handle the double dots `..`. Validating dependencies on targets anywhere else in the repo (except the root) or without using double dot in the pattern doesn't cause the error to be thrown.

**Pants version**
2.16 / 2.17 / 2.18

**OS**
Not OS specific

**Additional info**
If it's an implementation constraint, it would be helpful to know how to work around this.



Discussion:

Resolving patch:
diff --git a/src/python/pants/backend/visibility/glob.py b/src/python/pants/backend/visibility/glob.py
--- a/src/python/pants/backend/visibility/glob.py
+++ b/src/python/pants/backend/visibility/glob.py
@@ -129,7 +129,7 @@ def parse(cls, pattern: str, base: str) -> PathGlob:
 
     def _match_path(self, path: str, base: str) -> str | None:
         if self.anchor_mode is PathGlobAnchorMode.INVOKED_PATH:
-            path = os.path.relpath(path, base + "/.." * self.uplvl)
+            path = os.path.relpath(path or ".", base + "/.." * self.uplvl)
             if path.startswith(".."):
                 # The `path` is not in the sub tree of `base`.
                 return None


Test patch:
diff --git a/src/python/pants/backend/visibility/glob_test.py b/src/python/pants/backend/visibility/glob_test.py
--- a/src/python/pants/backend/visibility/glob_test.py
+++ b/src/python/pants/backend/visibility/glob_test.py
@@ -184,6 +184,8 @@ def test_pathglob_parse(base: str, pattern_text: str | tuple[str, str], expected
             (
                 # path, base, expected
                 ("src/foo/bar", "src/qux", "foo/bar"),
+                ("", "snout", ""),
+                ("", "snout/deep", None),
             ),
         ),
     ],