We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
pipx install option --install-deps not in version 0.16.4
### Summary

The [pipx plugin](https://github.com/ansible-collections/community.general/blob/main/plugins/modules/packaging/language/pipx.py) has an option `install_deps` which adds an `--install-deps` option to the the `pipx` command line. This causes the `pipx` command to fail with version 0.16.4 of `pipx`.

Version 0.16.4 of the program appears to provide the `--include-deps` option instead.

https://pypa.github.io/pipx/docs/#pipx-install
https://docs.ansible.com/ansible/latest/collections/community/general/pipx_module.html#parameter-install_deps

### Issue Type

Bug Report

### Component Name

pipx

### Ansible Version

```
ansible [core 2.11.6]
```


### Community.general Version

Global version
```
Collection        Version
----------------- -------
community.general 3.8.1
```

Playbook local version
```
Collection        Version
----------------- -------
community.general 4.1.0
```

### Configuration

```console (paste below)
$ ansible-config dump --only-changed

```


### OS / Environment

WSL2 (local)
Ubuntu 20.04 (remote)

### Steps to Reproduce

<!--- Paste example playbooks or commands between quotes below -->
```yaml
community.general.pipx:
  name: "{{ pipx_item }}"
  include_deps: true

```


### Expected Results

The module to complete succesfully

### Actual Results

```console
failed: [laptop] (item=ansible-base) => changed=false
  ansible_loop_var: pipx_item
  cmd: /usr/bin/python3 -m pipx install --install-deps ansible-base
  msg: |-
    usage: __main__.py [-h] [--version]
                       {install,inject,upgrade,upgrade-all,uninstall,uninstall-all,reinstall,reinstall-all,list,run,runpip,ensurepath,completions}
                       ...
    __main__.py: error: unrecognized arguments: --install-deps
  pipx_item: ansible-base
  rc: 2
  stderr: |-
    usage: __main__.py [-h] [--version]
                       {install,inject,upgrade,upgrade-all,uninstall,uninstall-all,reinstall,reinstall-all,list,run,runpip,ensurepath,completions}
                       ...
    __main__.py: error: unrecognized arguments: --install-deps
  stderr_lines: <omitted>
  stdout: ''
  stdout_lines: <omitted>
```


### Code of Conduct

- [X] I agree to follow the Ansible Code of Conduct

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `plugins/modules/packaging/language/pipx.py`
Content:
```
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3 
4 # (c) 2021, Alexei Znamensky <russoz@gmail.com>
5 # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
6 
7 from __future__ import absolute_import, division, print_function
8 __metaclass__ = type
9 
10 
11 DOCUMENTATION = '''
12 ---
13 module: pipx
14 short_description: Manages applications installed with pipx
15 version_added: 3.8.0
16 description:
17     - Manage Python applications installed in isolated virtualenvs using pipx.
18 options:
19     state:
20         type: str
21         choices: [present, absent, install, uninstall, uninstall_all, inject, upgrade, upgrade_all, reinstall, reinstall_all]
22         default: install
23         description:
24             - Desired state for the application.
25             - The states C(present) and C(absent) are aliases to C(install) and C(uninstall), respectively.
26     name:
27         type: str
28         description:
29             - >
30               The name of the application to be installed. It must to be a simple package name.
31               For passing package specifications or installing from URLs or directories,
32               please use the I(source) option.
33     source:
34         type: str
35         description:
36             - >
37               If the application source, such as a package with version specifier, or an URL,
38               directory or any other accepted specification. See C(pipx) documentation for more details.
39             - When specified, the C(pipx) command will use I(source) instead of I(name).
40     install_deps:
41         description:
42             - Include applications of dependent packages.
43             - Only used when I(state=install) or I(state=upgrade).
44         type: bool
45         default: false
46     inject_packages:
47         description:
48             - Packages to be injected into an existing virtual environment.
49             - Only used when I(state=inject).
50         type: list
51         elements: str
52     force:
53         description:
54             - Force modification of the application's virtual environment. See C(pipx) for details.
55             - Only used when I(state=install), I(state=upgrade), I(state=upgrade_all), or I(state=inject).
56         type: bool
57         default: false
58     include_injected:
59         description:
60             - Upgrade the injected packages along with the application.
61             - Only used when I(state=upgrade) or I(state=upgrade_all).
62         type: bool
63         default: false
64     index_url:
65         description:
66             - Base URL of Python Package Index.
67             - Only used when I(state=install), I(state=upgrade), or I(state=inject).
68         type: str
69     python:
70         description:
71             - Python version to be used when creating the application virtual environment. Must be 3.6+.
72             - Only used when I(state=install), I(state=reinstall), or I(state=reinstall_all).
73         type: str
74     executable:
75         description:
76             - Path to the C(pipx) installed in the system.
77             - >
78               If not specified, the module will use C(python -m pipx) to run the tool,
79               using the same Python interpreter as ansible itself.
80         type: path
81 notes:
82     - This module does not install the C(pipx) python package, however that can be easily done with the module M(ansible.builtin.pip).
83     - This module does not require C(pipx) to be in the shell C(PATH), but it must be loadable by Python as a module.
84     - Please note that C(pipx) requires Python 3.6 or above.
85     - >
86       This first implementation does not verify whether a specified version constraint has been installed or not.
87       Hence, when using version operators, C(pipx) module will always try to execute the operation,
88       even when the application was previously installed.
89       This feature will be added in the future.
90     - See also the C(pipx) documentation at U(https://pypa.github.io/pipx/).
91 author:
92     - "Alexei Znamensky (@russoz)"
93 '''
94 
95 EXAMPLES = '''
96 - name: Install tox
97   community.general.pipx:
98     name: tox
99 
100 - name: Install tox from git repository
101   community.general.pipx:
102     name: tox
103     source: git+https://github.com/tox-dev/tox.git
104 
105 - name: Upgrade tox
106   community.general.pipx:
107     name: tox
108     state: upgrade
109 
110 - name: Reinstall black with specific Python version
111   community.general.pipx:
112     name: black
113     state: reinstall
114     python: 3.7
115 
116 - name: Uninstall pycowsay
117   community.general.pipx:
118     name: pycowsay
119     state: absent
120 '''
121 
122 
123 import json
124 
125 from ansible_collections.community.general.plugins.module_utils.module_helper import (
126     CmdStateModuleHelper, ArgFormat, ModuleHelperException
127 )
128 from ansible.module_utils.facts.compat import ansible_facts
129 
130 
131 _state_map = dict(
132     present='install',
133     absent='uninstall',
134     uninstall_all='uninstall-all',
135     upgrade_all='upgrade-all',
136     reinstall_all='reinstall-all',
137 )
138 
139 
140 class PipX(CmdStateModuleHelper):
141     output_params = ['name', 'source', 'index_url', 'force', 'installdeps']
142     module = dict(
143         argument_spec=dict(
144             state=dict(type='str', default='install',
145                        choices=[
146                            'present', 'absent', 'install', 'uninstall', 'uninstall_all',
147                            'inject', 'upgrade', 'upgrade_all', 'reinstall', 'reinstall_all']),
148             name=dict(type='str'),
149             source=dict(type='str'),
150             install_deps=dict(type='bool', default=False),
151             inject_packages=dict(type='list', elements='str'),
152             force=dict(type='bool', default=False),
153             include_injected=dict(type='bool', default=False),
154             index_url=dict(type='str'),
155             python=dict(type='str'),
156             executable=dict(type='path')
157         ),
158         required_if=[
159             ('state', 'present', ['name']),
160             ('state', 'install', ['name']),
161             ('state', 'absent', ['name']),
162             ('state', 'uninstall', ['name']),
163             ('state', 'inject', ['name', 'inject_packages']),
164         ],
165         supports_check_mode=True,
166     )
167     command_args_formats = dict(
168         state=dict(fmt=lambda v: [_state_map.get(v, v)]),
169         name_source=dict(fmt=lambda n, s: [s] if s else [n], stars=1),
170         install_deps=dict(fmt="--install-deps", style=ArgFormat.BOOLEAN),
171         inject_packages=dict(fmt=lambda v: v),
172         force=dict(fmt="--force", style=ArgFormat.BOOLEAN),
173         include_injected=dict(fmt="--include-injected", style=ArgFormat.BOOLEAN),
174         index_url=dict(fmt=('--index-url', '{0}'),),
175         python=dict(fmt=('--python', '{0}'),),
176         _list=dict(fmt=('list', '--include-injected', '--json'), style=ArgFormat.BOOLEAN),
177     )
178     check_rc = True
179     run_command_fixed_options = dict(
180         environ_update={'USE_EMOJI': '0'}
181     )
182 
183     def _retrieve_installed(self):
184         def process_list(rc, out, err):
185             if not out:
186                 return {}
187 
188             results = {}
189             raw_data = json.loads(out)
190             for venv_name, venv in raw_data['venvs'].items():
191                 results[venv_name] = {
192                     'version': venv['metadata']['main_package']['package_version'],
193                     'injected': dict(
194                         (k, v['package_version']) for k, v in venv['metadata']['injected_packages'].items()
195                     ),
196                 }
197             return results
198 
199         installed = self.run_command(params=[{'_list': True}], process_output=process_list,
200                                      publish_rc=False, publish_out=False, publish_err=False, publish_cmd=False)
201 
202         if self.vars.name is not None:
203             app_list = installed.get(self.vars.name)
204             if app_list:
205                 return {self.vars.name: app_list}
206             else:
207                 return {}
208 
209         return installed
210 
211     def __init_module__(self):
212         if self.vars.executable:
213             self.command = [self.vars.executable]
214         else:
215             facts = ansible_facts(self.module, gather_subset=['python'])
216             self.command = [facts['python']['executable'], '-m', 'pipx']
217 
218         self.vars.set('application', self._retrieve_installed(), change=True, diff=True)
219 
220     def __quit_module__(self):
221         self.vars.application = self._retrieve_installed()
222 
223     def state_install(self):
224         if not self.vars.application or self.vars.force:
225             self.changed = True
226             if not self.module.check_mode:
227                 self.run_command(params=['state', 'index_url', 'install_deps', 'force', 'python',
228                                          {'name_source': [self.vars.name, self.vars.source]}])
229 
230     state_present = state_install
231 
232     def state_upgrade(self):
233         if not self.vars.application:
234             raise ModuleHelperException(
235                 "Trying to upgrade a non-existent application: {0}".format(self.vars.name))
236         if self.vars.force:
237             self.changed = True
238         if not self.module.check_mode:
239             self.run_command(params=['state', 'index_url', 'install_deps', 'force', 'name'])
240 
241     def state_uninstall(self):
242         if self.vars.application and not self.module.check_mode:
243             self.run_command(params=['state', 'name'])
244 
245     state_absent = state_uninstall
246 
247     def state_reinstall(self):
248         if not self.vars.application:
249             raise ModuleHelperException(
250                 "Trying to reinstall a non-existent application: {0}".format(self.vars.name))
251         self.changed = True
252         if not self.module.check_mode:
253             self.run_command(params=['state', 'name', 'python'])
254 
255     def state_inject(self):
256         if not self.vars.application:
257             raise ModuleHelperException(
258                 "Trying to inject packages into a non-existent application: {0}".format(self.vars.name))
259         if self.vars.force:
260             self.changed = True
261         if not self.module.check_mode:
262             self.run_command(params=['state', 'index_url', 'force', 'name', 'inject_packages'])
263 
264     def state_uninstall_all(self):
265         if not self.module.check_mode:
266             self.run_command(params=['state'])
267 
268     def state_reinstall_all(self):
269         if not self.module.check_mode:
270             self.run_command(params=['state', 'python'])
271 
272     def state_upgrade_all(self):
273         if self.vars.force:
274             self.changed = True
275         if not self.module.check_mode:
276             self.run_command(params=['state', 'include_injected', 'force'])
277 
278 
279 def main():
280     PipX.execute()
281 
282 
283 if __name__ == '__main__':
284     main()
285
```
--- 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/plugins/modules/packaging/language/pipx.py b/plugins/modules/packaging/language/pipx.py
--- a/plugins/modules/packaging/language/pipx.py
+++ b/plugins/modules/packaging/language/pipx.py
@@ -167,7 +167,7 @@
     command_args_formats = dict(
         state=dict(fmt=lambda v: [_state_map.get(v, v)]),
         name_source=dict(fmt=lambda n, s: [s] if s else [n], stars=1),
-        install_deps=dict(fmt="--install-deps", style=ArgFormat.BOOLEAN),
+        install_deps=dict(fmt="--include-deps", style=ArgFormat.BOOLEAN),
         inject_packages=dict(fmt=lambda v: v),
         force=dict(fmt="--force", style=ArgFormat.BOOLEAN),
         include_injected=dict(fmt="--include-injected", style=ArgFormat.BOOLEAN),

{"golden_diff": "diff --git a/plugins/modules/packaging/language/pipx.py b/plugins/modules/packaging/language/pipx.py\n--- a/plugins/modules/packaging/language/pipx.py\n+++ b/plugins/modules/packaging/language/pipx.py\n@@ -167,7 +167,7 @@\n     command_args_formats = dict(\n         state=dict(fmt=lambda v: [_state_map.get(v, v)]),\n         name_source=dict(fmt=lambda n, s: [s] if s else [n], stars=1),\n-        install_deps=dict(fmt=\"--install-deps\", style=ArgFormat.BOOLEAN),\n+        install_deps=dict(fmt=\"--include-deps\", style=ArgFormat.BOOLEAN),\n         inject_packages=dict(fmt=lambda v: v),\n         force=dict(fmt=\"--force\", style=ArgFormat.BOOLEAN),\n         include_injected=dict(fmt=\"--include-injected\", style=ArgFormat.BOOLEAN),\n", "issue": "pipx install option --install-deps not in version 0.16.4\n### Summary\n\nThe [pipx plugin](https://github.com/ansible-collections/community.general/blob/main/plugins/modules/packaging/language/pipx.py) has an option `install_deps` which adds an `--install-deps` option to the the `pipx` command line. This causes the `pipx` command to fail with version 0.16.4 of `pipx`.\r\n\r\nVersion 0.16.4 of the program appears to provide the `--include-deps` option instead.\r\n\r\nhttps://pypa.github.io/pipx/docs/#pipx-install\r\nhttps://docs.ansible.com/ansible/latest/collections/community/general/pipx_module.html#parameter-install_deps\n\n### Issue Type\n\nBug Report\n\n### Component Name\n\npipx\n\n### Ansible Version\n\n```\r\nansible [core 2.11.6]\r\n```\r\n\n\n### Community.general Version\n\nGlobal version\r\n```\r\nCollection        Version\r\n----------------- -------\r\ncommunity.general 3.8.1\r\n```\r\n\r\nPlaybook local version\r\n```\r\nCollection        Version\r\n----------------- -------\r\ncommunity.general 4.1.0\r\n```\n\n### Configuration\n\n```console (paste below)\r\n$ ansible-config dump --only-changed\r\n\r\n```\r\n\n\n### OS / Environment\n\nWSL2 (local)\r\nUbuntu 20.04 (remote)\n\n### Steps to Reproduce\n\n<!--- Paste example playbooks or commands between quotes below -->\r\n```yaml\r\ncommunity.general.pipx:\r\n  name: \"{{ pipx_item }}\"\r\n  include_deps: true\r\n\r\n```\r\n\n\n### Expected Results\n\nThe module to complete succesfully\n\n### Actual Results\n\n```console\r\nfailed: [laptop] (item=ansible-base) => changed=false\r\n  ansible_loop_var: pipx_item\r\n  cmd: /usr/bin/python3 -m pipx install --install-deps ansible-base\r\n  msg: |-\r\n    usage: __main__.py [-h] [--version]\r\n                       {install,inject,upgrade,upgrade-all,uninstall,uninstall-all,reinstall,reinstall-all,list,run,runpip,ensurepath,completions}\r\n                       ...\r\n    __main__.py: error: unrecognized arguments: --install-deps\r\n  pipx_item: ansible-base\r\n  rc: 2\r\n  stderr: |-\r\n    usage: __main__.py [-h] [--version]\r\n                       {install,inject,upgrade,upgrade-all,uninstall,uninstall-all,reinstall,reinstall-all,list,run,runpip,ensurepath,completions}\r\n                       ...\r\n    __main__.py: error: unrecognized arguments: --install-deps\r\n  stderr_lines: <omitted>\r\n  stdout: ''\r\n  stdout_lines: <omitted>\r\n```\r\n\n\n### Code of Conduct\n\n- [X] I agree to follow the Ansible Code of Conduct\n", "before_files": [{"content": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# (c) 2021, Alexei Znamensky <russoz@gmail.com>\n# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)\n\nfrom __future__ import absolute_import, division, print_function\n__metaclass__ = type\n\n\nDOCUMENTATION = '''\n---\nmodule: pipx\nshort_description: Manages applications installed with pipx\nversion_added: 3.8.0\ndescription:\n    - Manage Python applications installed in isolated virtualenvs using pipx.\noptions:\n    state:\n        type: str\n        choices: [present, absent, install, uninstall, uninstall_all, inject, upgrade, upgrade_all, reinstall, reinstall_all]\n        default: install\n        description:\n            - Desired state for the application.\n            - The states C(present) and C(absent) are aliases to C(install) and C(uninstall), respectively.\n    name:\n        type: str\n        description:\n            - >\n              The name of the application to be installed. It must to be a simple package name.\n              For passing package specifications or installing from URLs or directories,\n              please use the I(source) option.\n    source:\n        type: str\n        description:\n            - >\n              If the application source, such as a package with version specifier, or an URL,\n              directory or any other accepted specification. See C(pipx) documentation for more details.\n            - When specified, the C(pipx) command will use I(source) instead of I(name).\n    install_deps:\n        description:\n            - Include applications of dependent packages.\n            - Only used when I(state=install) or I(state=upgrade).\n        type: bool\n        default: false\n    inject_packages:\n        description:\n            - Packages to be injected into an existing virtual environment.\n            - Only used when I(state=inject).\n        type: list\n        elements: str\n    force:\n        description:\n            - Force modification of the application's virtual environment. See C(pipx) for details.\n            - Only used when I(state=install), I(state=upgrade), I(state=upgrade_all), or I(state=inject).\n        type: bool\n        default: false\n    include_injected:\n        description:\n            - Upgrade the injected packages along with the application.\n            - Only used when I(state=upgrade) or I(state=upgrade_all).\n        type: bool\n        default: false\n    index_url:\n        description:\n            - Base URL of Python Package Index.\n            - Only used when I(state=install), I(state=upgrade), or I(state=inject).\n        type: str\n    python:\n        description:\n            - Python version to be used when creating the application virtual environment. Must be 3.6+.\n            - Only used when I(state=install), I(state=reinstall), or I(state=reinstall_all).\n        type: str\n    executable:\n        description:\n            - Path to the C(pipx) installed in the system.\n            - >\n              If not specified, the module will use C(python -m pipx) to run the tool,\n              using the same Python interpreter as ansible itself.\n        type: path\nnotes:\n    - This module does not install the C(pipx) python package, however that can be easily done with the module M(ansible.builtin.pip).\n    - This module does not require C(pipx) to be in the shell C(PATH), but it must be loadable by Python as a module.\n    - Please note that C(pipx) requires Python 3.6 or above.\n    - >\n      This first implementation does not verify whether a specified version constraint has been installed or not.\n      Hence, when using version operators, C(pipx) module will always try to execute the operation,\n      even when the application was previously installed.\n      This feature will be added in the future.\n    - See also the C(pipx) documentation at U(https://pypa.github.io/pipx/).\nauthor:\n    - \"Alexei Znamensky (@russoz)\"\n'''\n\nEXAMPLES = '''\n- name: Install tox\n  community.general.pipx:\n    name: tox\n\n- name: Install tox from git repository\n  community.general.pipx:\n    name: tox\n    source: git+https://github.com/tox-dev/tox.git\n\n- name: Upgrade tox\n  community.general.pipx:\n    name: tox\n    state: upgrade\n\n- name: Reinstall black with specific Python version\n  community.general.pipx:\n    name: black\n    state: reinstall\n    python: 3.7\n\n- name: Uninstall pycowsay\n  community.general.pipx:\n    name: pycowsay\n    state: absent\n'''\n\n\nimport json\n\nfrom ansible_collections.community.general.plugins.module_utils.module_helper import (\n    CmdStateModuleHelper, ArgFormat, ModuleHelperException\n)\nfrom ansible.module_utils.facts.compat import ansible_facts\n\n\n_state_map = dict(\n    present='install',\n    absent='uninstall',\n    uninstall_all='uninstall-all',\n    upgrade_all='upgrade-all',\n    reinstall_all='reinstall-all',\n)\n\n\nclass PipX(CmdStateModuleHelper):\n    output_params = ['name', 'source', 'index_url', 'force', 'installdeps']\n    module = dict(\n        argument_spec=dict(\n            state=dict(type='str', default='install',\n                       choices=[\n                           'present', 'absent', 'install', 'uninstall', 'uninstall_all',\n                           'inject', 'upgrade', 'upgrade_all', 'reinstall', 'reinstall_all']),\n            name=dict(type='str'),\n            source=dict(type='str'),\n            install_deps=dict(type='bool', default=False),\n            inject_packages=dict(type='list', elements='str'),\n            force=dict(type='bool', default=False),\n            include_injected=dict(type='bool', default=False),\n            index_url=dict(type='str'),\n            python=dict(type='str'),\n            executable=dict(type='path')\n        ),\n        required_if=[\n            ('state', 'present', ['name']),\n            ('state', 'install', ['name']),\n            ('state', 'absent', ['name']),\n            ('state', 'uninstall', ['name']),\n            ('state', 'inject', ['name', 'inject_packages']),\n        ],\n        supports_check_mode=True,\n    )\n    command_args_formats = dict(\n        state=dict(fmt=lambda v: [_state_map.get(v, v)]),\n        name_source=dict(fmt=lambda n, s: [s] if s else [n], stars=1),\n        install_deps=dict(fmt=\"--install-deps\", style=ArgFormat.BOOLEAN),\n        inject_packages=dict(fmt=lambda v: v),\n        force=dict(fmt=\"--force\", style=ArgFormat.BOOLEAN),\n        include_injected=dict(fmt=\"--include-injected\", style=ArgFormat.BOOLEAN),\n        index_url=dict(fmt=('--index-url', '{0}'),),\n        python=dict(fmt=('--python', '{0}'),),\n        _list=dict(fmt=('list', '--include-injected', '--json'), style=ArgFormat.BOOLEAN),\n    )\n    check_rc = True\n    run_command_fixed_options = dict(\n        environ_update={'USE_EMOJI': '0'}\n    )\n\n    def _retrieve_installed(self):\n        def process_list(rc, out, err):\n            if not out:\n                return {}\n\n            results = {}\n            raw_data = json.loads(out)\n            for venv_name, venv in raw_data['venvs'].items():\n                results[venv_name] = {\n                    'version': venv['metadata']['main_package']['package_version'],\n                    'injected': dict(\n                        (k, v['package_version']) for k, v in venv['metadata']['injected_packages'].items()\n                    ),\n                }\n            return results\n\n        installed = self.run_command(params=[{'_list': True}], process_output=process_list,\n                                     publish_rc=False, publish_out=False, publish_err=False, publish_cmd=False)\n\n        if self.vars.name is not None:\n            app_list = installed.get(self.vars.name)\n            if app_list:\n                return {self.vars.name: app_list}\n            else:\n                return {}\n\n        return installed\n\n    def __init_module__(self):\n        if self.vars.executable:\n            self.command = [self.vars.executable]\n        else:\n            facts = ansible_facts(self.module, gather_subset=['python'])\n            self.command = [facts['python']['executable'], '-m', 'pipx']\n\n        self.vars.set('application', self._retrieve_installed(), change=True, diff=True)\n\n    def __quit_module__(self):\n        self.vars.application = self._retrieve_installed()\n\n    def state_install(self):\n        if not self.vars.application or self.vars.force:\n            self.changed = True\n            if not self.module.check_mode:\n                self.run_command(params=['state', 'index_url', 'install_deps', 'force', 'python',\n                                         {'name_source': [self.vars.name, self.vars.source]}])\n\n    state_present = state_install\n\n    def state_upgrade(self):\n        if not self.vars.application:\n            raise ModuleHelperException(\n                \"Trying to upgrade a non-existent application: {0}\".format(self.vars.name))\n        if self.vars.force:\n            self.changed = True\n        if not self.module.check_mode:\n            self.run_command(params=['state', 'index_url', 'install_deps', 'force', 'name'])\n\n    def state_uninstall(self):\n        if self.vars.application and not self.module.check_mode:\n            self.run_command(params=['state', 'name'])\n\n    state_absent = state_uninstall\n\n    def state_reinstall(self):\n        if not self.vars.application:\n            raise ModuleHelperException(\n                \"Trying to reinstall a non-existent application: {0}\".format(self.vars.name))\n        self.changed = True\n        if not self.module.check_mode:\n            self.run_command(params=['state', 'name', 'python'])\n\n    def state_inject(self):\n        if not self.vars.application:\n            raise ModuleHelperException(\n                \"Trying to inject packages into a non-existent application: {0}\".format(self.vars.name))\n        if self.vars.force:\n            self.changed = True\n        if not self.module.check_mode:\n            self.run_command(params=['state', 'index_url', 'force', 'name', 'inject_packages'])\n\n    def state_uninstall_all(self):\n        if not self.module.check_mode:\n            self.run_command(params=['state'])\n\n    def state_reinstall_all(self):\n        if not self.module.check_mode:\n            self.run_command(params=['state', 'python'])\n\n    def state_upgrade_all(self):\n        if self.vars.force:\n            self.changed = True\n        if not self.module.check_mode:\n            self.run_command(params=['state', 'include_injected', 'force'])\n\n\ndef main():\n    PipX.execute()\n\n\nif __name__ == '__main__':\n    main()\n", "path": "plugins/modules/packaging/language/pipx.py"}], "after_files": [{"content": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# (c) 2021, Alexei Znamensky <russoz@gmail.com>\n# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)\n\nfrom __future__ import absolute_import, division, print_function\n__metaclass__ = type\n\n\nDOCUMENTATION = '''\n---\nmodule: pipx\nshort_description: Manages applications installed with pipx\nversion_added: 3.8.0\ndescription:\n    - Manage Python applications installed in isolated virtualenvs using pipx.\noptions:\n    state:\n        type: str\n        choices: [present, absent, install, uninstall, uninstall_all, inject, upgrade, upgrade_all, reinstall, reinstall_all]\n        default: install\n        description:\n            - Desired state for the application.\n            - The states C(present) and C(absent) are aliases to C(install) and C(uninstall), respectively.\n    name:\n        type: str\n        description:\n            - >\n              The name of the application to be installed. It must to be a simple package name.\n              For passing package specifications or installing from URLs or directories,\n              please use the I(source) option.\n    source:\n        type: str\n        description:\n            - >\n              If the application source, such as a package with version specifier, or an URL,\n              directory or any other accepted specification. See C(pipx) documentation for more details.\n            - When specified, the C(pipx) command will use I(source) instead of I(name).\n    install_deps:\n        description:\n            - Include applications of dependent packages.\n            - Only used when I(state=install) or I(state=upgrade).\n        type: bool\n        default: false\n    inject_packages:\n        description:\n            - Packages to be injected into an existing virtual environment.\n            - Only used when I(state=inject).\n        type: list\n        elements: str\n    force:\n        description:\n            - Force modification of the application's virtual environment. See C(pipx) for details.\n            - Only used when I(state=install), I(state=upgrade), I(state=upgrade_all), or I(state=inject).\n        type: bool\n        default: false\n    include_injected:\n        description:\n            - Upgrade the injected packages along with the application.\n            - Only used when I(state=upgrade) or I(state=upgrade_all).\n        type: bool\n        default: false\n    index_url:\n        description:\n            - Base URL of Python Package Index.\n            - Only used when I(state=install), I(state=upgrade), or I(state=inject).\n        type: str\n    python:\n        description:\n            - Python version to be used when creating the application virtual environment. Must be 3.6+.\n            - Only used when I(state=install), I(state=reinstall), or I(state=reinstall_all).\n        type: str\n    executable:\n        description:\n            - Path to the C(pipx) installed in the system.\n            - >\n              If not specified, the module will use C(python -m pipx) to run the tool,\n              using the same Python interpreter as ansible itself.\n        type: path\nnotes:\n    - This module does not install the C(pipx) python package, however that can be easily done with the module M(ansible.builtin.pip).\n    - This module does not require C(pipx) to be in the shell C(PATH), but it must be loadable by Python as a module.\n    - Please note that C(pipx) requires Python 3.6 or above.\n    - >\n      This first implementation does not verify whether a specified version constraint has been installed or not.\n      Hence, when using version operators, C(pipx) module will always try to execute the operation,\n      even when the application was previously installed.\n      This feature will be added in the future.\n    - See also the C(pipx) documentation at U(https://pypa.github.io/pipx/).\nauthor:\n    - \"Alexei Znamensky (@russoz)\"\n'''\n\nEXAMPLES = '''\n- name: Install tox\n  community.general.pipx:\n    name: tox\n\n- name: Install tox from git repository\n  community.general.pipx:\n    name: tox\n    source: git+https://github.com/tox-dev/tox.git\n\n- name: Upgrade tox\n  community.general.pipx:\n    name: tox\n    state: upgrade\n\n- name: Reinstall black with specific Python version\n  community.general.pipx:\n    name: black\n    state: reinstall\n    python: 3.7\n\n- name: Uninstall pycowsay\n  community.general.pipx:\n    name: pycowsay\n    state: absent\n'''\n\n\nimport json\n\nfrom ansible_collections.community.general.plugins.module_utils.module_helper import (\n    CmdStateModuleHelper, ArgFormat, ModuleHelperException\n)\nfrom ansible.module_utils.facts.compat import ansible_facts\n\n\n_state_map = dict(\n    present='install',\n    absent='uninstall',\n    uninstall_all='uninstall-all',\n    upgrade_all='upgrade-all',\n    reinstall_all='reinstall-all',\n)\n\n\nclass PipX(CmdStateModuleHelper):\n    output_params = ['name', 'source', 'index_url', 'force', 'installdeps']\n    module = dict(\n        argument_spec=dict(\n            state=dict(type='str', default='install',\n                       choices=[\n                           'present', 'absent', 'install', 'uninstall', 'uninstall_all',\n                           'inject', 'upgrade', 'upgrade_all', 'reinstall', 'reinstall_all']),\n            name=dict(type='str'),\n            source=dict(type='str'),\n            install_deps=dict(type='bool', default=False),\n            inject_packages=dict(type='list', elements='str'),\n            force=dict(type='bool', default=False),\n            include_injected=dict(type='bool', default=False),\n            index_url=dict(type='str'),\n            python=dict(type='str'),\n            executable=dict(type='path')\n        ),\n        required_if=[\n            ('state', 'present', ['name']),\n            ('state', 'install', ['name']),\n            ('state', 'absent', ['name']),\n            ('state', 'uninstall', ['name']),\n            ('state', 'inject', ['name', 'inject_packages']),\n        ],\n        supports_check_mode=True,\n    )\n    command_args_formats = dict(\n        state=dict(fmt=lambda v: [_state_map.get(v, v)]),\n        name_source=dict(fmt=lambda n, s: [s] if s else [n], stars=1),\n        install_deps=dict(fmt=\"--include-deps\", style=ArgFormat.BOOLEAN),\n        inject_packages=dict(fmt=lambda v: v),\n        force=dict(fmt=\"--force\", style=ArgFormat.BOOLEAN),\n        include_injected=dict(fmt=\"--include-injected\", style=ArgFormat.BOOLEAN),\n        index_url=dict(fmt=('--index-url', '{0}'),),\n        python=dict(fmt=('--python', '{0}'),),\n        _list=dict(fmt=('list', '--include-injected', '--json'), style=ArgFormat.BOOLEAN),\n    )\n    check_rc = True\n    run_command_fixed_options = dict(\n        environ_update={'USE_EMOJI': '0'}\n    )\n\n    def _retrieve_installed(self):\n        def process_list(rc, out, err):\n            if not out:\n                return {}\n\n            results = {}\n            raw_data = json.loads(out)\n            for venv_name, venv in raw_data['venvs'].items():\n                results[venv_name] = {\n                    'version': venv['metadata']['main_package']['package_version'],\n                    'injected': dict(\n                        (k, v['package_version']) for k, v in venv['metadata']['injected_packages'].items()\n                    ),\n                }\n            return results\n\n        installed = self.run_command(params=[{'_list': True}], process_output=process_list,\n                                     publish_rc=False, publish_out=False, publish_err=False, publish_cmd=False)\n\n        if self.vars.name is not None:\n            app_list = installed.get(self.vars.name)\n            if app_list:\n                return {self.vars.name: app_list}\n            else:\n                return {}\n\n        return installed\n\n    def __init_module__(self):\n        if self.vars.executable:\n            self.command = [self.vars.executable]\n        else:\n            facts = ansible_facts(self.module, gather_subset=['python'])\n            self.command = [facts['python']['executable'], '-m', 'pipx']\n\n        self.vars.set('application', self._retrieve_installed(), change=True, diff=True)\n\n    def __quit_module__(self):\n        self.vars.application = self._retrieve_installed()\n\n    def state_install(self):\n        if not self.vars.application or self.vars.force:\n            self.changed = True\n            if not self.module.check_mode:\n                self.run_command(params=['state', 'index_url', 'install_deps', 'force', 'python',\n                                         {'name_source': [self.vars.name, self.vars.source]}])\n\n    state_present = state_install\n\n    def state_upgrade(self):\n        if not self.vars.application:\n            raise ModuleHelperException(\n                \"Trying to upgrade a non-existent application: {0}\".format(self.vars.name))\n        if self.vars.force:\n            self.changed = True\n        if not self.module.check_mode:\n            self.run_command(params=['state', 'index_url', 'install_deps', 'force', 'name'])\n\n    def state_uninstall(self):\n        if self.vars.application and not self.module.check_mode:\n            self.run_command(params=['state', 'name'])\n\n    state_absent = state_uninstall\n\n    def state_reinstall(self):\n        if not self.vars.application:\n            raise ModuleHelperException(\n                \"Trying to reinstall a non-existent application: {0}\".format(self.vars.name))\n        self.changed = True\n        if not self.module.check_mode:\n            self.run_command(params=['state', 'name', 'python'])\n\n    def state_inject(self):\n        if not self.vars.application:\n            raise ModuleHelperException(\n                \"Trying to inject packages into a non-existent application: {0}\".format(self.vars.name))\n        if self.vars.force:\n            self.changed = True\n        if not self.module.check_mode:\n            self.run_command(params=['state', 'index_url', 'force', 'name', 'inject_packages'])\n\n    def state_uninstall_all(self):\n        if not self.module.check_mode:\n            self.run_command(params=['state'])\n\n    def state_reinstall_all(self):\n        if not self.module.check_mode:\n            self.run_command(params=['state', 'python'])\n\n    def state_upgrade_all(self):\n        if self.vars.force:\n            self.changed = True\n        if not self.module.check_mode:\n            self.run_command(params=['state', 'include_injected', 'force'])\n\n\ndef main():\n    PipX.execute()\n\n\nif __name__ == '__main__':\n    main()\n", "path": "plugins/modules/packaging/language/pipx.py"}]}