We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Gem: Force is not working when uninstalling
### Summary

Force flag is not being appended when uninstalling, which could lead to a hang because gem could interactively ask if the user is sure to uninstall when there are dependencies

### Issue Type

Bug Report

### Component Name

gem

### Ansible Version

```console (paste below)
$ ansible --version
ansible [core 2.13.6]
  [...]
  python version = 3.11.0 (main, Oct 25 2022, 13:57:33) [Clang 14.0.0 (clang-1400.0.29.202)]
  jinja version = 3.1.2
```


### Community.general Version

```console (paste below)
$ ansible-galaxy collection list community.general
# /Users/admin/.ansible/collections/ansible_collections
Collection        Version
----------------- -------
community.general 5.6.0  

# /opt/homebrew/Cellar/ansible/6.6.0/libexec/lib/python3.11/site-packages/ansible_collections
Collection        Version
----------------- -------
community.general 5.8.0
```


### Configuration

Not relevant

### OS / Environment

Not relevant

### Steps to Reproduce

<!--- Paste example playbooks or commands between quotes below -->
```yaml (paste below)
- name: Uninstall fastlane gem
  community.general.gem:
    name: fastlane
    state: absent
    force: true
    user_install: no
```


### Expected Results

The `--force` flag should be appended to the `gem uninstall` command

### Actual Results

The `--force` flag is not being appended to the `gem uninstall` command

