We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
conan updates all my software installed with yum
Hi,

my system:
CentOs7, conan 1.16.0, packet manager yum

```python
installer = SystemPackageTool()
installer.update()
```
The above code will instuct conan to update ALL installed packets in the system. It was introduced here: https://github.com/conan-io/conan/pull/3181

This contradicts with the docu that states:

> update(): Updates the system package manager database. It’s called automatically from the install() method by default.

This would be achieved with `yum check-update` instead of `yum update`.
In my opinion conan should not touch any installed packets, unless expicitly instructed to do so. So I would like to see the old behavior back, like it is discribed in the docu.

Cheers

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `conans/client/tools/system_pm.py`
Content:
```
1 import os
2 import sys
3 
4 from conans.client.runner import ConanRunner
5 from conans.client.tools.oss import OSInfo
6 from conans.client.tools.files import which
7 from conans.errors import ConanException
8 from conans.util.env_reader import get_env
9 from conans.util.fallbacks import default_output
10 
11 
12 class SystemPackageTool(object):
13 
14     def __init__(self, runner=None, os_info=None, tool=None, recommends=False, output=None):
15 
16         self._output = default_output(output, 'conans.client.tools.system_pm.SystemPackageTool')
17         os_info = os_info or OSInfo()
18         self._is_up_to_date = False
19         self._tool = tool or self._create_tool(os_info, output=self._output)
20         self._tool._sudo_str = self._get_sudo_str()
21         self._tool._runner = runner or ConanRunner(output=self._output)
22         self._tool._recommends = recommends
23 
24     @staticmethod
25     def _get_sudo_str():
26         if not SystemPackageTool._is_sudo_enabled():
27             return ""
28 
29         if hasattr(sys.stdout, "isatty") and not sys.stdout.isatty():
30             return "sudo -A "
31         else:
32             return "sudo "
33 
34     @staticmethod
35     def _is_sudo_enabled():
36         if "CONAN_SYSREQUIRES_SUDO" not in os.environ:
37             if not which("sudo"):
38                 return False
39             if os.name == 'posix' and os.geteuid() == 0:
40                 return False
41             if os.name == 'nt':
42                 return False
43         return get_env("CONAN_SYSREQUIRES_SUDO", True)
44 
45     @staticmethod
46     def _get_sysrequire_mode():
47         allowed_modes = ("enabled", "verify", "disabled")
48         mode = get_env("CONAN_SYSREQUIRES_MODE", "enabled")
49         mode_lower = mode.lower()
50         if mode_lower not in allowed_modes:
51             raise ConanException("CONAN_SYSREQUIRES_MODE=%s is not allowed, allowed modes=%r"
52                                  % (mode, allowed_modes))
53         return mode_lower
54 
55     @staticmethod
56     def _create_tool(os_info, output):
57         if os_info.with_apt:
58             return AptTool(output=output)
59         elif os_info.with_yum:
60             return YumTool(output=output)
61         elif os_info.with_pacman:
62             return PacManTool(output=output)
63         elif os_info.is_macos:
64             return BrewTool(output=output)
65         elif os_info.is_freebsd:
66             return PkgTool(output=output)
67         elif os_info.is_solaris:
68             return PkgUtilTool(output=output)
69         elif os_info.with_zypper:
70             return ZypperTool(output=output)
71         else:
72             return NullTool(output=output)
73 
74     def add_repository(self, repository, repo_key=None, update=True):
75         self._tool.add_repository(repository, repo_key=repo_key)
76         if update:
77             self.update()
78 
79     def update(self):
80         """
81             Get the system package tool update command
82         """
83         mode = self._get_sysrequire_mode()
84         if mode in ("disabled", "verify"):
85             self._output.info("Not updating system_requirements. CONAN_SYSREQUIRES_MODE=%s" % mode)
86             return
87         self._is_up_to_date = True
88         self._tool.update()
89 
90     def install(self, packages, update=True, force=False):
91         """
92             Get the system package tool install command.
93         '"""
94         packages = [packages] if isinstance(packages, str) else list(packages)
95 
96         mode = self._get_sysrequire_mode()
97 
98         if mode in ("verify", "disabled"):
99             # Report to output packages need to be installed
100             if mode == "disabled":
101                 self._output.info("The following packages need to be installed:\n %s"
102                                   % "\n".join(packages))
103                 return
104 
105             if mode == "verify" and not self._installed(packages):
106                 self._output.error("The following packages need to be installed:\n %s"
107                                    % "\n".join(packages))
108                 raise ConanException("Aborted due to CONAN_SYSREQUIRES_MODE=%s. "
109                                      "Some system packages need to be installed" % mode)
110 
111         if not force and self._installed(packages):
112             return
113 
114         # From here system packages can be updated/modified
115         if update and not self._is_up_to_date:
116             self.update()
117         self._install_any(packages)
118 
119     def _installed(self, packages):
120         if not packages:
121             return True
122 
123         for pkg in packages:
124             if self._tool.installed(pkg):
125                 self._output.info("Package already installed: %s" % pkg)
126                 return True
127         return False
128 
129     def _install_any(self, packages):
130         if len(packages) == 1:
131             return self._tool.install(packages[0])
132         for pkg in packages:
133             try:
134                 return self._tool.install(pkg)
135             except ConanException:
136                 pass
137         raise ConanException("Could not install any of %s" % packages)
138 
139 
140 class BaseTool(object):
141     def __init__(self, output=None):
142         self._output = default_output(output, 'conans.client.tools.system_pm.BaseTool')
143 
144 
145 class NullTool(BaseTool):
146     def add_repository(self, repository, repo_key=None):
147         pass
148 
149     def update(self):
150         pass
151 
152     def install(self, package_name):
153         self._output.warn("Only available for linux with apt-get, yum, or pacman or OSX with brew or"
154                           " FreeBSD with pkg or Solaris with pkgutil")
155 
156     def installed(self, package_name):
157         return False
158 
159 
160 class AptTool(BaseTool):
161     def add_repository(self, repository, repo_key=None):
162         _run(self._runner, "%sapt-add-repository %s" % (self._sudo_str, repository),
163              output=self._output)
164         if repo_key:
165             _run(self._runner, "wget -qO - %s | %sapt-key add -" % (repo_key, self._sudo_str),
166                  output=self._output)
167 
168     def update(self):
169         _run(self._runner, "%sapt-get update" % self._sudo_str, output=self._output)
170 
171     def install(self, package_name):
172         recommends_str = '' if self._recommends else '--no-install-recommends '
173         _run(self._runner,
174              "%sapt-get install -y %s%s" % (self._sudo_str, recommends_str, package_name),
175              output=self._output)
176 
177     def installed(self, package_name):
178         exit_code = self._runner("dpkg-query -W -f='${Status}' %s | grep -q \"ok installed\""
179                                  % package_name, None)
180         return exit_code == 0
181 
182 
183 class YumTool(BaseTool):
184     def add_repository(self, repository, repo_key=None):
185         raise ConanException("YumTool::add_repository not implemented")
186 
187     def update(self):
188         _run(self._runner, "%syum update -y" % self._sudo_str, accepted_returns=[0, 100],
189              output=self._output)
190 
191     def install(self, package_name):
192         _run(self._runner, "%syum install -y %s" % (self._sudo_str, package_name),
193              output=self._output)
194 
195     def installed(self, package_name):
196         exit_code = self._runner("rpm -q %s" % package_name, None)
197         return exit_code == 0
198 
199 
200 class BrewTool(BaseTool):
201     def add_repository(self, repository, repo_key=None):
202         raise ConanException("BrewTool::add_repository not implemented")
203 
204     def update(self):
205         _run(self._runner, "brew update", output=self._output)
206 
207     def install(self, package_name):
208         _run(self._runner, "brew install %s" % package_name, output=self._output)
209 
210     def installed(self, package_name):
211         exit_code = self._runner('test -n "$(brew ls --versions %s)"' % package_name, None)
212         return exit_code == 0
213 
214 
215 class PkgTool(BaseTool):
216     def add_repository(self, repository, repo_key=None):
217         raise ConanException("PkgTool::add_repository not implemented")
218 
219     def update(self):
220         _run(self._runner, "%spkg update" % self._sudo_str, output=self._output)
221 
222     def install(self, package_name):
223         _run(self._runner, "%spkg install -y %s" % (self._sudo_str, package_name),
224              output=self._output)
225 
226     def installed(self, package_name):
227         exit_code = self._runner("pkg info %s" % package_name, None)
228         return exit_code == 0
229 
230 
231 class PkgUtilTool(BaseTool):
232     def add_repository(self, repository, repo_key=None):
233         raise ConanException("PkgUtilTool::add_repository not implemented")
234 
235     def update(self):
236         _run(self._runner, "%spkgutil --catalog" % self._sudo_str, output=self._output)
237 
238     def install(self, package_name):
239         _run(self._runner, "%spkgutil --install --yes %s" % (self._sudo_str, package_name),
240              output=self._output)
241 
242     def installed(self, package_name):
243         exit_code = self._runner('test -n "`pkgutil --list %s`"' % package_name, None)
244         return exit_code == 0
245 
246 
247 class ChocolateyTool(BaseTool):
248     def add_repository(self, repository, repo_key=None):
249         raise ConanException("ChocolateyTool::add_repository not implemented")
250 
251     def update(self):
252         _run(self._runner, "choco outdated", output=self._output)
253 
254     def install(self, package_name):
255         _run(self._runner, "choco install --yes %s" % package_name, output=self._output)
256 
257     def installed(self, package_name):
258         exit_code = self._runner('choco search --local-only --exact %s | '
259                                  'findstr /c:"1 packages installed."' % package_name, None)
260         return exit_code == 0
261 
262 
263 class PacManTool(BaseTool):
264     def add_repository(self, repository, repo_key=None):
265         raise ConanException("PacManTool::add_repository not implemented")
266 
267     def update(self):
268         _run(self._runner, "%spacman -Syyu --noconfirm" % self._sudo_str, output=self._output)
269 
270     def install(self, package_name):
271         _run(self._runner, "%spacman -S --noconfirm %s" % (self._sudo_str, package_name),
272              output=self._output)
273 
274     def installed(self, package_name):
275         exit_code = self._runner("pacman -Qi %s" % package_name, None)
276         return exit_code == 0
277 
278 
279 class ZypperTool(BaseTool):
280     def add_repository(self, repository, repo_key=None):
281         raise ConanException("ZypperTool::add_repository not implemented")
282 
283     def update(self):
284         _run(self._runner, "%szypper --non-interactive ref" % self._sudo_str, output=self._output)
285 
286     def install(self, package_name):
287         _run(self._runner, "%szypper --non-interactive in %s" % (self._sudo_str, package_name),
288              output=self._output)
289 
290     def installed(self, package_name):
291         exit_code = self._runner("rpm -q %s" % package_name, None)
292         return exit_code == 0
293 
294 
295 def _run(runner, command, output, accepted_returns=None):
296     accepted_returns = accepted_returns or [0, ]
297     output.info("Running: %s" % command)
298     if runner(command, True) not in accepted_returns:
299         raise ConanException("Command '%s' failed" % command)
300
```
--- 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/conans/client/tools/system_pm.py b/conans/client/tools/system_pm.py
--- a/conans/client/tools/system_pm.py
+++ b/conans/client/tools/system_pm.py
@@ -185,7 +185,7 @@
         raise ConanException("YumTool::add_repository not implemented")
 
     def update(self):
