Repository: conan-io/conan
Pull request #16233 (2024-05-10 10:15:32)

options patterns warning
Changelog: Fix: Warn when using ``options`` without pattern scope, to improve UX of users expecting ``-o shared=True`` to apply to dependencies.
Docs: https://github.com/conan-io/docs/pull/3720


Patch:
diff --git a/conan/api/subapi/profiles.py b/conan/api/subapi/profiles.py
index f6d927048..6184a60cc 100644
--- a/conan/api/subapi/profiles.py
+++ b/conan/api/subapi/profiles.py
@@ -1,5 +1,6 @@
 import os
 
+from conan.api.output import ConanOutput
 from conan.internal.cache.home_paths import HomePaths
 
 from conans.client.loader import load_python_file
@@ -97,6 +98,11 @@ class ProfilesAPI:
         profile.conf.validate()
         # Apply the new_config to the profiles the global one, so recipes get it too
         profile.conf.rebase_conf_definition(global_conf)
+        for k, v in sorted(profile.options._package_options.items()):
+            ConanOutput().warning("Unscoped option definition is ambiguous.\n"
+                                  f"Use '&:{k}={v}' to refer to the current package.\n"
+                                  f"Use '*:{k}={v}' or other pattern if the intent was to apply to "
+                                  f"dependencies", warn_tag="legacy")
         return profile
 
     def get_path(self, profile, cwd=None, exists=True):


Test patch:
diff --git a/conans/test/integration/command/test_profile.py b/conans/test/integration/command/test_profile.py
index db8e6d7b7..8de40adbb 100644
--- a/conans/test/integration/command/test_profile.py
+++ b/conans/test/integration/command/test_profile.py
@@ -43,7 +43,7 @@ def test_shorthand_syntax():
     tc.run(
         "profile show -o:a=both_options=True -pr:a=profile -s:a=os=WindowsCE -s:a=os.platform=conan -c:a=user.conf:cli=True -f=json")
 
-    out = json.loads(tc.out)
+    out = json.loads(tc.stdout)
     assert out == {'build': {'build_env': '',
                              'conf': {'user.conf:cli': True, 'user:profile': True},
                              'options': {'both_options': 'True'},
@@ -93,7 +93,7 @@ def test_shorthand_syntax():
                             'tool_requires': {}}}
 
     tc.run("profile show -pr:a=pre -pr:h=post -f=json")
-    out = json.loads(tc.out)
+    out = json.loads(tc.stdout)
     assert out == {'build': {'build_env': '',
                              'conf': {},
                              'options': {},
@@ -112,7 +112,7 @@ def test_shorthand_syntax():
                             'tool_requires': {}}}
 
     tc.run("profile show -pr:a=pre -o:b foo=False -o:a foo=True -o:h foo=False -f=json")
-    out = json.loads(tc.out)
+    out = json.loads(tc.stdout)
     assert out == {'build': {'build_env': '',
                              'conf': {},
                              'options': {'foo': 'True'},
diff --git a/conans/test/integration/options/options_test.py b/conans/test/integration/options/options_test.py
index 65f4d77e7..fcc825765 100644
--- a/conans/test/integration/options/options_test.py
+++ b/conans/test/integration/options/options_test.py
@@ -23,6 +23,7 @@ class OptionsTest(unittest.TestCase):
         client.run("create . --name=pkg --version=0.1 --user=user --channel=testing -o *:shared=1")
         self.assertIn("pkg/0.1@user/testing: BUILD SHARED: 1", client.out)
         client.run("create . --name=pkg --version=0.1 --user=user --channel=testing -o shared=2")
+        assert 'legacy: Unscoped option definition is ambiguous' in client.out
         self.assertIn("pkg/0.1@user/testing: BUILD SHARED: 2", client.out)
         # With test_package
         client.save({"conanfile.py": conanfile,