### 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/gem.py`
Content:
```
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3 
4 # Copyright (c) 2013, Johan Wiren <johan.wiren.se@gmail.com>
5 # GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
6 # SPDX-License-Identifier: GPL-3.0-or-later
7 
8 from __future__ import absolute_import, division, print_function
9 __metaclass__ = type
10 
11 
12 DOCUMENTATION = '''
13 ---
14 module: gem
15 short_description: Manage Ruby gems
16 description:
17   - Manage installation and uninstallation of Ruby gems.
18 options:
19   name:
20     type: str
21     description:
22       - The name of the gem to be managed.
23     required: true
24   state:
25     type: str
26     description:
27       - The desired state of the gem. C(latest) ensures that the latest version is installed.
28     required: false
29     choices: [present, absent, latest]
30     default: present
31   gem_source:
32     type: path
33     description:
34       - The path to a local gem used as installation source.
35     required: false
36   include_dependencies:
37     description:
38       - Whether to include dependencies or not.
39     required: false
40     type: bool
41     default: true
42   repository:
43     type: str
44     description:
45       - The repository from which the gem will be installed
46     required: false
47     aliases: [source]
48   user_install:
49     description:
50       - Install gem in user's local gems cache or for all users
51     required: false
52     type: bool
53     default: true
54   executable:
55     type: path
56     description:
57     - Override the path to the gem executable
58     required: false
59   install_dir:
60     type: path
61     description:
62     - Install the gems into a specific directory.
63       These gems will be independent from the global installed ones.
64       Specifying this requires user_install to be false.
65     required: false
66   bindir:
67     type: path
68     description:
69     - Install executables into a specific directory.
70     version_added: 3.3.0
71   norc:
72     type: bool
73     default: true
74     description:
75     - Avoid loading any C(.gemrc) file. Ignored for RubyGems prior to 2.5.2.
76     - The default changed from C(false) to C(true) in community.general 6.0.0.
77     version_added: 3.3.0
78   env_shebang:
79     description:
80       - Rewrite the shebang line on installed scripts to use /usr/bin/env.
81     required: false
82     default: false
83     type: bool
84   version:
85     type: str
86     description:
87       - Version of the gem to be installed/removed.
88     required: false
89   pre_release:
90     description:
91       - Allow installation of pre-release versions of the gem.
92     required: false
93     default: false
94     type: bool
95   include_doc:
96     description:
97       - Install with or without docs.
98     required: false
99     default: false
100     type: bool
101   build_flags:
102     type: str
103     description:
104       - Allow adding build flags for gem compilation
105     required: false
106   force:
107     description:
108       - Force gem to install, bypassing dependency checks.
109     required: false
110     default: false
111     type: bool
112 author:
113     - "Ansible Core Team"
114     - "Johan Wiren (@johanwiren)"
115 '''
116 
117 EXAMPLES = '''
118 - name: Install version 1.0 of vagrant
119   community.general.gem:
120     name: vagrant
121     version: 1.0
122     state: present
123 
124 - name: Install latest available version of rake
125   community.general.gem:
126     name: rake
127     state: latest
128 
129 - name: Install rake version 1.0 from a local gem on disk
130   community.general.gem:
131     name: rake
132     gem_source: /path/to/gems/rake-1.0.gem
133     state: present
134 '''
135 
136 import re
137 
138 from ansible.module_utils.basic import AnsibleModule
139 
140 
141 def get_rubygems_path(module):
142     if module.params['executable']:
143         result = module.params['executable'].split(' ')
144     else:
145         result = [module.get_bin_path('gem', True)]
146     return result
147 
148 
149 def get_rubygems_version(module):
150     if hasattr(get_rubygems_version, "ver"):
151         return get_rubygems_version.ver
152 
153     cmd = get_rubygems_path(module) + ['--version']
154     (rc, out, err) = module.run_command(cmd, check_rc=True)
155 
156     match = re.match(r'^(\d+)\.(\d+)\.(\d+)', out)
157     if not match:
158         return None
159 
160     ver = tuple(int(x) for x in match.groups())
161     get_rubygems_version.ver = ver
162 
163     return ver
164 
165 
166 def get_rubygems_environ(module):
167     if module.params['install_dir']:
168         return {'GEM_HOME': module.params['install_dir']}
169     return None
170 
171 
172 def get_installed_versions(module, remote=False):
173 
174     cmd = get_rubygems_path(module)
175     cmd.append('query')
176     cmd.extend(common_opts(module))
177     if remote:
178         cmd.append('--remote')
179         if module.params['repository']:
180             cmd.extend(['--source', module.params['repository']])
181     cmd.append('-n')
182     cmd.append('^%s$' % module.params['name'])
183 
184     environ = get_rubygems_environ(module)
185     (rc, out, err) = module.run_command(cmd, environ_update=environ, check_rc=True)
186     installed_versions = []
187     for line in out.splitlines():
188         match = re.match(r"\S+\s+\((?:default: )?(.+)\)", line)
189         if match:
190             versions = match.group(1)
191             for version in versions.split(', '):
192                 installed_versions.append(version.split()[0])
193     return installed_versions
194 
195 
196 def exists(module):
197     if module.params['state'] == 'latest':
198         remoteversions = get_installed_versions(module, remote=True)
199         if remoteversions:
200             module.params['version'] = remoteversions[0]
201     installed_versions = get_installed_versions(module)
202     if module.params['version']:
203         if module.params['version'] in installed_versions:
204             return True
205     else:
206         if installed_versions:
207             return True
208     return False
209 
210 
211 def common_opts(module):
212     opts = []
213     ver = get_rubygems_version(module)
214     if module.params['norc'] and ver and ver >= (2, 5, 2):
215         opts.append('--norc')
216     return opts
217 
218 
219 def uninstall(module):
220 
221     if module.check_mode:
222         return
223     cmd = get_rubygems_path(module)
224     environ = get_rubygems_environ(module)
225     cmd.append('uninstall')
226     cmd.extend(common_opts(module))
227     if module.params['install_dir']:
228         cmd.extend(['--install-dir', module.params['install_dir']])
229 
230     if module.params['bindir']:
231         cmd.extend(['--bindir', module.params['bindir']])
232 
233     if module.params['version']:
234         cmd.extend(['--version', module.params['version']])
235     else:
236         cmd.append('--all')
237     cmd.append('--executable')
238     cmd.append(module.params['name'])
239     module.run_command(cmd, environ_update=environ, check_rc=True)
240 
241 
242 def install(module):
243 
244     if module.check_mode:
245         return
246 
247     ver = get_rubygems_version(module)
248 
249     cmd = get_rubygems_path(module)
250     cmd.append('install')
251     cmd.extend(common_opts(module))
252     if module.params['version']:
253         cmd.extend(['--version', module.params['version']])
254     if module.params['repository']:
255         cmd.extend(['--source', module.params['repository']])
256     if not module.params['include_dependencies']:
257         cmd.append('--ignore-dependencies')
258     else:
259         if ver and ver < (2, 0, 0):
260             cmd.append('--include-dependencies')
261     if module.params['user_install']:
262         cmd.append('--user-install')
263     else:
264         cmd.append('--no-user-install')
265     if module.params['install_dir']:
266         cmd.extend(['--install-dir', module.params['install_dir']])
267     if module.params['bindir']:
268         cmd.extend(['--bindir', module.params['bindir']])
269     if module.params['pre_release']:
270         cmd.append('--pre')
271     if not module.params['include_doc']:
272         if ver and ver < (2, 0, 0):
273             cmd.append('--no-rdoc')
274             cmd.append('--no-ri')
275         else:
276             cmd.append('--no-document')
277     if module.params['env_shebang']:
278         cmd.append('--env-shebang')
279     cmd.append(module.params['gem_source'])
280     if module.params['build_flags']:
281         cmd.extend(['--', module.params['build_flags']])
282     if module.params['force']:
283         cmd.append('--force')
284     module.run_command(cmd, check_rc=True)
285 
286 
287 def main():
288 
289     module = AnsibleModule(
290         argument_spec=dict(
291             executable=dict(required=False, type='path'),
292             gem_source=dict(required=False, type='path'),
293             include_dependencies=dict(required=False, default=True, type='bool'),
294             name=dict(required=True, type='str'),
295             repository=dict(required=False, aliases=['source'], type='str'),
296             state=dict(required=False, default='present', choices=['present', 'absent', 'latest'], type='str'),
297             user_install=dict(required=False, default=True, type='bool'),
298             install_dir=dict(required=False, type='path'),
299             bindir=dict(type='path'),
300             norc=dict(type='bool', default=True),
301             pre_release=dict(required=False, default=False, type='bool'),
302             include_doc=dict(required=False, default=False, type='bool'),
303             env_shebang=dict(required=False, default=False, type='bool'),
304             version=dict(required=False, type='str'),
305             build_flags=dict(required=False, type='str'),
306             force=dict(required=False, default=False, type='bool'),
307         ),
308         supports_check_mode=True,
309         mutually_exclusive=[['gem_source', 'repository'], ['gem_source', 'version']],
310     )
311 
312     if module.params['version'] and module.params['state'] == 'latest':
313         module.fail_json(msg="Cannot specify version when state=latest")
314     if module.params['gem_source'] and module.params['state'] == 'latest':
315         module.fail_json(msg="Cannot maintain state=latest when installing from local source")
316     if module.params['user_install'] and module.params['install_dir']:
317         module.fail_json(msg="install_dir requires user_install=false")
318 
319     if not module.params['gem_source']:
320         module.params['gem_source'] = module.params['name']
321 
322     changed = False
323 
324     if module.params['state'] in ['present', 'latest']:
325         if not exists(module):
326             install(module)
327             changed = True
328     elif module.params['state'] == 'absent':
329         if exists(module):
330             uninstall(module)
331             changed = True
332 
333     result = {}
334     result['name'] = module.params['name']
335     result['state'] = module.params['state']
336     if module.params['version']:
337         result['version'] = module.params['version']
338     result['changed'] = changed
339 
340     module.exit_json(**result)
341 
342 
343 if __name__ == '__main__':
344     main()
345
```
--- 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/gem.py b/plugins/modules/gem.py
--- a/plugins/modules/gem.py
+++ b/plugins/modules/gem.py
@@ -105,7 +105,7 @@
     required: false
   force:
     description:
