Repository: conan-io/conan

Issue:
[bug] `conan list` filtering option asks users to use scope patterns when those don't work in that context
### Describe the bug

When running `conan install` with the `--filter-options` argument, you're supposed _not_ to scope the option. But if you do so, you get a warning like
```
WARN: legacy: Unscoped option definition is ambiguous.
Use '&:shared=True' to refer to the current package.
Use '*:shared=True' or other pattern if the intent was to apply to dependencies
```

which disappears if you use a scope, but then the filter does not work properly

### How to reproduce it

_No response_


Discussion:
I might have missremembered and you're actually supposed to scope it with `*:`. Still, the point stands than then it's not intuitive and we should check if we can do something about it
The only test that applies is ``c.run(f"list *:* -fs os=Windows -fo *:shared=False --format=json {r}")``, so I am not sure if the intent is not to scope options. Actually, the warnings were added with the intention to always scope options everywhere, including profiles, and also in the ``--filter-options``. The idea is that the filter will be what you would put in a profile, and get the same warning as if you use it in a profile.

The test doing it seems to work: https://github.com/conan-io/conan/blob/88d03589084167471262d004a183fea39985a616/test/integration/command_v2/list_test.py#L891, with the scope.



Patch:
diff --git a/conan/api/subapi/list.py b/conan/api/subapi/list.py
index 1e92cf74d98..a7452ecfe51 100644
--- a/conan/api/subapi/list.py
+++ b/conan/api/subapi/list.py
@@ -104,7 +104,9 @@ def filter_packages_profile(packages, profile, ref):
             options = data.get("options", {})
             for k, v in options.items():
                 for pattern, pattern_options in profile_options.items():
-                    if ref_matches(ref, pattern, None):
+                    # Accept &: as referring to the current package being listed,
+                    # even if it's not technically a "consumer"
+                    if ref_matches(ref, pattern, True):
                         value = pattern_options.get_safe(k)
                         if value is not None and value != v:
                             options_match = False


Test patch:
diff --git a/test/integration/command_v2/list_test.py b/test/integration/command_v2/list_test.py
index b73c9742ee5..0139bb5d5c2 100644
--- a/test/integration/command_v2/list_test.py
+++ b/test/integration/command_v2/list_test.py
@@ -896,3 +896,13 @@ def test_list_filter(self, remote):
         assert len(pkg["packages"]) == 1
         settings = pkg["packages"]["d2e97769569ac0a583d72c10a37d5ca26de7c9fa"]["info"]["settings"]
         assert settings == {"arch": "x86", "os": "Windows"}
+
+        # &: will also match every package being listed, as if it was a consumer
+        c.run(f"list *:* -fo &:shared=False --format=json {r}")
+        result = json.loads(c.stdout)
+        header = result[pkg_key]["header/1.0"]["revisions"]["747cc49983b14bdd00df50a0671bd8b3"]
+        assert header["packages"] == {"da39a3ee5e6b4b0d3255bfef95601890afd80709": {"info": {}}}
+        pkg = result[pkg_key]["pkg/1.0"]["revisions"]["03591c8b22497dd74214e08b3bf2a56f"]
+        assert len(pkg["packages"]) == 2
+        settings = pkg["packages"]["d2e97769569ac0a583d72c10a37d5ca26de7c9fa"]["info"]["settings"]
+        assert settings == {"arch": "x86", "os": "Windows"}