-        _run(self._runner, "%syum update -y" % self._sudo_str, accepted_returns=[0, 100],
+        _run(self._runner, "%syum check-update -y" % self._sudo_str, accepted_returns=[0, 100],
              output=self._output)
 
     def install(self, package_name):

{"golden_diff": "diff --git a/conans/client/tools/system_pm.py b/conans/client/tools/system_pm.py\n--- a/conans/client/tools/system_pm.py\n+++ b/conans/client/tools/system_pm.py\n@@ -185,7 +185,7 @@\n         raise ConanException(\"YumTool::add_repository not implemented\")\n \n     def update(self):\n-        _run(self._runner, \"%syum update -y\" % self._sudo_str, accepted_returns=[0, 100],\n+        _run(self._runner, \"%syum check-update -y\" % self._sudo_str, accepted_returns=[0, 100],\n              output=self._output)\n \n     def install(self, package_name):\n", "issue": "conan updates all my software installed with yum\nHi,\r\n\r\nmy system:\r\nCentOs7, conan 1.16.0, packet manager yum\r\n\r\n```python\r\ninstaller = SystemPackageTool()\r\ninstaller.update()\r\n```\r\nThe above code will instuct conan to update ALL installed packets in the system. It was introduced here: https://github.com/conan-io/conan/pull/3181\r\n\r\nThis contradicts with the docu that states:\r\n\r\n> update(): Updates the system package manager database. It\u2019s called automatically from the install() method by default.\r\n\r\nThis would be achieved with `yum check-update` instead of `yum update`.\r\nIn my opinion conan should not touch any installed packets, unless expicitly instructed to do so. So I would like to see the old behavior back, like it is discribed in the docu.\r\n\r\nCheers\n", "before_files": [{"content": "import os\nimport sys\n\nfrom conans.client.runner import ConanRunner\nfrom conans.client.tools.oss import OSInfo\nfrom conans.client.tools.files import which\nfrom conans.errors import ConanException\nfrom conans.util.env_reader import get_env\nfrom conans.util.fallbacks import default_output\n\n\nclass SystemPackageTool(object):\n\n    def __init__(self, runner=None, os_info=None, tool=None, recommends=False, output=None):\n\n        self._output = default_output(output, 'conans.client.tools.system_pm.SystemPackageTool')\n        os_info = os_info or OSInfo()\n        self._is_up_to_date = False\n        self._tool = tool or self._create_tool(os_info, output=self._output)\n        self._tool._sudo_str = self._get_sudo_str()\n        self._tool._runner = runner or ConanRunner(output=self._output)\n        self._tool._recommends = recommends\n\n    @staticmethod\n    def _get_sudo_str():\n        if not SystemPackageTool._is_sudo_enabled():\n            return \"\"\n\n        if hasattr(sys.stdout, \"isatty\") and not sys.stdout.isatty():\n            return \"sudo -A \"\n        else:\n            return \"sudo \"\n\n    @staticmethod\n    def _is_sudo_enabled():\n        if \"CONAN_SYSREQUIRES_SUDO\" not in os.environ:\n            if not which(\"sudo\"):\n                return False\n            if os.name == 'posix' and os.geteuid() == 0:\n                return False\n            if os.name == 'nt':\n                return False\n        return get_env(\"CONAN_SYSREQUIRES_SUDO\", True)\n\n    @staticmethod\n    def _get_sysrequire_mode():\n        allowed_modes = (\"enabled\", \"verify\", \"disabled\")\n        mode = get_env(\"CONAN_SYSREQUIRES_MODE\", \"enabled\")\n        mode_lower = mode.lower()\n        if mode_lower not in allowed_modes:\n            raise ConanException(\"CONAN_SYSREQUIRES_MODE=%s is not allowed, allowed modes=%r\"\n                                 % (mode, allowed_modes))\n        return mode_lower\n\n    @staticmethod\n    def _create_tool(os_info, output):\n        if os_info.with_apt:\n            return AptTool(output=output)\n        elif os_info.with_yum:\n            return YumTool(output=output)\n        elif os_info.with_pacman:\n            return PacManTool(output=output)\n        elif os_info.is_macos:\n            return BrewTool(output=output)\n        elif os_info.is_freebsd:\n            return PkgTool(output=output)\n        elif os_info.is_solaris:\n            return PkgUtilTool(output=output)\n        elif os_info.with_zypper:\n            return ZypperTool(output=output)\n        else:\n            return NullTool(output=output)\n\n    def add_repository(self, repository, repo_key=None, update=True):\n        self._tool.add_repository(repository, repo_key=repo_key)\n        if update:\n            self.update()\n\n    def update(self):\n        \"\"\"\n            Get the system package tool update command\n        \"\"\"\n        mode = self._get_sysrequire_mode()\n        if mode in (\"disabled\", \"verify\"):\n            self._output.info(\"Not updating system_requirements. CONAN_SYSREQUIRES_MODE=%s\" % mode)\n            return\n        self._is_up_to_date = True\n        self._tool.update()\n\n    def install(self, packages, update=True, force=False):\n        \"\"\"\n            Get the system package tool install command.\n        '\"\"\"\n        packages = [packages] if isinstance(packages, str) else list(packages)\n\n        mode = self._get_sysrequire_mode()\n\n        if mode in (\"verify\", \"disabled\"):\n            # Report to output packages need to be installed\n            if mode == \"disabled\":\n                self._output.info(\"The following packages need to be installed:\\n %s\"\n                                  % \"\\n\".join(packages))\n                return\n\n            if mode == \"verify\" and not self._installed(packages):\n                self._output.error(\"The following packages need to be installed:\\n %s\"\n                                   % \"\\n\".join(packages))\n                raise ConanException(\"Aborted due to CONAN_SYSREQUIRES_MODE=%s. \"\n                                     \"Some system packages need to be installed\" % mode)\n\n        if not force and self._installed(packages):\n            return\n\n        # From here system packages can be updated/modified\n        if update and not self._is_up_to_date:\n            self.update()\n        self._install_any(packages)\n\n    def _installed(self, packages):\n        if not packages:\n            return True\n\n        for pkg in packages:\n            if self._tool.installed(pkg):\n                self._output.info(\"Package already installed: %s\" % pkg)\n                return True\n        return False\n\n    def _install_any(self, packages):\n        if len(packages) == 1:\n            return self._tool.install(packages[0])\n        for pkg in packages:\n            try:\n                return self._tool.install(pkg)\n            except ConanException:\n                pass\n        raise ConanException(\"Could not install any of %s\" % packages)\n\n\nclass BaseTool(object):\n    def __init__(self, output=None):\n        self._output = default_output(output, 'conans.client.tools.system_pm.BaseTool')\n\n\nclass NullTool(BaseTool):\n    def add_repository(self, repository, repo_key=None):\n        pass\n\n    def update(self):\n        pass\n\n    def install(self, package_name):\n        self._output.warn(\"Only available for linux with apt-get, yum, or pacman or OSX with brew or\"\n                          \" FreeBSD with pkg or Solaris with pkgutil\")\n\n    def installed(self, package_name):\n        return False\n\n\nclass AptTool(BaseTool):\n    def add_repository(self, repository, repo_key=None):\n        _run(self._runner, \"%sapt-add-repository %s\" % (self._sudo_str, repository),\n             output=self._output)\n        if repo_key:\n            _run(self._runner, \"wget -qO - %s | %sapt-key add -\" % (repo_key, self._sudo_str),\n                 output=self._output)\n\n    def update(self):\n        _run(self._runner, \"%sapt-get update\" % self._sudo_str, output=self._output)\n\n    def install(self, package_name):\n        recommends_str = '' if self._recommends else '--no-install-recommends '\n        _run(self._runner,\n             \"%sapt-get install -y %s%s\" % (self._sudo_str, recommends_str, package_name),\n             output=self._output)\n\n    def installed(self, package_name):\n        exit_code = self._runner(\"dpkg-query -W -f='${Status}' %s | grep -q \\\"ok installed\\\"\"\n                                 % package_name, None)\n        return exit_code == 0\n\n\nclass YumTool(BaseTool):\n    def add_repository(self, repository, repo_key=None):\n        raise ConanException(\"YumTool::add_repository not implemented\")\n\n    def update(self):\n        _run(self._runner, \"%syum update -y\" % self._sudo_str, accepted_returns=[0, 100],\n             output=self._output)\n\n    def install(self, package_name):\n        _run(self._runner, \"%syum install -y %s\" % (self._sudo_str, package_name),\n             output=self._output)\n\n    def installed(self, package_name):\n        exit_code = self._runner(\"rpm -q %s\" % package_name, None)\n        return exit_code == 0\n\n\nclass BrewTool(BaseTool):\n    def add_repository(self, repository, repo_key=None):\n        raise ConanException(\"BrewTool::add_repository not implemented\")\n\n    def update(self):\n        _run(self._runner, \"brew update\", output=self._output)\n\n    def install(self, package_name):\n        _run(self._runner, \"brew install %s\" % package_name, output=self._output)\n\n    def installed(self, package_name):\n        exit_code = self._runner('test -n \"$(brew ls --versions %s)\"' % package_name, None)\n        return exit_code == 0\n\n\nclass PkgTool(BaseTool):\n    def add_repository(self, repository, repo_key=None):\n        raise ConanException(\"PkgTool::add_repository not implemented\")\n\n    def update(self):\n        _run(self._runner, \"%spkg update\" % self._sudo_str, output=self._output)\n\n    def install(self, package_name):\n        _run(self._runner, \"%spkg install -y %s\" % (self._sudo_str, package_name),\n             output=self._output)\n\n    def installed(self, package_name):\n        exit_code = self._runner(\"pkg info %s\" % package_name, None)\n        return exit_code == 0\n\n\nclass PkgUtilTool(BaseTool):\n    def add_repository(self, repository, repo_key=None):\n        raise ConanException(\"PkgUtilTool::add_repository not implemented\")\n\n    def update(self):\n        _run(self._runner, \"%spkgutil --catalog\" % self._sudo_str, output=self._output)\n\n    def install(self, package_name):\n        _run(self._runner, \"%spkgutil --install --yes %s\" % (self._sudo_str, package_name),\n             output=self._output)\n\n    def installed(self, package_name):\n        exit_code = self._runner('test -n \"`pkgutil --list %s`\"' % package_name, None)\n        return exit_code == 0\n\n\nclass ChocolateyTool(BaseTool):\n    def add_repository(self, repository, repo_key=None):\n        raise ConanException(\"ChocolateyTool::add_repository not implemented\")\n\n    def update(self):\n        _run(self._runner, \"choco outdated\", output=self._output)\n\n    def install(self, package_name):\n        _run(self._runner, \"choco install --yes %s\" % package_name, output=self._output)\n\n    def installed(self, package_name):\n        exit_code = self._runner('choco search --local-only --exact %s | '\n                                 'findstr /c:\"1 packages installed.\"' % package_name, None)\n        return exit_code == 0\n\n\nclass PacManTool(BaseTool):\n    def add_repository(self, repository, repo_key=None):\n        raise ConanException(\"PacManTool::add_repository not implemented\")\n\n    def update(self):\n        _run(self._runner, \"%spacman -Syyu --noconfirm\" % self._sudo_str, output=self._output)\n\n    def install(self, package_name):\n        _run(self._runner, \"%spacman -S --noconfirm %s\" % (self._sudo_str, package_name),\n             output=self._output)\n\n    def installed(self, package_name):\n        exit_code = self._runner(\"pacman -Qi %s\" % package_name, None)\n        return exit_code == 0\n\n\nclass ZypperTool(BaseTool):\n    def add_repository(self, repository, repo_key=None):\n        raise ConanException(\"ZypperTool::add_repository not implemented\")\n\n    def update(self):\n        _run(self._runner, \"%szypper --non-interactive ref\" % self._sudo_str, output=self._output)\n\n    def install(self, package_name):\n        _run(self._runner, \"%szypper --non-interactive in %s\" % (self._sudo_str, package_name),\n             output=self._output)\n\n    def installed(self, package_name):\n        exit_code = self._runner(\"rpm -q %s\" % package_name, None)\n        return exit_code == 0\n\n\ndef _run(runner, command, output, accepted_returns=None):\n    accepted_returns = accepted_returns or [0, ]\n    output.info(\"Running: %s\" % command)\n    if runner(command, True) not in accepted_returns:\n        raise ConanException(\"Command '%s' failed\" % command)\n", "path": "conans/client/tools/system_pm.py"}], "after_files": [{"content": "import os\nimport sys\n\nfrom conans.client.runner import ConanRunner\nfrom conans.client.tools.oss import OSInfo\nfrom conans.client.tools.files import which\nfrom conans.errors import ConanException\nfrom conans.util.env_reader import get_env\nfrom conans.util.fallbacks import default_output\n\n\nclass SystemPackageTool(object):\n\n    def __init__(self, runner=None, os_info=None, tool=None, recommends=False, output=None):\n\n        self._output = default_output(output, 'conans.client.tools.system_pm.SystemPackageTool')\n        os_info = os_info or OSInfo()\n        self._is_up_to_date = False\n        self._tool = tool or self._create_tool(os_info, output=self._output)\n        self._tool._sudo_str = self._get_sudo_str()\n        self._tool._runner = runner or ConanRunner(output=self._output)\n        self._tool._recommends = recommends\n\n    @staticmethod\n    def _get_sudo_str():\n        if not SystemPackageTool._is_sudo_enabled():\n            return \"\"\n\n        if hasattr(sys.stdout, \"isatty\") and not sys.stdout.isatty():\n            return \"sudo -A \"\n        else:\n            return \"sudo \"\n\n    @staticmethod\n    def _is_sudo_enabled():\n        if \"CONAN_SYSREQUIRES_SUDO\" not in os.environ:\n            if not which(\"sudo\"):\n                return False\n            if os.name == 'posix' and os.geteuid() == 0:\n                return False\n            if os.name == 'nt':\n                return False\n        return get_env(\"CONAN_SYSREQUIRES_SUDO\", True)\n\n    @staticmethod\n    def _get_sysrequire_mode():\n        allowed_modes = (\"enabled\", \"verify\", \"disabled\")\n        mode = get_env(\"CONAN_SYSREQUIRES_MODE\", \"enabled\")\n        mode_lower = mode.lower()\n        if mode_lower not in allowed_modes:\n            raise ConanException(\"CONAN_SYSREQUIRES_MODE=%s is not allowed, allowed modes=%r\"\n                                 % (mode, allowed_modes))\n        return mode_lower\n\n    @staticmethod\n    def _create_tool(os_info, output):\n        if os_info.with_apt:\n            return AptTool(output=output)\n        elif os_info.with_yum:\n            return YumTool(output=output)\n        elif os_info.with_pacman:\n            return PacManTool(output=output)\n        elif os_info.is_macos:\n            return BrewTool(output=output)\n        elif os_info.is_freebsd:\n            return PkgTool(output=output)\n        elif os_info.is_solaris:\n            return PkgUtilTool(output=output)\n        elif os_info.with_zypper:\n            return ZypperTool(output=output)\n        else:\n            return NullTool(output=output)\n\n    def add_repository(self, repository, repo_key=None, update=True):\n        self._tool.add_repository(repository, repo_key=repo_key)\n        if update:\n            self.update()\n\n    def update(self):\n        \"\"\"\n            Get the system package tool update command\n        \"\"\"\n        mode = self._get_sysrequire_mode()\n        if mode in (\"disabled\", \"verify\"):\n            self._output.info(\"Not updating system_requirements. CONAN_SYSREQUIRES_MODE=%s\" % mode)\n            return\n        self._is_up_to_date = True\n        self._tool.update()\n\n    def install(self, packages, update=True, force=False):\n        \"\"\"\n            Get the system package tool install command.\n        '\"\"\"\n        packages = [packages] if isinstance(packages, str) else list(packages)\n\n        mode = self._get_sysrequire_mode()\n\n        if mode in (\"verify\", \"disabled\"):\n            # Report to output packages need to be installed\n            if mode == \"disabled\":\n                self._output.info(\"The following packages need to be installed:\\n %s\"\n                                  % \"\\n\".join(packages))\n                return\n\n            if mode == \"verify\" and not self._installed(packages):\n                self._output.error(\"The following packages need to be installed:\\n %s\"\n                                   % \"\\n\".join(packages))\n                raise ConanException(\"Aborted due to CONAN_SYSREQUIRES_MODE=%s. \"\n                                     \"Some system packages need to be installed\" % mode)\n\n        if not force and self._installed(packages):\n            return\n\n        # From here system packages can be updated/modified\n        if update and not self._is_up_to_date:\n            self.update()\n        self._install_any(packages)\n\n    def _installed(self, packages):\n        if not packages:\n            return True\n\n        for pkg in packages:\n            if self._tool.installed(pkg):\n                self._output.info(\"Package already installed: %s\" % pkg)\n                return True\n        return False\n\n    def _install_any(self, packages):\n        if len(packages) == 1:\n            return self._tool.install(packages[0])\n        for pkg in packages:\n            try:\n                return self._tool.install(pkg)\n            except ConanException:\n                pass\n        raise ConanException(\"Could not install any of %s\" % packages)\n\n\nclass BaseTool(object):\n    def __init__(self, output=None):\n        self._output = default_output(output, 'conans.client.tools.system_pm.BaseTool')\n\n\nclass NullTool(BaseTool):\n    def add_repository(self, repository, repo_key=None):\n        pass\n\n    def update(self):\n        pass\n\n    def install(self, package_name):\n        self._output.warn(\"Only available for linux with apt-get, yum, or pacman or OSX with brew or\"\n                          \" FreeBSD with pkg or Solaris with pkgutil\")\n\n    def installed(self, package_name):\n        return False\n\n\nclass AptTool(BaseTool):\n    def add_repository(self, repository, repo_key=None):\n        _run(self._runner, \"%sapt-add-repository %s\" % (self._sudo_str, repository),\n             output=self._output)\n        if repo_key:\n            _run(self._runner, \"wget -qO - %s | %sapt-key add -\" % (repo_key, self._sudo_str),\n                 output=self._output)\n\n    def update(self):\n        _run(self._runner, \"%sapt-get update\" % self._sudo_str, output=self._output)\n\n    def install(self, package_name):\n        recommends_str = '' if self._recommends else '--no-install-recommends '\n        _run(self._runner,\n             \"%sapt-get install -y %s%s\" % (self._sudo_str, recommends_str, package_name),\n             output=self._output)\n\n    def installed(self, package_name):\n        exit_code = self._runner(\"dpkg-query -W -f='${Status}' %s | grep -q \\\"ok installed\\\"\"\n                                 % package_name, None)\n        return exit_code == 0\n\n\nclass YumTool(BaseTool):\n    def add_repository(self, repository, repo_key=None):\n        raise ConanException(\"YumTool::add_repository not implemented\")\n\n    def update(self):\n        _run(self._runner, \"%syum check-update -y\" % self._sudo_str, accepted_returns=[0, 100],\n             output=self._output)\n\n    def install(self, package_name):\n        _run(self._runner, \"%syum install -y %s\" % (self._sudo_str, package_name),\n             output=self._output)\n\n    def installed(self, package_name):\n        exit_code = self._runner(\"rpm -q %s\" % package_name, None)\n        return exit_code == 0\n\n\nclass BrewTool(BaseTool):\n    def add_repository(self, repository, repo_key=None):\n        raise ConanException(\"BrewTool::add_repository not implemented\")\n\n    def update(self):\n        _run(self._runner, \"brew update\", output=self._output)\n\n    def install(self, package_name):\n        _run(self._runner, \"brew install %s\" % package_name, output=self._output)\n\n    def installed(self, package_name):\n        exit_code = self._runner('test -n \"$(brew ls --versions %s)\"' % package_name, None)\n        return exit_code == 0\n\n\nclass PkgTool(BaseTool):\n    def add_repository(self, repository, repo_key=None):\n        raise ConanException(\"PkgTool::add_repository not implemented\")\n\n    def update(self):\n        _run(self._runner, \"%spkg update\" % self._sudo_str, output=self._output)\n\n    def install(self, package_name):\n        _run(self._runner, \"%spkg install -y %s\" % (self._sudo_str, package_name),\n             output=self._output)\n\n    def installed(self, package_name):\n        exit_code = self._runner(\"pkg info %s\" % package_name, None)\n        return exit_code == 0\n\n\nclass PkgUtilTool(BaseTool):\n    def add_repository(self, repository, repo_key=None):\n        raise ConanException(\"PkgUtilTool::add_repository not implemented\")\n\n    def update(self):\n        _run(self._runner, \"%spkgutil --catalog\" % self._sudo_str, output=self._output)\n\n    def install(self, package_name):\n        _run(self._runner, \"%spkgutil --install --yes %s\" % (self._sudo_str, package_name),\n             output=self._output)\n\n    def installed(self, package_name):\n        exit_code = self._runner('test -n \"`pkgutil --list %s`\"' % package_name, None)\n        return exit_code == 0\n\n\nclass ChocolateyTool(BaseTool):\n    def add_repository(self, repository, repo_key=None):\n        raise ConanException(\"ChocolateyTool::add_repository not implemented\")\n\n    def update(self):\n        _run(self._runner, \"choco outdated\", output=self._output)\n\n    def install(self, package_name):\n        _run(self._runner, \"choco install --yes %s\" % package_name, output=self._output)\n\n    def installed(self, package_name):\n        exit_code = self._runner('choco search --local-only --exact %s | '\n                                 'findstr /c:\"1 packages installed.\"' % package_name, None)\n        return exit_code == 0\n\n\nclass PacManTool(BaseTool):\n    def add_repository(self, repository, repo_key=None):\n        raise ConanException(\"PacManTool::add_repository not implemented\")\n\n    def update(self):\n        _run(self._runner, \"%spacman -Syyu --noconfirm\" % self._sudo_str, output=self._output)\n\n    def install(self, package_name):\n        _run(self._runner, \"%spacman -S --noconfirm %s\" % (self._sudo_str, package_name),\n             output=self._output)\n\n    def installed(self, package_name):\n        exit_code = self._runner(\"pacman -Qi %s\" % package_name, None)\n        return exit_code == 0\n\n\nclass ZypperTool(BaseTool):\n    def add_repository(self, repository, repo_key=None):\n        raise ConanException(\"ZypperTool::add_repository not implemented\")\n\n    def update(self):\n        _run(self._runner, \"%szypper --non-interactive ref\" % self._sudo_str, output=self._output)\n\n    def install(self, package_name):\n        _run(self._runner, \"%szypper --non-interactive in %s\" % (self._sudo_str, package_name),\n             output=self._output)\n\n    def installed(self, package_name):\n        exit_code = self._runner(\"rpm -q %s\" % package_name, None)\n        return exit_code == 0\n\n\ndef _run(runner, command, output, accepted_returns=None):\n    accepted_returns = accepted_returns or [0, ]\n    output.info(\"Running: %s\" % command)\n    if runner(command, True) not in accepted_returns:\n        raise ConanException(\"Command '%s' failed\" % command)\n", "path": "conans/client/tools/system_pm.py"}]}