-      - Force gem to install, bypassing dependency checks.
+      - Force gem to (un-)install, bypassing dependency checks.
     required: false
     default: false
     type: bool
@@ -235,6 +235,8 @@
     else:
         cmd.append('--all')
     cmd.append('--executable')
+    if module.params['force']:
+        cmd.append('--force')
     cmd.append(module.params['name'])
     module.run_command(cmd, environ_update=environ, check_rc=True)

{"golden_diff": "diff --git a/plugins/modules/gem.py b/plugins/modules/gem.py\n--- a/plugins/modules/gem.py\n+++ b/plugins/modules/gem.py\n@@ -105,7 +105,7 @@\n     required: false\n   force:\n     description:\n-      - Force gem to install, bypassing dependency checks.\n+      - Force gem to (un-)install, bypassing dependency checks.\n     required: false\n     default: false\n     type: bool\n@@ -235,6 +235,8 @@\n     else:\n         cmd.append('--all')\n     cmd.append('--executable')\n+    if module.params['force']:\n+        cmd.append('--force')\n     cmd.append(module.params['name'])\n     module.run_command(cmd, environ_update=environ, check_rc=True)\n", "issue": "Gem: Force is not working when uninstalling\n### Summary\n\nForce flag is not being appended when uninstalling, which could lead to a hang because gem could interactively ask if the user is sure to uninstall when there are dependencies\n\n### Issue Type\n\nBug Report\n\n### Component Name\n\ngem\n\n### Ansible Version\n\n```console (paste below)\r\n$ ansible --version\r\nansible [core 2.13.6]\r\n  [...]\r\n  python version = 3.11.0 (main, Oct 25 2022, 13:57:33) [Clang 14.0.0 (clang-1400.0.29.202)]\r\n  jinja version = 3.1.2\r\n```\r\n\n\n### Community.general Version\n\n```console (paste below)\r\n$ ansible-galaxy collection list community.general\r\n# /Users/admin/.ansible/collections/ansible_collections\r\nCollection        Version\r\n----------------- -------\r\ncommunity.general 5.6.0  \r\n\r\n# /opt/homebrew/Cellar/ansible/6.6.0/libexec/lib/python3.11/site-packages/ansible_collections\r\nCollection        Version\r\n----------------- -------\r\ncommunity.general 5.8.0\r\n```\r\n\n\n### Configuration\n\nNot relevant\n\n### OS / Environment\n\nNot relevant\n\n### Steps to Reproduce\n\n<!--- Paste example playbooks or commands between quotes below -->\r\n```yaml (paste below)\r\n- name: Uninstall fastlane gem\r\n  community.general.gem:\r\n    name: fastlane\r\n    state: absent\r\n    force: true\r\n    user_install: no\r\n```\r\n\n\n### Expected Results\n\nThe `--force` flag should be appended to the `gem uninstall` command\n\n### Actual Results\n\nThe `--force` flag is not being appended to the `gem uninstall` command\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# Copyright (c) 2013, Johan Wiren <johan.wiren.se@gmail.com>\n# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)\n# SPDX-License-Identifier: GPL-3.0-or-later\n\nfrom __future__ import absolute_import, division, print_function\n__metaclass__ = type\n\n\nDOCUMENTATION = '''\n---\nmodule: gem\nshort_description: Manage Ruby gems\ndescription:\n  - Manage installation and uninstallation of Ruby gems.\noptions:\n  name:\n    type: str\n    description:\n      - The name of the gem to be managed.\n    required: true\n  state:\n    type: str\n    description:\n      - The desired state of the gem. C(latest) ensures that the latest version is installed.\n    required: false\n    choices: [present, absent, latest]\n    default: present\n  gem_source:\n    type: path\n    description:\n      - The path to a local gem used as installation source.\n    required: false\n  include_dependencies:\n    description:\n      - Whether to include dependencies or not.\n    required: false\n    type: bool\n    default: true\n  repository:\n    type: str\n    description:\n      - The repository from which the gem will be installed\n    required: false\n    aliases: [source]\n  user_install:\n    description:\n      - Install gem in user's local gems cache or for all users\n    required: false\n    type: bool\n    default: true\n  executable:\n    type: path\n    description:\n    - Override the path to the gem executable\n    required: false\n  install_dir:\n    type: path\n    description:\n    - Install the gems into a specific directory.\n      These gems will be independent from the global installed ones.\n      Specifying this requires user_install to be false.\n    required: false\n  bindir:\n    type: path\n    description:\n    - Install executables into a specific directory.\n    version_added: 3.3.0\n  norc:\n    type: bool\n    default: true\n    description:\n    - Avoid loading any C(.gemrc) file. Ignored for RubyGems prior to 2.5.2.\n    - The default changed from C(false) to C(true) in community.general 6.0.0.\n    version_added: 3.3.0\n  env_shebang:\n    description:\n      - Rewrite the shebang line on installed scripts to use /usr/bin/env.\n    required: false\n    default: false\n    type: bool\n  version:\n    type: str\n    description:\n      - Version of the gem to be installed/removed.\n    required: false\n  pre_release:\n    description:\n      - Allow installation of pre-release versions of the gem.\n    required: false\n    default: false\n    type: bool\n  include_doc:\n    description:\n      - Install with or without docs.\n    required: false\n    default: false\n    type: bool\n  build_flags:\n    type: str\n    description:\n      - Allow adding build flags for gem compilation\n    required: false\n  force:\n    description:\n      - Force gem to install, bypassing dependency checks.\n    required: false\n    default: false\n    type: bool\nauthor:\n    - \"Ansible Core Team\"\n    - \"Johan Wiren (@johanwiren)\"\n'''\n\nEXAMPLES = '''\n- name: Install version 1.0 of vagrant\n  community.general.gem:\n    name: vagrant\n    version: 1.0\n    state: present\n\n- name: Install latest available version of rake\n  community.general.gem:\n    name: rake\n    state: latest\n\n- name: Install rake version 1.0 from a local gem on disk\n  community.general.gem:\n    name: rake\n    gem_source: /path/to/gems/rake-1.0.gem\n    state: present\n'''\n\nimport re\n\nfrom ansible.module_utils.basic import AnsibleModule\n\n\ndef get_rubygems_path(module):\n    if module.params['executable']:\n        result = module.params['executable'].split(' ')\n    else:\n        result = [module.get_bin_path('gem', True)]\n    return result\n\n\ndef get_rubygems_version(module):\n    if hasattr(get_rubygems_version, \"ver\"):\n        return get_rubygems_version.ver\n\n    cmd = get_rubygems_path(module) + ['--version']\n    (rc, out, err) = module.run_command(cmd, check_rc=True)\n\n    match = re.match(r'^(\\d+)\\.(\\d+)\\.(\\d+)', out)\n    if not match:\n        return None\n\n    ver = tuple(int(x) for x in match.groups())\n    get_rubygems_version.ver = ver\n\n    return ver\n\n\ndef get_rubygems_environ(module):\n    if module.params['install_dir']:\n        return {'GEM_HOME': module.params['install_dir']}\n    return None\n\n\ndef get_installed_versions(module, remote=False):\n\n    cmd = get_rubygems_path(module)\n    cmd.append('query')\n    cmd.extend(common_opts(module))\n    if remote:\n        cmd.append('--remote')\n        if module.params['repository']:\n            cmd.extend(['--source', module.params['repository']])\n    cmd.append('-n')\n    cmd.append('^%s$' % module.params['name'])\n\n    environ = get_rubygems_environ(module)\n    (rc, out, err) = module.run_command(cmd, environ_update=environ, check_rc=True)\n    installed_versions = []\n    for line in out.splitlines():\n        match = re.match(r\"\\S+\\s+\\((?:default: )?(.+)\\)\", line)\n        if match:\n            versions = match.group(1)\n            for version in versions.split(', '):\n                installed_versions.append(version.split()[0])\n    return installed_versions\n\n\ndef exists(module):\n    if module.params['state'] == 'latest':\n        remoteversions = get_installed_versions(module, remote=True)\n        if remoteversions:\n            module.params['version'] = remoteversions[0]\n    installed_versions = get_installed_versions(module)\n    if module.params['version']:\n        if module.params['version'] in installed_versions:\n            return True\n    else:\n        if installed_versions:\n            return True\n    return False\n\n\ndef common_opts(module):\n    opts = []\n    ver = get_rubygems_version(module)\n    if module.params['norc'] and ver and ver >= (2, 5, 2):\n        opts.append('--norc')\n    return opts\n\n\ndef uninstall(module):\n\n    if module.check_mode:\n        return\n    cmd = get_rubygems_path(module)\n    environ = get_rubygems_environ(module)\n    cmd.append('uninstall')\n    cmd.extend(common_opts(module))\n    if module.params['install_dir']:\n        cmd.extend(['--install-dir', module.params['install_dir']])\n\n    if module.params['bindir']:\n        cmd.extend(['--bindir', module.params['bindir']])\n\n    if module.params['version']:\n        cmd.extend(['--version', module.params['version']])\n    else:\n        cmd.append('--all')\n    cmd.append('--executable')\n    cmd.append(module.params['name'])\n    module.run_command(cmd, environ_update=environ, check_rc=True)\n\n\ndef install(module):\n\n    if module.check_mode:\n        return\n\n    ver = get_rubygems_version(module)\n\n    cmd = get_rubygems_path(module)\n    cmd.append('install')\n    cmd.extend(common_opts(module))\n    if module.params['version']:\n        cmd.extend(['--version', module.params['version']])\n    if module.params['repository']:\n        cmd.extend(['--source', module.params['repository']])\n    if not module.params['include_dependencies']:\n        cmd.append('--ignore-dependencies')\n    else:\n        if ver and ver < (2, 0, 0):\n            cmd.append('--include-dependencies')\n    if module.params['user_install']:\n        cmd.append('--user-install')\n    else:\n        cmd.append('--no-user-install')\n    if module.params['install_dir']:\n        cmd.extend(['--install-dir', module.params['install_dir']])\n    if module.params['bindir']:\n        cmd.extend(['--bindir', module.params['bindir']])\n    if module.params['pre_release']:\n        cmd.append('--pre')\n    if not module.params['include_doc']:\n        if ver and ver < (2, 0, 0):\n            cmd.append('--no-rdoc')\n            cmd.append('--no-ri')\n        else:\n            cmd.append('--no-document')\n    if module.params['env_shebang']:\n        cmd.append('--env-shebang')\n    cmd.append(module.params['gem_source'])\n    if module.params['build_flags']:\n        cmd.extend(['--', module.params['build_flags']])\n    if module.params['force']:\n        cmd.append('--force')\n    module.run_command(cmd, check_rc=True)\n\n\ndef main():\n\n    module = AnsibleModule(\n        argument_spec=dict(\n            executable=dict(required=False, type='path'),\n            gem_source=dict(required=False, type='path'),\n            include_dependencies=dict(required=False, default=True, type='bool'),\n            name=dict(required=True, type='str'),\n            repository=dict(required=False, aliases=['source'], type='str'),\n            state=dict(required=False, default='present', choices=['present', 'absent', 'latest'], type='str'),\n            user_install=dict(required=False, default=True, type='bool'),\n            install_dir=dict(required=False, type='path'),\n            bindir=dict(type='path'),\n            norc=dict(type='bool', default=True),\n            pre_release=dict(required=False, default=False, type='bool'),\n            include_doc=dict(required=False, default=False, type='bool'),\n            env_shebang=dict(required=False, default=False, type='bool'),\n            version=dict(required=False, type='str'),\n            build_flags=dict(required=False, type='str'),\n            force=dict(required=False, default=False, type='bool'),\n        ),\n        supports_check_mode=True,\n        mutually_exclusive=[['gem_source', 'repository'], ['gem_source', 'version']],\n    )\n\n    if module.params['version'] and module.params['state'] == 'latest':\n        module.fail_json(msg=\"Cannot specify version when state=latest\")\n    if module.params['gem_source'] and module.params['state'] == 'latest':\n        module.fail_json(msg=\"Cannot maintain state=latest when installing from local source\")\n    if module.params['user_install'] and module.params['install_dir']:\n        module.fail_json(msg=\"install_dir requires user_install=false\")\n\n    if not module.params['gem_source']:\n        module.params['gem_source'] = module.params['name']\n\n    changed = False\n\n    if module.params['state'] in ['present', 'latest']:\n        if not exists(module):\n            install(module)\n            changed = True\n    elif module.params['state'] == 'absent':\n        if exists(module):\n            uninstall(module)\n            changed = True\n\n    result = {}\n    result['name'] = module.params['name']\n    result['state'] = module.params['state']\n    if module.params['version']:\n        result['version'] = module.params['version']\n    result['changed'] = changed\n\n    module.exit_json(**result)\n\n\nif __name__ == '__main__':\n    main()\n", "path": "plugins/modules/gem.py"}], "after_files": [{"content": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n\n# Copyright (c) 2013, Johan Wiren <johan.wiren.se@gmail.com>\n# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)\n# SPDX-License-Identifier: GPL-3.0-or-later\n\nfrom __future__ import absolute_import, division, print_function\n__metaclass__ = type\n\n\nDOCUMENTATION = '''\n---\nmodule: gem\nshort_description: Manage Ruby gems\ndescription:\n  - Manage installation and uninstallation of Ruby gems.\noptions:\n  name:\n    type: str\n    description:\n      - The name of the gem to be managed.\n    required: true\n  state:\n    type: str\n    description:\n      - The desired state of the gem. C(latest) ensures that the latest version is installed.\n    required: false\n    choices: [present, absent, latest]\n    default: present\n  gem_source:\n    type: path\n    description:\n      - The path to a local gem used as installation source.\n    required: false\n  include_dependencies:\n    description:\n      - Whether to include dependencies or not.\n    required: false\n    type: bool\n    default: true\n  repository:\n    type: str\n    description:\n      - The repository from which the gem will be installed\n    required: false\n    aliases: [source]\n  user_install:\n    description:\n      - Install gem in user's local gems cache or for all users\n    required: false\n    type: bool\n    default: true\n  executable:\n    type: path\n    description:\n    - Override the path to the gem executable\n    required: false\n  install_dir:\n    type: path\n    description:\n    - Install the gems into a specific directory.\n      These gems will be independent from the global installed ones.\n      Specifying this requires user_install to be false.\n    required: false\n  bindir:\n    type: path\n    description:\n    - Install executables into a specific directory.\n    version_added: 3.3.0\n  norc:\n    type: bool\n    default: true\n    description:\n    - Avoid loading any C(.gemrc) file. Ignored for RubyGems prior to 2.5.2.\n    - The default changed from C(false) to C(true) in community.general 6.0.0.\n    version_added: 3.3.0\n  env_shebang:\n    description:\n      - Rewrite the shebang line on installed scripts to use /usr/bin/env.\n    required: false\n    default: false\n    type: bool\n  version:\n    type: str\n    description:\n      - Version of the gem to be installed/removed.\n    required: false\n  pre_release:\n    description:\n      - Allow installation of pre-release versions of the gem.\n    required: false\n    default: false\n    type: bool\n  include_doc:\n    description:\n      - Install with or without docs.\n    required: false\n    default: false\n    type: bool\n  build_flags:\n    type: str\n    description:\n      - Allow adding build flags for gem compilation\n    required: false\n  force:\n    description:\n      - Force gem to (un-)install, bypassing dependency checks.\n    required: false\n    default: false\n    type: bool\nauthor:\n    - \"Ansible Core Team\"\n    - \"Johan Wiren (@johanwiren)\"\n'''\n\nEXAMPLES = '''\n- name: Install version 1.0 of vagrant\n  community.general.gem:\n    name: vagrant\n    version: 1.0\n    state: present\n\n- name: Install latest available version of rake\n  community.general.gem:\n    name: rake\n    state: latest\n\n- name: Install rake version 1.0 from a local gem on disk\n  community.general.gem:\n    name: rake\n    gem_source: /path/to/gems/rake-1.0.gem\n    state: present\n'''\n\nimport re\n\nfrom ansible.module_utils.basic import AnsibleModule\n\n\ndef get_rubygems_path(module):\n    if module.params['executable']:\n        result = module.params['executable'].split(' ')\n    else:\n        result = [module.get_bin_path('gem', True)]\n    return result\n\n\ndef get_rubygems_version(module):\n    if hasattr(get_rubygems_version, \"ver\"):\n        return get_rubygems_version.ver\n\n    cmd = get_rubygems_path(module) + ['--version']\n    (rc, out, err) = module.run_command(cmd, check_rc=True)\n\n    match = re.match(r'^(\\d+)\\.(\\d+)\\.(\\d+)', out)\n    if not match:\n        return None\n\n    ver = tuple(int(x) for x in match.groups())\n    get_rubygems_version.ver = ver\n\n    return ver\n\n\ndef get_rubygems_environ(module):\n    if module.params['install_dir']:\n        return {'GEM_HOME': module.params['install_dir']}\n    return None\n\n\ndef get_installed_versions(module, remote=False):\n\n    cmd = get_rubygems_path(module)\n    cmd.append('query')\n    cmd.extend(common_opts(module))\n    if remote:\n        cmd.append('--remote')\n        if module.params['repository']:\n            cmd.extend(['--source', module.params['repository']])\n    cmd.append('-n')\n    cmd.append('^%s$' % module.params['name'])\n\n    environ = get_rubygems_environ(module)\n    (rc, out, err) = module.run_command(cmd, environ_update=environ, check_rc=True)\n    installed_versions = []\n    for line in out.splitlines():\n        match = re.match(r\"\\S+\\s+\\((?:default: )?(.+)\\)\", line)\n        if match:\n            versions = match.group(1)\n            for version in versions.split(', '):\n                installed_versions.append(version.split()[0])\n    return installed_versions\n\n\ndef exists(module):\n    if module.params['state'] == 'latest':\n        remoteversions = get_installed_versions(module, remote=True)\n        if remoteversions:\n            module.params['version'] = remoteversions[0]\n    installed_versions = get_installed_versions(module)\n    if module.params['version']:\n        if module.params['version'] in installed_versions:\n            return True\n    else:\n        if installed_versions:\n            return True\n    return False\n\n\ndef common_opts(module):\n    opts = []\n    ver = get_rubygems_version(module)\n    if module.params['norc'] and ver and ver >= (2, 5, 2):\n        opts.append('--norc')\n    return opts\n\n\ndef uninstall(module):\n\n    if module.check_mode:\n        return\n    cmd = get_rubygems_path(module)\n    environ = get_rubygems_environ(module)\n    cmd.append('uninstall')\n    cmd.extend(common_opts(module))\n    if module.params['install_dir']:\n        cmd.extend(['--install-dir', module.params['install_dir']])\n\n    if module.params['bindir']:\n        cmd.extend(['--bindir', module.params['bindir']])\n\n    if module.params['version']:\n        cmd.extend(['--version', module.params['version']])\n    else:\n        cmd.append('--all')\n    cmd.append('--executable')\n    if module.params['force']:\n        cmd.append('--force')\n    cmd.append(module.params['name'])\n    module.run_command(cmd, environ_update=environ, check_rc=True)\n\n\ndef install(module):\n\n    if module.check_mode:\n        return\n\n    ver = get_rubygems_version(module)\n\n    cmd = get_rubygems_path(module)\n    cmd.append('install')\n    cmd.extend(common_opts(module))\n    if module.params['version']:\n        cmd.extend(['--version', module.params['version']])\n    if module.params['repository']:\n        cmd.extend(['--source', module.params['repository']])\n    if not module.params['include_dependencies']:\n        cmd.append('--ignore-dependencies')\n    else:\n        if ver and ver < (2, 0, 0):\n            cmd.append('--include-dependencies')\n    if module.params['user_install']:\n        cmd.append('--user-install')\n    else:\n        cmd.append('--no-user-install')\n    if module.params['install_dir']:\n        cmd.extend(['--install-dir', module.params['install_dir']])\n    if module.params['bindir']:\n        cmd.extend(['--bindir', module.params['bindir']])\n    if module.params['pre_release']:\n        cmd.append('--pre')\n    if not module.params['include_doc']:\n        if ver and ver < (2, 0, 0):\n            cmd.append('--no-rdoc')\n            cmd.append('--no-ri')\n        else:\n            cmd.append('--no-document')\n    if module.params['env_shebang']:\n        cmd.append('--env-shebang')\n    cmd.append(module.params['gem_source'])\n    if module.params['build_flags']:\n        cmd.extend(['--', module.params['build_flags']])\n    if module.params['force']:\n        cmd.append('--force')\n    module.run_command(cmd, check_rc=True)\n\n\ndef main():\n\n    module = AnsibleModule(\n        argument_spec=dict(\n            executable=dict(required=False, type='path'),\n            gem_source=dict(required=False, type='path'),\n            include_dependencies=dict(required=False, default=True, type='bool'),\n            name=dict(required=True, type='str'),\n            repository=dict(required=False, aliases=['source'], type='str'),\n            state=dict(required=False, default='present', choices=['present', 'absent', 'latest'], type='str'),\n            user_install=dict(required=False, default=True, type='bool'),\n            install_dir=dict(required=False, type='path'),\n            bindir=dict(type='path'),\n            norc=dict(type='bool', default=True),\n            pre_release=dict(required=False, default=False, type='bool'),\n            include_doc=dict(required=False, default=False, type='bool'),\n            env_shebang=dict(required=False, default=False, type='bool'),\n            version=dict(required=False, type='str'),\n            build_flags=dict(required=False, type='str'),\n            force=dict(required=False, default=False, type='bool'),\n        ),\n        supports_check_mode=True,\n        mutually_exclusive=[['gem_source', 'repository'], ['gem_source', 'version']],\n    )\n\n    if module.params['version'] and module.params['state'] == 'latest':\n        module.fail_json(msg=\"Cannot specify version when state=latest\")\n    if module.params['gem_source'] and module.params['state'] == 'latest':\n        module.fail_json(msg=\"Cannot maintain state=latest when installing from local source\")\n    if module.params['user_install'] and module.params['install_dir']:\n        module.fail_json(msg=\"install_dir requires user_install=false\")\n\n    if not module.params['gem_source']:\n        module.params['gem_source'] = module.params['name']\n\n    changed = False\n\n    if module.params['state'] in ['present', 'latest']:\n        if not exists(module):\n            install(module)\n            changed = True\n    elif module.params['state'] == 'absent':\n        if exists(module):\n            uninstall(module)\n            changed = True\n\n    result = {}\n    result['name'] = module.params['name']\n    result['state'] = module.params['state']\n    if module.params['version']:\n        result['version'] = module.params['version']\n    result['changed'] = changed\n\n    module.exit_json(**result)\n\n\nif __name__ == '__main__':\n    main()\n", "path": "plugins/modules/gem.py"}]}