We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[feature] Supress Conan 2 compatibility message
### What is your suggestion?

When a recipe fails to build Conan 2 will print a migration note regarding v2 compatibility:

```
*********************************************************
Recipe 'conanfile.py (...)' cannot build its binary
It is possible that this recipe is not Conan 2.0 ready
If the recipe comes from ConanCenter check: https://conan.io/cci-v2.html
If it is your recipe, check if it is updated to 2.0
*********************************************************
```

This is confusing our developers though because they assume a Conan issue when in fact its a good old compiler failure right above that flashy message. Looking at the code I found now way to disable this - is there any plans to offer an option for that?

### Have you read the CONTRIBUTING guide?

- [X] I've read the CONTRIBUTING guide

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `conan/cli/cli.py`
Content:
```
1 import importlib
2 import os
3 import pkgutil
4 import re
5 import signal
6 import sys
7 import textwrap
8 import traceback
9 from collections import defaultdict
10 from difflib import get_close_matches
11 from inspect import getmembers
12 
13 from conan.api.conan_api import ConanAPI
14 from conan.api.output import ConanOutput, Color, cli_out_write, LEVEL_TRACE
15 from conan.cli.command import ConanSubCommand
16 from conan.cli.exit_codes import SUCCESS, ERROR_MIGRATION, ERROR_GENERAL, USER_CTRL_C, \
17     ERROR_SIGTERM, USER_CTRL_BREAK, ERROR_INVALID_CONFIGURATION, ERROR_UNEXPECTED
18 from conan.internal.cache.home_paths import HomePaths
19 from conans import __version__ as client_version
20 from conan.errors import ConanException, ConanInvalidConfiguration, ConanMigrationError
21 from conans.util.files import exception_message_safe
22 
23 
24 class Cli:
25     """A single command of the conan application, with all the first level commands. Manages the
26     parsing of parameters and delegates functionality to the conan python api. It can also show the
27     help of the tool.
28     """
29 
30     def __init__(self, conan_api):
31         assert isinstance(conan_api, ConanAPI), \
32             "Expected 'Conan' type, got '{}'".format(type(conan_api))
33         self._conan_api = conan_api
34         self._groups = defaultdict(list)
35         self._commands = {}
36 
37     def _add_commands(self):
38         conan_commands_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "commands")
39         for module in pkgutil.iter_modules([conan_commands_path]):
40             module_name = module[1]
41             self._add_command("conan.cli.commands.{}".format(module_name), module_name)
42 
43         custom_commands_path = HomePaths(self._conan_api.cache_folder).custom_commands_path
44         if not os.path.isdir(custom_commands_path):
45             return
46 
47         sys.path.append(custom_commands_path)
48         for module in pkgutil.iter_modules([custom_commands_path]):
49             module_name = module[1]
50             if module_name.startswith("cmd_"):
51                 try:
52                     self._add_command(module_name, module_name.replace("cmd_", ""))
53                 except Exception as e:
54                     ConanOutput().error("Error loading custom command "
55                                         "'{}.py': {}".format(module_name, e))
56         # layers
57         for folder in os.listdir(custom_commands_path):
58             layer_folder = os.path.join(custom_commands_path, folder)
59             sys.path.append(layer_folder)
60             if not os.path.isdir(layer_folder):
61                 continue
62             for module in pkgutil.iter_modules([layer_folder]):
63                 module_name = module[1]
64                 if module_name.startswith("cmd_"):
65                     module_path = f"{folder}.{module_name}"
66                     try:
67                         self._add_command(module_path, module_name.replace("cmd_", ""),
68                                           package=folder)
69                     except Exception as e:
70                         ConanOutput().error(f"Error loading custom command {module_path}: {e}")
71 
72     def _add_command(self, import_path, method_name, package=None):
73         try:
74             imported_module = importlib.import_module(import_path)
75             command_wrapper = getattr(imported_module, method_name)
76             if command_wrapper.doc:
77                 name = f"{package}:{command_wrapper.name}" if package else command_wrapper.name
78                 self._commands[name] = command_wrapper
79                 self._groups[command_wrapper.group].append(name)
80             for name, value in getmembers(imported_module):
81                 if isinstance(value, ConanSubCommand):
82                     if name.startswith("{}_".format(method_name)):
83                         command_wrapper.add_subcommand(value)
84                     else:
85                         raise ConanException("The name for the subcommand method should "
86                                              "begin with the main command name + '_'. "
87                                              "i.e. {}_<subcommand_name>".format(method_name))
88         except AttributeError:
89             raise ConanException("There is no {} method defined in {}".format(method_name,
90                                                                               import_path))
91 
92     def _print_similar(self, command):
93         """ Looks for similar commands and prints them if found.
94         """
95         output = ConanOutput()
96         matches = get_close_matches(
97             word=command, possibilities=self._commands.keys(), n=5, cutoff=0.75)
98 
99         if len(matches) == 0:
100             return
101 
102         if len(matches) > 1:
103             output.info("The most similar commands are")
104         else:
105             output.info("The most similar command is")
106 
107         for match in matches:
108             output.info("    %s" % match)
109 
110         output.writeln("")
111 
112     def _output_help_cli(self):
113         """
114         Prints a summary of all commands.
115         """
116         max_len = max((len(c) for c in self._commands)) + 1
117         line_format = '{{: <{}}}'.format(max_len)
118 
119         for group_name, comm_names in sorted(self._groups.items()):
120             cli_out_write("\n" + group_name + " commands", Color.BRIGHT_MAGENTA)
121             for name in comm_names:
122                 # future-proof way to ensure tabular formatting
123                 cli_out_write(line_format.format(name), Color.GREEN, endline="")
124 
125                 # Help will be all the lines up to the first empty one
126                 docstring_lines = self._commands[name].doc.split('\n')
127                 start = False
128                 data = []
129                 for line in docstring_lines:
130                     line = line.strip()
131                     if not line:
132                         if start:
133                             break
134                         start = True
135                         continue
136                     data.append(line)
137 
138                 txt = textwrap.fill(' '.join(data), 80, subsequent_indent=" " * (max_len + 2))
139                 cli_out_write(txt)
140 
141         cli_out_write("")
142         cli_out_write('Type "conan <command> -h" for help', Color.BRIGHT_MAGENTA)
143 
144     def run(self, *args):
145         """ Entry point for executing commands, dispatcher to class
146         methods
147         """
148         output = ConanOutput()
149         self._add_commands()
150         try:
151             command_argument = args[0][0]
152         except IndexError:  # No parameters
153             self._output_help_cli()
154             return
155         try:
156             command = self._commands[command_argument]
157         except KeyError as exc:
158             if command_argument in ["-v", "--version"]:
159                 cli_out_write("Conan version %s" % client_version)
160                 return
161 
162             if command_argument in ["-h", "--help"]:
163                 self._output_help_cli()
164                 return
165 
166             output.info("'%s' is not a Conan command. See 'conan --help'." % command_argument)
167             output.info("")
168             self._print_similar(command_argument)
169             raise ConanException("Unknown command %s" % str(exc))
170 
171         try:
172             command.run(self._conan_api, args[0][1:])
173         except Exception as e:
174             # must be a local-import to get updated value
175             if ConanOutput.level_allowed(LEVEL_TRACE):
176                 print(traceback.format_exc(), file=sys.stderr)
177             self._conan2_migrate_recipe_msg(e)
178             raise
179 
180     @staticmethod
181     def _conan2_migrate_recipe_msg(exception):
182         message = str(exception)
183 
184         result = re.search(r"Package '(.*)' not resolved: .*: Cannot load recipe", message)
185         if result:
186             pkg = result.group(1)
187             error = "*********************************************************\n" \
188                     f"Recipe '{pkg}' seems broken.\n" \
189                     f"It is possible that this recipe is not Conan 2.0 ready\n"\
190                     "If the recipe comes from ConanCenter, report it at https://github.com/conan-io/conan-center-index/issues\n" \
191                     "If it is your recipe, check if it is updated to 2.0\n" \
192                     "*********************************************************\n"
193             ConanOutput().writeln(error, fg=Color.BRIGHT_MAGENTA)
194         result = re.search(r"(.*): Error in build\(\) method, line", message)
195         if result:
196             pkg = result.group(1)
197             error = "*********************************************************\n" \
198                     f"Recipe '{pkg}' cannot build its binary\n" \
199                     f"It is possible that this recipe is not Conan 2.0 ready\n" \
200                     "If the recipe comes from ConanCenter, report it at https://github.com/conan-io/conan-center-index/issues\n" \
201                     "If it is your recipe, check if it is updated to 2.0\n" \
202                     "*********************************************************\n"
203             ConanOutput().writeln(error, fg=Color.BRIGHT_MAGENTA)
204 
205     @staticmethod
206     def exception_exit_error(exception):
207         output = ConanOutput()
208         if exception is None:
209             return SUCCESS
210         if isinstance(exception, ConanInvalidConfiguration):
211             output.error(exception)
212             return ERROR_INVALID_CONFIGURATION
213         if isinstance(exception, ConanException):
214             output.error(exception)
215             return ERROR_GENERAL
216         if isinstance(exception, SystemExit):
217             if exception.code != 0:
218                 output.error("Exiting with code: %d" % exception.code)
219             return exception.code
220 
221         assert isinstance(exception, Exception)
222         output.error(traceback.format_exc())
223         msg = exception_message_safe(exception)
224         output.error(msg)
225         return ERROR_UNEXPECTED
226 
227 
228 def main(args):
229     """ main entry point of the conan application, using a Command to
230     parse parameters
231 
232     Exit codes for conan command:
233 
234         0: Success (done)
235         1: General ConanException error (done)
236         2: Migration error
237         3: Ctrl+C
238         4: Ctrl+Break
239         5: SIGTERM
240         6: Invalid configuration (done)
241     """
242 
243     try:
244         conan_api = ConanAPI()
245     except ConanMigrationError:  # Error migrating
246         sys.exit(ERROR_MIGRATION)
247     except ConanException as e:
248         sys.stderr.write("Error in Conan initialization: {}".format(e))
249         sys.exit(ERROR_GENERAL)
250 
251     def ctrl_c_handler(_, __):
252         print('You pressed Ctrl+C!')
253         sys.exit(USER_CTRL_C)
254 
255     def sigterm_handler(_, __):
256         print('Received SIGTERM!')
257         sys.exit(ERROR_SIGTERM)
258 
259     def ctrl_break_handler(_, __):
260         print('You pressed Ctrl+Break!')
261         sys.exit(USER_CTRL_BREAK)
262 
263     signal.signal(signal.SIGINT, ctrl_c_handler)
264     signal.signal(signal.SIGTERM, sigterm_handler)
265 
266     if sys.platform == 'win32':
267         signal.signal(signal.SIGBREAK, ctrl_break_handler)
268 
269     cli = Cli(conan_api)
270     error = SUCCESS
271     try:
272         cli.run(args)
273     except BaseException as e:
274         error = cli.exception_exit_error(e)
275     sys.exit(error)
276
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/conan/cli/cli.py b/conan/cli/cli.py
--- a/conan/cli/cli.py
+++ b/conan/cli/cli.py
@@ -191,16 +191,6 @@
                     "If it is your recipe, check if it is updated to 2.0\n" \
                     "*********************************************************\n"
             ConanOutput().writeln(error, fg=Color.BRIGHT_MAGENTA)
-        result = re.search(r"(.*): Error in build\(\) method, line", message)
-        if result:
-            pkg = result.group(1)
-            error = "*********************************************************\n" \
-                    f"Recipe '{pkg}' cannot build its binary\n" \
-                    f"It is possible that this recipe is not Conan 2.0 ready\n" \
-                    "If the recipe comes from ConanCenter, report it at https://github.com/conan-io/conan-center-index/issues\n" \
-                    "If it is your recipe, check if it is updated to 2.0\n" \
-                    "*********************************************************\n"
-            ConanOutput().writeln(error, fg=Color.BRIGHT_MAGENTA)
 
     @staticmethod
     def exception_exit_error(exception):

{"golden_diff": "diff --git a/conan/cli/cli.py b/conan/cli/cli.py\n--- a/conan/cli/cli.py\n+++ b/conan/cli/cli.py\n@@ -191,16 +191,6 @@\n                     \"If it is your recipe, check if it is updated to 2.0\\n\" \\\n                     \"*********************************************************\\n\"\n             ConanOutput().writeln(error, fg=Color.BRIGHT_MAGENTA)\n-        result = re.search(r\"(.*): Error in build\\(\\) method, line\", message)\n-        if result:\n-            pkg = result.group(1)\n-            error = \"*********************************************************\\n\" \\\n-                    f\"Recipe '{pkg}' cannot build its binary\\n\" \\\n-                    f\"It is possible that this recipe is not Conan 2.0 ready\\n\" \\\n-                    \"If the recipe comes from ConanCenter, report it at https://github.com/conan-io/conan-center-index/issues\\n\" \\\n-                    \"If it is your recipe, check if it is updated to 2.0\\n\" \\\n-                    \"*********************************************************\\n\"\n-            ConanOutput().writeln(error, fg=Color.BRIGHT_MAGENTA)\n \n     @staticmethod\n     def exception_exit_error(exception):\n", "issue": "[feature] Supress Conan 2 compatibility message\n### What is your suggestion?\r\n\r\nWhen a recipe fails to build Conan 2 will print a migration note regarding v2 compatibility:\r\n\r\n```\r\n*********************************************************\r\nRecipe 'conanfile.py (...)' cannot build its binary\r\nIt is possible that this recipe is not Conan 2.0 ready\r\nIf the recipe comes from ConanCenter check: https://conan.io/cci-v2.html\r\nIf it is your recipe, check if it is updated to 2.0\r\n*********************************************************\r\n```\r\n\r\nThis is confusing our developers though because they assume a Conan issue when in fact its a good old compiler failure right above that flashy message. Looking at the code I found now way to disable this - is there any plans to offer an option for that?\r\n\r\n### Have you read the CONTRIBUTING guide?\r\n\r\n- [X] I've read the CONTRIBUTING guide\n", "before_files": [{"content": "import importlib\nimport os\nimport pkgutil\nimport re\nimport signal\nimport sys\nimport textwrap\nimport traceback\nfrom collections import defaultdict\nfrom difflib import get_close_matches\nfrom inspect import getmembers\n\nfrom conan.api.conan_api import ConanAPI\nfrom conan.api.output import ConanOutput, Color, cli_out_write, LEVEL_TRACE\nfrom conan.cli.command import ConanSubCommand\nfrom conan.cli.exit_codes import SUCCESS, ERROR_MIGRATION, ERROR_GENERAL, USER_CTRL_C, \\\n    ERROR_SIGTERM, USER_CTRL_BREAK, ERROR_INVALID_CONFIGURATION, ERROR_UNEXPECTED\nfrom conan.internal.cache.home_paths import HomePaths\nfrom conans import __version__ as client_version\nfrom conan.errors import ConanException, ConanInvalidConfiguration, ConanMigrationError\nfrom conans.util.files import exception_message_safe\n\n\nclass Cli:\n    \"\"\"A single command of the conan application, with all the first level commands. Manages the\n    parsing of parameters and delegates functionality to the conan python api. It can also show the\n    help of the tool.\n    \"\"\"\n\n    def __init__(self, conan_api):\n        assert isinstance(conan_api, ConanAPI), \\\n            \"Expected 'Conan' type, got '{}'\".format(type(conan_api))\n        self._conan_api = conan_api\n        self._groups = defaultdict(list)\n        self._commands = {}\n\n    def _add_commands(self):\n        conan_commands_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), \"commands\")\n        for module in pkgutil.iter_modules([conan_commands_path]):\n            module_name = module[1]\n            self._add_command(\"conan.cli.commands.{}\".format(module_name), module_name)\n\n        custom_commands_path = HomePaths(self._conan_api.cache_folder).custom_commands_path\n        if not os.path.isdir(custom_commands_path):\n            return\n\n        sys.path.append(custom_commands_path)\n        for module in pkgutil.iter_modules([custom_commands_path]):\n            module_name = module[1]\n            if module_name.startswith(\"cmd_\"):\n                try:\n                    self._add_command(module_name, module_name.replace(\"cmd_\", \"\"))\n                except Exception as e:\n                    ConanOutput().error(\"Error loading custom command \"\n                                        \"'{}.py': {}\".format(module_name, e))\n        # layers\n        for folder in os.listdir(custom_commands_path):\n            layer_folder = os.path.join(custom_commands_path, folder)\n            sys.path.append(layer_folder)\n            if not os.path.isdir(layer_folder):\n                continue\n            for module in pkgutil.iter_modules([layer_folder]):\n                module_name = module[1]\n                if module_name.startswith(\"cmd_\"):\n                    module_path = f\"{folder}.{module_name}\"\n                    try:\n                        self._add_command(module_path, module_name.replace(\"cmd_\", \"\"),\n                                          package=folder)\n                    except Exception as e:\n                        ConanOutput().error(f\"Error loading custom command {module_path}: {e}\")\n\n    def _add_command(self, import_path, method_name, package=None):\n        try:\n            imported_module = importlib.import_module(import_path)\n            command_wrapper = getattr(imported_module, method_name)\n            if command_wrapper.doc:\n                name = f\"{package}:{command_wrapper.name}\" if package else command_wrapper.name\n                self._commands[name] = command_wrapper\n                self._groups[command_wrapper.group].append(name)\n            for name, value in getmembers(imported_module):\n                if isinstance(value, ConanSubCommand):\n                    if name.startswith(\"{}_\".format(method_name)):\n                        command_wrapper.add_subcommand(value)\n                    else:\n                        raise ConanException(\"The name for the subcommand method should \"\n                                             \"begin with the main command name + '_'. \"\n                                             \"i.e. {}_<subcommand_name>\".format(method_name))\n        except AttributeError:\n            raise ConanException(\"There is no {} method defined in {}\".format(method_name,\n                                                                              import_path))\n\n    def _print_similar(self, command):\n        \"\"\" Looks for similar commands and prints them if found.\n        \"\"\"\n        output = ConanOutput()\n        matches = get_close_matches(\n            word=command, possibilities=self._commands.keys(), n=5, cutoff=0.75)\n\n        if len(matches) == 0:\n            return\n\n        if len(matches) > 1:\n            output.info(\"The most similar commands are\")\n        else:\n            output.info(\"The most similar command is\")\n\n        for match in matches:\n            output.info(\"    %s\" % match)\n\n        output.writeln(\"\")\n\n    def _output_help_cli(self):\n        \"\"\"\n        Prints a summary of all commands.\n        \"\"\"\n        max_len = max((len(c) for c in self._commands)) + 1\n        line_format = '{{: <{}}}'.format(max_len)\n\n        for group_name, comm_names in sorted(self._groups.items()):\n            cli_out_write(\"\\n\" + group_name + \" commands\", Color.BRIGHT_MAGENTA)\n            for name in comm_names:\n                # future-proof way to ensure tabular formatting\n                cli_out_write(line_format.format(name), Color.GREEN, endline=\"\")\n\n                # Help will be all the lines up to the first empty one\n                docstring_lines = self._commands[name].doc.split('\\n')\n                start = False\n                data = []\n                for line in docstring_lines:\n                    line = line.strip()\n                    if not line:\n                        if start:\n                            break\n                        start = True\n                        continue\n                    data.append(line)\n\n                txt = textwrap.fill(' '.join(data), 80, subsequent_indent=\" \" * (max_len + 2))\n                cli_out_write(txt)\n\n        cli_out_write(\"\")\n        cli_out_write('Type \"conan <command> -h\" for help', Color.BRIGHT_MAGENTA)\n\n    def run(self, *args):\n        \"\"\" Entry point for executing commands, dispatcher to class\n        methods\n        \"\"\"\n        output = ConanOutput()\n        self._add_commands()\n        try:\n            command_argument = args[0][0]\n        except IndexError:  # No parameters\n            self._output_help_cli()\n            return\n        try:\n            command = self._commands[command_argument]\n        except KeyError as exc:\n            if command_argument in [\"-v\", \"--version\"]:\n                cli_out_write(\"Conan version %s\" % client_version)\n                return\n\n            if command_argument in [\"-h\", \"--help\"]:\n                self._output_help_cli()\n                return\n\n            output.info(\"'%s' is not a Conan command. See 'conan --help'.\" % command_argument)\n            output.info(\"\")\n            self._print_similar(command_argument)\n            raise ConanException(\"Unknown command %s\" % str(exc))\n\n        try:\n            command.run(self._conan_api, args[0][1:])\n        except Exception as e:\n            # must be a local-import to get updated value\n            if ConanOutput.level_allowed(LEVEL_TRACE):\n                print(traceback.format_exc(), file=sys.stderr)\n            self._conan2_migrate_recipe_msg(e)\n            raise\n\n    @staticmethod\n    def _conan2_migrate_recipe_msg(exception):\n        message = str(exception)\n\n        result = re.search(r\"Package '(.*)' not resolved: .*: Cannot load recipe\", message)\n        if result:\n            pkg = result.group(1)\n            error = \"*********************************************************\\n\" \\\n                    f\"Recipe '{pkg}' seems broken.\\n\" \\\n                    f\"It is possible that this recipe is not Conan 2.0 ready\\n\"\\\n                    \"If the recipe comes from ConanCenter, report it at https://github.com/conan-io/conan-center-index/issues\\n\" \\\n                    \"If it is your recipe, check if it is updated to 2.0\\n\" \\\n                    \"*********************************************************\\n\"\n            ConanOutput().writeln(error, fg=Color.BRIGHT_MAGENTA)\n        result = re.search(r\"(.*): Error in build\\(\\) method, line\", message)\n        if result:\n            pkg = result.group(1)\n            error = \"*********************************************************\\n\" \\\n                    f\"Recipe '{pkg}' cannot build its binary\\n\" \\\n                    f\"It is possible that this recipe is not Conan 2.0 ready\\n\" \\\n                    \"If the recipe comes from ConanCenter, report it at https://github.com/conan-io/conan-center-index/issues\\n\" \\\n                    \"If it is your recipe, check if it is updated to 2.0\\n\" \\\n                    \"*********************************************************\\n\"\n            ConanOutput().writeln(error, fg=Color.BRIGHT_MAGENTA)\n\n    @staticmethod\n    def exception_exit_error(exception):\n        output = ConanOutput()\n        if exception is None:\n            return SUCCESS\n        if isinstance(exception, ConanInvalidConfiguration):\n            output.error(exception)\n            return ERROR_INVALID_CONFIGURATION\n        if isinstance(exception, ConanException):\n            output.error(exception)\n            return ERROR_GENERAL\n        if isinstance(exception, SystemExit):\n            if exception.code != 0:\n                output.error(\"Exiting with code: %d\" % exception.code)\n            return exception.code\n\n        assert isinstance(exception, Exception)\n        output.error(traceback.format_exc())\n        msg = exception_message_safe(exception)\n        output.error(msg)\n        return ERROR_UNEXPECTED\n\n\ndef main(args):\n    \"\"\" main entry point of the conan application, using a Command to\n    parse parameters\n\n    Exit codes for conan command:\n\n        0: Success (done)\n        1: General ConanException error (done)\n        2: Migration error\n        3: Ctrl+C\n        4: Ctrl+Break\n        5: SIGTERM\n        6: Invalid configuration (done)\n    \"\"\"\n\n    try:\n        conan_api = ConanAPI()\n    except ConanMigrationError:  # Error migrating\n        sys.exit(ERROR_MIGRATION)\n    except ConanException as e:\n        sys.stderr.write(\"Error in Conan initialization: {}\".format(e))\n        sys.exit(ERROR_GENERAL)\n\n    def ctrl_c_handler(_, __):\n        print('You pressed Ctrl+C!')\n        sys.exit(USER_CTRL_C)\n\n    def sigterm_handler(_, __):\n        print('Received SIGTERM!')\n        sys.exit(ERROR_SIGTERM)\n\n    def ctrl_break_handler(_, __):\n        print('You pressed Ctrl+Break!')\n        sys.exit(USER_CTRL_BREAK)\n\n    signal.signal(signal.SIGINT, ctrl_c_handler)\n    signal.signal(signal.SIGTERM, sigterm_handler)\n\n    if sys.platform == 'win32':\n        signal.signal(signal.SIGBREAK, ctrl_break_handler)\n\n    cli = Cli(conan_api)\n    error = SUCCESS\n    try:\n        cli.run(args)\n    except BaseException as e:\n        error = cli.exception_exit_error(e)\n    sys.exit(error)\n", "path": "conan/cli/cli.py"}], "after_files": [{"content": "import importlib\nimport os\nimport pkgutil\nimport re\nimport signal\nimport sys\nimport textwrap\nimport traceback\nfrom collections import defaultdict\nfrom difflib import get_close_matches\nfrom inspect import getmembers\n\nfrom conan.api.conan_api import ConanAPI\nfrom conan.api.output import ConanOutput, Color, cli_out_write, LEVEL_TRACE\nfrom conan.cli.command import ConanSubCommand\nfrom conan.cli.exit_codes import SUCCESS, ERROR_MIGRATION, ERROR_GENERAL, USER_CTRL_C, \\\n    ERROR_SIGTERM, USER_CTRL_BREAK, ERROR_INVALID_CONFIGURATION, ERROR_UNEXPECTED\nfrom conan.internal.cache.home_paths import HomePaths\nfrom conans import __version__ as client_version\nfrom conan.errors import ConanException, ConanInvalidConfiguration, ConanMigrationError\nfrom conans.util.files import exception_message_safe\n\n\nclass Cli:\n    \"\"\"A single command of the conan application, with all the first level commands. Manages the\n    parsing of parameters and delegates functionality to the conan python api. It can also show the\n    help of the tool.\n    \"\"\"\n\n    def __init__(self, conan_api):\n        assert isinstance(conan_api, ConanAPI), \\\n            \"Expected 'Conan' type, got '{}'\".format(type(conan_api))\n        self._conan_api = conan_api\n        self._groups = defaultdict(list)\n        self._commands = {}\n\n    def _add_commands(self):\n        conan_commands_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), \"commands\")\n        for module in pkgutil.iter_modules([conan_commands_path]):\n            module_name = module[1]\n            self._add_command(\"conan.cli.commands.{}\".format(module_name), module_name)\n\n        custom_commands_path = HomePaths(self._conan_api.cache_folder).custom_commands_path\n        if not os.path.isdir(custom_commands_path):\n            return\n\n        sys.path.append(custom_commands_path)\n        for module in pkgutil.iter_modules([custom_commands_path]):\n            module_name = module[1]\n            if module_name.startswith(\"cmd_\"):\n                try:\n                    self._add_command(module_name, module_name.replace(\"cmd_\", \"\"))\n                except Exception as e:\n                    ConanOutput().error(\"Error loading custom command \"\n                                        \"'{}.py': {}\".format(module_name, e))\n        # layers\n        for folder in os.listdir(custom_commands_path):\n            layer_folder = os.path.join(custom_commands_path, folder)\n            sys.path.append(layer_folder)\n            if not os.path.isdir(layer_folder):\n                continue\n            for module in pkgutil.iter_modules([layer_folder]):\n                module_name = module[1]\n                if module_name.startswith(\"cmd_\"):\n                    module_path = f\"{folder}.{module_name}\"\n                    try:\n                        self._add_command(module_path, module_name.replace(\"cmd_\", \"\"),\n                                          package=folder)\n                    except Exception as e:\n                        ConanOutput().error(f\"Error loading custom command {module_path}: {e}\")\n\n    def _add_command(self, import_path, method_name, package=None):\n        try:\n            imported_module = importlib.import_module(import_path)\n            command_wrapper = getattr(imported_module, method_name)\n            if command_wrapper.doc:\n                name = f\"{package}:{command_wrapper.name}\" if package else command_wrapper.name\n                self._commands[name] = command_wrapper\n                self._groups[command_wrapper.group].append(name)\n            for name, value in getmembers(imported_module):\n                if isinstance(value, ConanSubCommand):\n                    if name.startswith(\"{}_\".format(method_name)):\n                        command_wrapper.add_subcommand(value)\n                    else:\n                        raise ConanException(\"The name for the subcommand method should \"\n                                             \"begin with the main command name + '_'. \"\n                                             \"i.e. {}_<subcommand_name>\".format(method_name))\n        except AttributeError:\n            raise ConanException(\"There is no {} method defined in {}\".format(method_name,\n                                                                              import_path))\n\n    def _print_similar(self, command):\n        \"\"\" Looks for similar commands and prints them if found.\n        \"\"\"\n        output = ConanOutput()\n        matches = get_close_matches(\n            word=command, possibilities=self._commands.keys(), n=5, cutoff=0.75)\n\n        if len(matches) == 0:\n            return\n\n        if len(matches) > 1:\n            output.info(\"The most similar commands are\")\n        else:\n            output.info(\"The most similar command is\")\n\n        for match in matches:\n            output.info(\"    %s\" % match)\n\n        output.writeln(\"\")\n\n    def _output_help_cli(self):\n        \"\"\"\n        Prints a summary of all commands.\n        \"\"\"\n        max_len = max((len(c) for c in self._commands)) + 1\n        line_format = '{{: <{}}}'.format(max_len)\n\n        for group_name, comm_names in sorted(self._groups.items()):\n            cli_out_write(\"\\n\" + group_name + \" commands\", Color.BRIGHT_MAGENTA)\n            for name in comm_names:\n                # future-proof way to ensure tabular formatting\n                cli_out_write(line_format.format(name), Color.GREEN, endline=\"\")\n\n                # Help will be all the lines up to the first empty one\n                docstring_lines = self._commands[name].doc.split('\\n')\n                start = False\n                data = []\n                for line in docstring_lines:\n                    line = line.strip()\n                    if not line:\n                        if start:\n                            break\n                        start = True\n                        continue\n                    data.append(line)\n\n                txt = textwrap.fill(' '.join(data), 80, subsequent_indent=\" \" * (max_len + 2))\n                cli_out_write(txt)\n\n        cli_out_write(\"\")\n        cli_out_write('Type \"conan <command> -h\" for help', Color.BRIGHT_MAGENTA)\n\n    def run(self, *args):\n        \"\"\" Entry point for executing commands, dispatcher to class\n        methods\n        \"\"\"\n        output = ConanOutput()\n        self._add_commands()\n        try:\n            command_argument = args[0][0]\n        except IndexError:  # No parameters\n            self._output_help_cli()\n            return\n        try:\n            command = self._commands[command_argument]\n        except KeyError as exc:\n            if command_argument in [\"-v\", \"--version\"]:\n                cli_out_write(\"Conan version %s\" % client_version)\n                return\n\n            if command_argument in [\"-h\", \"--help\"]:\n                self._output_help_cli()\n                return\n\n            output.info(\"'%s' is not a Conan command. See 'conan --help'.\" % command_argument)\n            output.info(\"\")\n            self._print_similar(command_argument)\n            raise ConanException(\"Unknown command %s\" % str(exc))\n\n        try:\n            command.run(self._conan_api, args[0][1:])\n        except Exception as e:\n            # must be a local-import to get updated value\n            if ConanOutput.level_allowed(LEVEL_TRACE):\n                print(traceback.format_exc(), file=sys.stderr)\n            self._conan2_migrate_recipe_msg(e)\n            raise\n\n    @staticmethod\n    def _conan2_migrate_recipe_msg(exception):\n        message = str(exception)\n\n        result = re.search(r\"Package '(.*)' not resolved: .*: Cannot load recipe\", message)\n        if result:\n            pkg = result.group(1)\n            error = \"*********************************************************\\n\" \\\n                    f\"Recipe '{pkg}' seems broken.\\n\" \\\n                    f\"It is possible that this recipe is not Conan 2.0 ready\\n\"\\\n                    \"If the recipe comes from ConanCenter, report it at https://github.com/conan-io/conan-center-index/issues\\n\" \\\n                    \"If it is your recipe, check if it is updated to 2.0\\n\" \\\n                    \"*********************************************************\\n\"\n            ConanOutput().writeln(error, fg=Color.BRIGHT_MAGENTA)\n\n    @staticmethod\n    def exception_exit_error(exception):\n        output = ConanOutput()\n        if exception is None:\n            return SUCCESS\n        if isinstance(exception, ConanInvalidConfiguration):\n            output.error(exception)\n            return ERROR_INVALID_CONFIGURATION\n        if isinstance(exception, ConanException):\n            output.error(exception)\n            return ERROR_GENERAL\n        if isinstance(exception, SystemExit):\n            if exception.code != 0:\n                output.error(\"Exiting with code: %d\" % exception.code)\n            return exception.code\n\n        assert isinstance(exception, Exception)\n        output.error(traceback.format_exc())\n        msg = exception_message_safe(exception)\n        output.error(msg)\n        return ERROR_UNEXPECTED\n\n\ndef main(args):\n    \"\"\" main entry point of the conan application, using a Command to\n    parse parameters\n\n    Exit codes for conan command:\n\n        0: Success (done)\n        1: General ConanException error (done)\n        2: Migration error\n        3: Ctrl+C\n        4: Ctrl+Break\n        5: SIGTERM\n        6: Invalid configuration (done)\n    \"\"\"\n\n    try:\n        conan_api = ConanAPI()\n    except ConanMigrationError:  # Error migrating\n        sys.exit(ERROR_MIGRATION)\n    except ConanException as e:\n        sys.stderr.write(\"Error in Conan initialization: {}\".format(e))\n        sys.exit(ERROR_GENERAL)\n\n    def ctrl_c_handler(_, __):\n        print('You pressed Ctrl+C!')\n        sys.exit(USER_CTRL_C)\n\n    def sigterm_handler(_, __):\n        print('Received SIGTERM!')\n        sys.exit(ERROR_SIGTERM)\n\n    def ctrl_break_handler(_, __):\n        print('You pressed Ctrl+Break!')\n        sys.exit(USER_CTRL_BREAK)\n\n    signal.signal(signal.SIGINT, ctrl_c_handler)\n    signal.signal(signal.SIGTERM, sigterm_handler)\n\n    if sys.platform == 'win32':\n        signal.signal(signal.SIGBREAK, ctrl_break_handler)\n\n    cli = Cli(conan_api)\n    error = SUCCESS\n    try:\n        cli.run(args)\n    except BaseException as e:\n        error = cli.exception_exit_error(e)\n    sys.exit(error)\n", "path": "conan/cli/cli.py"}]}