We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
xfconf not setting return values as stated in documentation
<!--- Verify first that your issue is not already reported on GitHub -->
<!--- Also test if the latest release and devel branch are affected too -->
<!--- Complete *all* sections as described, this form is processed automatically -->

##### SUMMARY
<!--- Explain the problem briefly below -->
The xfconf documentations that it will return several values related to the operation (channel, previous_name, property, value, value_type). None of these are getting set ever.

This looks like it might have got missed during the recent refactor in #1322 by @russoz. There is a method named  `update_xfconf_output()` in the `XFConfProperty` class that looks like it would be the right thing to use for this, it just isn't called anywhere.

I think I see what needs to be fixed for this and will take a stab at a PR.

##### ISSUE TYPE
- Bug Report

##### COMPONENT NAME
<!--- Write the short name of the module, plugin, task or feature below, use your best guess if unsure -->
plugins/modules/system/xfconf.py

##### ANSIBLE VERSION
<!--- Paste verbatim output from "ansible --version" between quotes -->
```paste below
ansible 2.10.3
```

##### CONFIGURATION
<!--- Paste verbatim output from "ansible-config dump --only-changed" between quotes -->
```paste below
Not relevant
```

##### OS / ENVIRONMENT
<!--- Provide all relevant information below, e.g. target OS versions, network device firmware, etc. -->
Not relevant

##### STEPS TO REPRODUCE
<!--- Describe exactly how to reproduce the problem, using a minimal test-case -->
Attempting to get or set any value doesn't set the correct return values. In the case below, you would expect the return to contain a value named `value` with the current value of `/panels/panel-0/plugin-ids`, but it is missing.

<!--- Paste example playbooks or commands between quotes below -->
```yaml
- name: Get current panel layout
  xfconf:
    channel: xfce4-panel
    property: /panels/panel-0/plugin-ids
    state: get
  register: panel_order
```

<!--- HINT: You can paste gist.github.com links for larger files -->

##### EXPECTED RESULTS
<!--- Describe what you expected to happen when running the steps above -->
Expect to see the values set per the documentation in the return.

##### ACTUAL RESULTS
<!--- Describe what actually happened. If possible run with extra verbosity (-vvvv) -->
None of the expected values are there in the return. Note, the values do appear in the stdout from running the command, but this is a side effect and not following the docs.

<!--- Paste verbatim command output between quotes -->
```paste below
ok: [localhost] => {
    "changed": false,
    "force_lang": "C",
    "invocation": {
        "module_args": {
            "channel": "xfce4-panel",
            "force_array": false,
            "property": "/panels/panel-0/plugin-ids",
            "state": "get",
            "value": null,
            "value_type": null
        }
    },
    "rc": 0,
    "stderr": "",
    "stderr_lines": [],
    "stdout": "Value is an array with 13 items:\n\n1\n2\n3\n4\n15\n5\n6\n7\n8\n9\n10\n11\n12\n",
    "stdout_lines": [
        "Value is an array with 13 items:",
        "",
        "1",
        "2",
        "3",
        "4",
        "15",
        "5",
        "6",
        "7",
        "8",
        "9",
        "10",
        "11",
        "12"
    ]
}
```


--- 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/system/xfconf.py`
Content:
```
1 #!/usr/bin/python
2 # -*- coding: utf-8 -*-
3 # (c) 2017, Joseph Benden <joe@benden.us>
4 #
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 DOCUMENTATION = '''
11 module: xfconf
12 author:
13     - "Joseph Benden (@jbenden)"
14     - "Alexei Znamensky (@russoz)"
15 short_description: Edit XFCE4 Configurations
16 description:
17   - This module allows for the manipulation of Xfce 4 Configuration via
18     xfconf-query.  Please see the xfconf-query(1) man pages for more details.
19 options:
20   channel:
21     description:
22     - A Xfconf preference channel is a top-level tree key, inside of the
23       Xfconf repository that corresponds to the location for which all
24       application properties/keys are stored. See man xfconf-query(1)
25     required: yes
26     type: str
27   property:
28     description:
29     - A Xfce preference key is an element in the Xfconf repository
30       that corresponds to an application preference. See man xfconf-query(1)
31     required: yes
32     type: str
33   value:
34     description:
35     - Preference properties typically have simple values such as strings,
36       integers, or lists of strings and integers. This is ignored if the state
37       is "get". For array mode, use a list of values. See man xfconf-query(1)
38     type: list
39     elements: raw
40   value_type:
41     description:
42     - The type of value being set. This is ignored if the state is "get".
43       For array mode, use a list of types.
44     type: list
45     elements: str
46     choices: [ int, uint, bool, float, double, string ]
47   state:
48     type: str
49     description:
50     - The action to take upon the property/value.
51     choices: [ get, present, absent ]
52     default: "present"
53   force_array:
54     description:
55     - Force array even if only one element
56     type: bool
57     default: 'no'
58     aliases: ['array']
59     version_added: 1.0.0
60 '''
61 
62 EXAMPLES = """
63 - name: Change the DPI to "192"
64   xfconf:
65     channel: "xsettings"
66     property: "/Xft/DPI"
67     value_type: "int"
68     value: "192"
69 
70 - name: Set workspace names (4)
71   xfconf:
72     channel: xfwm4
73     property: /general/workspace_names
74     value_type: string
75     value: ['Main', 'Work1', 'Work2', 'Tmp']
76 
77 - name: Set workspace names (1)
78   xfconf:
79     channel: xfwm4
80     property: /general/workspace_names
81     value_type: string
82     value: ['Main']
83     force_array: yes
84 """
85 
86 RETURN = '''
87   channel:
88     description: The channel specified in the module parameters
89     returned: success
90     type: str
91     sample: "xsettings"
92   property:
93     description: The property specified in the module parameters
94     returned: success
95     type: str
96     sample: "/Xft/DPI"
97   value_type:
98     description: The type of the value that was changed
99     returned: success
100     type: str
101     sample: "int"
102   value:
103     description: The value of the preference key after executing the module
104     returned: success
105     type: str
106     sample: "192"
107   previous_value:
108     description: The value of the preference key before executing the module (None for "get" state).
109     returned: success
110     type: str
111     sample: "96"
112 '''
113 
114 from ansible_collections.community.general.plugins.module_utils.module_helper import (
115     ModuleHelper, CmdMixin, StateMixin, ArgFormat
116 )
117 
118 
119 def fix_bool(value):
120     vl = value.lower()
121     return vl if vl in ("true", "false") else value
122 
123 
124 @ArgFormat.stars_deco(1)
125 def values_fmt(values, value_types):
126     result = []
127     for value, value_type in zip(values, value_types):
128         if value_type == 'bool':
129             value = fix_bool(value)
130         result.append('--type')
131         result.append('{0}'.format(value_type))
132         result.append('--set')
133         result.append('{0}'.format(value))
134     return result
135 
136 
137 class XFConfException(Exception):
138     pass
139 
140 
141 class XFConfProperty(CmdMixin, StateMixin, ModuleHelper):
142     module = dict(
143         argument_spec=dict(
144             state=dict(default="present",
145                        choices=("present", "get", "absent"),
146                        type='str'),
147             channel=dict(required=True, type='str'),
148             property=dict(required=True, type='str'),
149             value_type=dict(required=False, type='list',
150                             elements='str', choices=('int', 'uint', 'bool', 'float', 'double', 'string')),
151             value=dict(required=False, type='list', elements='raw'),
152             force_array=dict(default=False, type='bool', aliases=['array']),
153         ),
154         required_if=[('state', 'present', ['value', 'value_type'])],
155         required_together=[('value', 'value_type')],
156         supports_check_mode=True,
157     )
158 
159     facts_name = "xfconf"
160     default_state = 'present'
161     command = 'xfconf-query'
162     command_args_formats = dict(
163         channel=dict(fmt=('--channel', '{0}'),),
164         property=dict(fmt=('--property', '{0}'),),
165         is_array=dict(fmt="--force-array", style=ArgFormat.BOOLEAN),
166         reset=dict(fmt="--reset", style=ArgFormat.BOOLEAN),
167         create=dict(fmt="--create", style=ArgFormat.BOOLEAN),
168         values_and_types=dict(fmt=values_fmt)
169     )
170 
171     def update_xfconf_output(self, **kwargs):
172         self.update_output(**kwargs)
173         self.update_facts(**kwargs)
174 
175     def __init_module__(self):
176         self.does_not = 'Property "{0}" does not exist on channel "{1}".'.format(self.module.params['property'],
177                                                                                  self.module.params['channel'])
178         self.vars.previous_value = self._get()
179 
180     def process_command_output(self, rc, out, err):
181         if err.rstrip() == self.does_not:
182             return None
183         if rc or len(err):
184             raise XFConfException('xfconf-query failed with error (rc={0}): {1}'.format(rc, err))
185 
186         result = out.rstrip()
187         if "Value is an array with" in result:
188             result = result.split("\n")
189             result.pop(0)
190             result.pop(0)
191 
192         return result
193 
194     @property
195     def changed(self):
196         if self.vars.previous_value is None:
197             return self.vars.value is not None
198         elif self.vars.value is None:
199             return self.vars.previous_value is not None
200         else:
201             return set(self.vars.previous_value) != set(self.vars.value)
202 
203     def _get(self):
204         return self.run_command(params=('channel', 'property'))
205 
206     def state_get(self):
207         self.vars.value = self.vars.previous_value
208 
209     def state_absent(self):
210         self.vars.value = None
211         self.run_command(params=('channel', 'property', 'reset'), extra_params={"reset": True})
212 
213     def state_present(self):
214         # stringify all values - in the CLI they will all be happy strings anyway
215         # and by doing this here the rest of the code can be agnostic to it
216         self.vars.value = [str(v) for v in self.module.params['value']]
217         value_type = self.module.params['value_type']
218 
219         values_len = len(self.vars.value)
220         types_len = len(value_type)
221 
222         if types_len == 1:
223             # use one single type for the entire list
224             value_type = value_type * values_len
225         elif types_len != values_len:
226             # or complain if lists' lengths are different
227             raise XFConfException('Number of elements in "value" and "value_type" must be the same')
228 
229         # fix boolean values
230         self.vars.value = [fix_bool(v[0]) if v[1] == 'bool' else v[0] for v in zip(self.vars.value, value_type)]
231 
232         # calculates if it is an array
233         self.vars.is_array = \
234             bool(self.module.params['force_array']) or \
235             isinstance(self.vars.previous_value, list) or \
236             values_len > 1
237 
238         params = ['channel', 'property', 'create']
239         if self.vars.is_array:
240             params.append('is_array')
241         params.append('values_and_types')
242 
243         extra_params = dict(values_and_types=(self.vars.value, value_type))
244         extra_params['create'] = True
245         extra_params['is_array'] = self.vars.is_array
246 
247         if not self.module.check_mode:
248             self.run_command(params=params, extra_params=extra_params)
249 
250         if not self.vars.is_array:
251             self.vars.value = self.vars.value[0]
252 
253 
254 def main():
255     xfconf = XFConfProperty()
256     xfconf.run()
257 
258 
259 if __name__ == '__main__':
260     main()
261
```
--- 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/system/xfconf.py b/plugins/modules/system/xfconf.py
--- a/plugins/modules/system/xfconf.py
+++ b/plugins/modules/system/xfconf.py
@@ -95,20 +95,28 @@
     type: str
     sample: "/Xft/DPI"
   value_type:
-    description: The type of the value that was changed
+    description:
+    - The type of the value that was changed (C(none) for C(get) and C(reset)
+      state). Either a single string value or a list of strings for array
+      types.
     returned: success
-    type: str
-    sample: "int"
+    type: string or list of strings
+    sample: '"int" or ["str", "str", "str"]'
   value:
-    description: The value of the preference key after executing the module
+    description:
+    - The value of the preference key after executing the module. Either a
+      single string value or a list of strings for array types.
     returned: success
-    type: str
-    sample: "192"
+    type: string or list of strings
+    sample: '"192" or ["orange", "yellow", "violet"]'
   previous_value:
-    description: The value of the preference key before executing the module (None for "get" state).
+    description:
+    - The value of the preference key before executing the module (C(none) for
+      C(get) state). Either a single string value or a list of strings for array
+      types.
     returned: success
-    type: str
-    sample: "96"
+    type: string or list of strings
+    sample: '"96" or ["red", "blue", "green"]'
 '''
 
 from ansible_collections.community.general.plugins.module_utils.module_helper import (
@@ -176,6 +184,9 @@
         self.does_not = 'Property "{0}" does not exist on channel "{1}".'.format(self.module.params['property'],
                                                                                  self.module.params['channel'])
         self.vars.previous_value = self._get()
+        self.update_xfconf_output(property=self.module.params['property'],
+                                  channel=self.module.params['channel'],
+                                  previous_value=None)
 
     def process_command_output(self, rc, out, err):
         if err.rstrip() == self.does_not:
@@ -205,10 +216,13 @@
 
     def state_get(self):
         self.vars.value = self.vars.previous_value
+        self.update_xfconf_output(value=self.vars.value)
 
     def state_absent(self):
         self.vars.value = None
         self.run_command(params=('channel', 'property', 'reset'), extra_params={"reset": True})
+        self.update_xfconf_output(previous_value=self.vars.previous_value,
+                                  value=None)
 
     def state_present(self):
         # stringify all values - in the CLI they will all be happy strings anyway
@@ -249,6 +263,11 @@
 
         if not self.vars.is_array:
             self.vars.value = self.vars.value[0]
+            value_type = value_type[0]
+
+        self.update_xfconf_output(previous_value=self.vars.previous_value,
+                                  value=self.vars.value,
+                                  type=value_type)
 
 
 def main():

{"golden_diff": "diff --git a/plugins/modules/system/xfconf.py b/plugins/modules/system/xfconf.py\n--- a/plugins/modules/system/xfconf.py\n+++ b/plugins/modules/system/xfconf.py\n@@ -95,20 +95,28 @@\n     type: str\n     sample: \"/Xft/DPI\"\n   value_type:\n-    description: The type of the value that was changed\n+    description:\n+    - The type of the value that was changed (C(none) for C(get) and C(reset)\n+      state). Either a single string value or a list of strings for array\n+      types.\n     returned: success\n-    type: str\n-    sample: \"int\"\n+    type: string or list of strings\n+    sample: '\"int\" or [\"str\", \"str\", \"str\"]'\n   value:\n-    description: The value of the preference key after executing the module\n+    description:\n+    - The value of the preference key after executing the module. Either a\n+      single string value or a list of strings for array types.\n     returned: success\n-    type: str\n-    sample: \"192\"\n+    type: string or list of strings\n+    sample: '\"192\" or [\"orange\", \"yellow\", \"violet\"]'\n   previous_value:\n-    description: The value of the preference key before executing the module (None for \"get\" state).\n+    description:\n+    - The value of the preference key before executing the module (C(none) for\n+      C(get) state). Either a single string value or a list of strings for array\n+      types.\n     returned: success\n-    type: str\n-    sample: \"96\"\n+    type: string or list of strings\n+    sample: '\"96\" or [\"red\", \"blue\", \"green\"]'\n '''\n \n from ansible_collections.community.general.plugins.module_utils.module_helper import (\n@@ -176,6 +184,9 @@\n         self.does_not = 'Property \"{0}\" does not exist on channel \"{1}\".'.format(self.module.params['property'],\n                                                                                  self.module.params['channel'])\n         self.vars.previous_value = self._get()\n+        self.update_xfconf_output(property=self.module.params['property'],\n+                                  channel=self.module.params['channel'],\n+                                  previous_value=None)\n \n     def process_command_output(self, rc, out, err):\n         if err.rstrip() == self.does_not:\n@@ -205,10 +216,13 @@\n \n     def state_get(self):\n         self.vars.value = self.vars.previous_value\n+        self.update_xfconf_output(value=self.vars.value)\n \n     def state_absent(self):\n         self.vars.value = None\n         self.run_command(params=('channel', 'property', 'reset'), extra_params={\"reset\": True})\n+        self.update_xfconf_output(previous_value=self.vars.previous_value,\n+                                  value=None)\n \n     def state_present(self):\n         # stringify all values - in the CLI they will all be happy strings anyway\n@@ -249,6 +263,11 @@\n \n         if not self.vars.is_array:\n             self.vars.value = self.vars.value[0]\n+            value_type = value_type[0]\n+\n+        self.update_xfconf_output(previous_value=self.vars.previous_value,\n+                                  value=self.vars.value,\n+                                  type=value_type)\n \n \n def main():\n", "issue": "xfconf not setting return values as stated in documentation\n<!--- Verify first that your issue is not already reported on GitHub -->\r\n<!--- Also test if the latest release and devel branch are affected too -->\r\n<!--- Complete *all* sections as described, this form is processed automatically -->\r\n\r\n##### SUMMARY\r\n<!--- Explain the problem briefly below -->\r\nThe xfconf documentations that it will return several values related to the operation (channel, previous_name, property, value, value_type). None of these are getting set ever.\r\n\r\nThis looks like it might have got missed during the recent refactor in #1322 by @russoz. There is a method named  `update_xfconf_output()` in the `XFConfProperty` class that looks like it would be the right thing to use for this, it just isn't called anywhere.\r\n\r\nI think I see what needs to be fixed for this and will take a stab at a PR.\r\n\r\n##### ISSUE TYPE\r\n- Bug Report\r\n\r\n##### COMPONENT NAME\r\n<!--- Write the short name of the module, plugin, task or feature below, use your best guess if unsure -->\r\nplugins/modules/system/xfconf.py\r\n\r\n##### ANSIBLE VERSION\r\n<!--- Paste verbatim output from \"ansible --version\" between quotes -->\r\n```paste below\r\nansible 2.10.3\r\n```\r\n\r\n##### CONFIGURATION\r\n<!--- Paste verbatim output from \"ansible-config dump --only-changed\" between quotes -->\r\n```paste below\r\nNot relevant\r\n```\r\n\r\n##### OS / ENVIRONMENT\r\n<!--- Provide all relevant information below, e.g. target OS versions, network device firmware, etc. -->\r\nNot relevant\r\n\r\n##### STEPS TO REPRODUCE\r\n<!--- Describe exactly how to reproduce the problem, using a minimal test-case -->\r\nAttempting to get or set any value doesn't set the correct return values. In the case below, you would expect the return to contain a value named `value` with the current value of `/panels/panel-0/plugin-ids`, but it is missing.\r\n\r\n<!--- Paste example playbooks or commands between quotes below -->\r\n```yaml\r\n- name: Get current panel layout\r\n  xfconf:\r\n    channel: xfce4-panel\r\n    property: /panels/panel-0/plugin-ids\r\n    state: get\r\n  register: panel_order\r\n```\r\n\r\n<!--- HINT: You can paste gist.github.com links for larger files -->\r\n\r\n##### EXPECTED RESULTS\r\n<!--- Describe what you expected to happen when running the steps above -->\r\nExpect to see the values set per the documentation in the return.\r\n\r\n##### ACTUAL RESULTS\r\n<!--- Describe what actually happened. If possible run with extra verbosity (-vvvv) -->\r\nNone of the expected values are there in the return. Note, the values do appear in the stdout from running the command, but this is a side effect and not following the docs.\r\n\r\n<!--- Paste verbatim command output between quotes -->\r\n```paste below\r\nok: [localhost] => {\r\n    \"changed\": false,\r\n    \"force_lang\": \"C\",\r\n    \"invocation\": {\r\n        \"module_args\": {\r\n            \"channel\": \"xfce4-panel\",\r\n            \"force_array\": false,\r\n            \"property\": \"/panels/panel-0/plugin-ids\",\r\n            \"state\": \"get\",\r\n            \"value\": null,\r\n            \"value_type\": null\r\n        }\r\n    },\r\n    \"rc\": 0,\r\n    \"stderr\": \"\",\r\n    \"stderr_lines\": [],\r\n    \"stdout\": \"Value is an array with 13 items:\\n\\n1\\n2\\n3\\n4\\n15\\n5\\n6\\n7\\n8\\n9\\n10\\n11\\n12\\n\",\r\n    \"stdout_lines\": [\r\n        \"Value is an array with 13 items:\",\r\n        \"\",\r\n        \"1\",\r\n        \"2\",\r\n        \"3\",\r\n        \"4\",\r\n        \"15\",\r\n        \"5\",\r\n        \"6\",\r\n        \"7\",\r\n        \"8\",\r\n        \"9\",\r\n        \"10\",\r\n        \"11\",\r\n        \"12\"\r\n    ]\r\n}\r\n```\r\n\n", "before_files": [{"content": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n# (c) 2017, Joseph Benden <joe@benden.us>\n#\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\nDOCUMENTATION = '''\nmodule: xfconf\nauthor:\n    - \"Joseph Benden (@jbenden)\"\n    - \"Alexei Znamensky (@russoz)\"\nshort_description: Edit XFCE4 Configurations\ndescription:\n  - This module allows for the manipulation of Xfce 4 Configuration via\n    xfconf-query.  Please see the xfconf-query(1) man pages for more details.\noptions:\n  channel:\n    description:\n    - A Xfconf preference channel is a top-level tree key, inside of the\n      Xfconf repository that corresponds to the location for which all\n      application properties/keys are stored. See man xfconf-query(1)\n    required: yes\n    type: str\n  property:\n    description:\n    - A Xfce preference key is an element in the Xfconf repository\n      that corresponds to an application preference. See man xfconf-query(1)\n    required: yes\n    type: str\n  value:\n    description:\n    - Preference properties typically have simple values such as strings,\n      integers, or lists of strings and integers. This is ignored if the state\n      is \"get\". For array mode, use a list of values. See man xfconf-query(1)\n    type: list\n    elements: raw\n  value_type:\n    description:\n    - The type of value being set. This is ignored if the state is \"get\".\n      For array mode, use a list of types.\n    type: list\n    elements: str\n    choices: [ int, uint, bool, float, double, string ]\n  state:\n    type: str\n    description:\n    - The action to take upon the property/value.\n    choices: [ get, present, absent ]\n    default: \"present\"\n  force_array:\n    description:\n    - Force array even if only one element\n    type: bool\n    default: 'no'\n    aliases: ['array']\n    version_added: 1.0.0\n'''\n\nEXAMPLES = \"\"\"\n- name: Change the DPI to \"192\"\n  xfconf:\n    channel: \"xsettings\"\n    property: \"/Xft/DPI\"\n    value_type: \"int\"\n    value: \"192\"\n\n- name: Set workspace names (4)\n  xfconf:\n    channel: xfwm4\n    property: /general/workspace_names\n    value_type: string\n    value: ['Main', 'Work1', 'Work2', 'Tmp']\n\n- name: Set workspace names (1)\n  xfconf:\n    channel: xfwm4\n    property: /general/workspace_names\n    value_type: string\n    value: ['Main']\n    force_array: yes\n\"\"\"\n\nRETURN = '''\n  channel:\n    description: The channel specified in the module parameters\n    returned: success\n    type: str\n    sample: \"xsettings\"\n  property:\n    description: The property specified in the module parameters\n    returned: success\n    type: str\n    sample: \"/Xft/DPI\"\n  value_type:\n    description: The type of the value that was changed\n    returned: success\n    type: str\n    sample: \"int\"\n  value:\n    description: The value of the preference key after executing the module\n    returned: success\n    type: str\n    sample: \"192\"\n  previous_value:\n    description: The value of the preference key before executing the module (None for \"get\" state).\n    returned: success\n    type: str\n    sample: \"96\"\n'''\n\nfrom ansible_collections.community.general.plugins.module_utils.module_helper import (\n    ModuleHelper, CmdMixin, StateMixin, ArgFormat\n)\n\n\ndef fix_bool(value):\n    vl = value.lower()\n    return vl if vl in (\"true\", \"false\") else value\n\n\n@ArgFormat.stars_deco(1)\ndef values_fmt(values, value_types):\n    result = []\n    for value, value_type in zip(values, value_types):\n        if value_type == 'bool':\n            value = fix_bool(value)\n        result.append('--type')\n        result.append('{0}'.format(value_type))\n        result.append('--set')\n        result.append('{0}'.format(value))\n    return result\n\n\nclass XFConfException(Exception):\n    pass\n\n\nclass XFConfProperty(CmdMixin, StateMixin, ModuleHelper):\n    module = dict(\n        argument_spec=dict(\n            state=dict(default=\"present\",\n                       choices=(\"present\", \"get\", \"absent\"),\n                       type='str'),\n            channel=dict(required=True, type='str'),\n            property=dict(required=True, type='str'),\n            value_type=dict(required=False, type='list',\n                            elements='str', choices=('int', 'uint', 'bool', 'float', 'double', 'string')),\n            value=dict(required=False, type='list', elements='raw'),\n            force_array=dict(default=False, type='bool', aliases=['array']),\n        ),\n        required_if=[('state', 'present', ['value', 'value_type'])],\n        required_together=[('value', 'value_type')],\n        supports_check_mode=True,\n    )\n\n    facts_name = \"xfconf\"\n    default_state = 'present'\n    command = 'xfconf-query'\n    command_args_formats = dict(\n        channel=dict(fmt=('--channel', '{0}'),),\n        property=dict(fmt=('--property', '{0}'),),\n        is_array=dict(fmt=\"--force-array\", style=ArgFormat.BOOLEAN),\n        reset=dict(fmt=\"--reset\", style=ArgFormat.BOOLEAN),\n        create=dict(fmt=\"--create\", style=ArgFormat.BOOLEAN),\n        values_and_types=dict(fmt=values_fmt)\n    )\n\n    def update_xfconf_output(self, **kwargs):\n        self.update_output(**kwargs)\n        self.update_facts(**kwargs)\n\n    def __init_module__(self):\n        self.does_not = 'Property \"{0}\" does not exist on channel \"{1}\".'.format(self.module.params['property'],\n                                                                                 self.module.params['channel'])\n        self.vars.previous_value = self._get()\n\n    def process_command_output(self, rc, out, err):\n        if err.rstrip() == self.does_not:\n            return None\n        if rc or len(err):\n            raise XFConfException('xfconf-query failed with error (rc={0}): {1}'.format(rc, err))\n\n        result = out.rstrip()\n        if \"Value is an array with\" in result:\n            result = result.split(\"\\n\")\n            result.pop(0)\n            result.pop(0)\n\n        return result\n\n    @property\n    def changed(self):\n        if self.vars.previous_value is None:\n            return self.vars.value is not None\n        elif self.vars.value is None:\n            return self.vars.previous_value is not None\n        else:\n            return set(self.vars.previous_value) != set(self.vars.value)\n\n    def _get(self):\n        return self.run_command(params=('channel', 'property'))\n\n    def state_get(self):\n        self.vars.value = self.vars.previous_value\n\n    def state_absent(self):\n        self.vars.value = None\n        self.run_command(params=('channel', 'property', 'reset'), extra_params={\"reset\": True})\n\n    def state_present(self):\n        # stringify all values - in the CLI they will all be happy strings anyway\n        # and by doing this here the rest of the code can be agnostic to it\n        self.vars.value = [str(v) for v in self.module.params['value']]\n        value_type = self.module.params['value_type']\n\n        values_len = len(self.vars.value)\n        types_len = len(value_type)\n\n        if types_len == 1:\n            # use one single type for the entire list\n            value_type = value_type * values_len\n        elif types_len != values_len:\n            # or complain if lists' lengths are different\n            raise XFConfException('Number of elements in \"value\" and \"value_type\" must be the same')\n\n        # fix boolean values\n        self.vars.value = [fix_bool(v[0]) if v[1] == 'bool' else v[0] for v in zip(self.vars.value, value_type)]\n\n        # calculates if it is an array\n        self.vars.is_array = \\\n            bool(self.module.params['force_array']) or \\\n            isinstance(self.vars.previous_value, list) or \\\n            values_len > 1\n\n        params = ['channel', 'property', 'create']\n        if self.vars.is_array:\n            params.append('is_array')\n        params.append('values_and_types')\n\n        extra_params = dict(values_and_types=(self.vars.value, value_type))\n        extra_params['create'] = True\n        extra_params['is_array'] = self.vars.is_array\n\n        if not self.module.check_mode:\n            self.run_command(params=params, extra_params=extra_params)\n\n        if not self.vars.is_array:\n            self.vars.value = self.vars.value[0]\n\n\ndef main():\n    xfconf = XFConfProperty()\n    xfconf.run()\n\n\nif __name__ == '__main__':\n    main()\n", "path": "plugins/modules/system/xfconf.py"}], "after_files": [{"content": "#!/usr/bin/python\n# -*- coding: utf-8 -*-\n# (c) 2017, Joseph Benden <joe@benden.us>\n#\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\nDOCUMENTATION = '''\nmodule: xfconf\nauthor:\n    - \"Joseph Benden (@jbenden)\"\n    - \"Alexei Znamensky (@russoz)\"\nshort_description: Edit XFCE4 Configurations\ndescription:\n  - This module allows for the manipulation of Xfce 4 Configuration via\n    xfconf-query.  Please see the xfconf-query(1) man pages for more details.\noptions:\n  channel:\n    description:\n    - A Xfconf preference channel is a top-level tree key, inside of the\n      Xfconf repository that corresponds to the location for which all\n      application properties/keys are stored. See man xfconf-query(1)\n    required: yes\n    type: str\n  property:\n    description:\n    - A Xfce preference key is an element in the Xfconf repository\n      that corresponds to an application preference. See man xfconf-query(1)\n    required: yes\n    type: str\n  value:\n    description:\n    - Preference properties typically have simple values such as strings,\n      integers, or lists of strings and integers. This is ignored if the state\n      is \"get\". For array mode, use a list of values. See man xfconf-query(1)\n    type: list\n    elements: raw\n  value_type:\n    description:\n    - The type of value being set. This is ignored if the state is \"get\".\n      For array mode, use a list of types.\n    type: list\n    elements: str\n    choices: [ int, uint, bool, float, double, string ]\n  state:\n    type: str\n    description:\n    - The action to take upon the property/value.\n    choices: [ get, present, absent ]\n    default: \"present\"\n  force_array:\n    description:\n    - Force array even if only one element\n    type: bool\n    default: 'no'\n    aliases: ['array']\n    version_added: 1.0.0\n'''\n\nEXAMPLES = \"\"\"\n- name: Change the DPI to \"192\"\n  xfconf:\n    channel: \"xsettings\"\n    property: \"/Xft/DPI\"\n    value_type: \"int\"\n    value: \"192\"\n\n- name: Set workspace names (4)\n  xfconf:\n    channel: xfwm4\n    property: /general/workspace_names\n    value_type: string\n    value: ['Main', 'Work1', 'Work2', 'Tmp']\n\n- name: Set workspace names (1)\n  xfconf:\n    channel: xfwm4\n    property: /general/workspace_names\n    value_type: string\n    value: ['Main']\n    force_array: yes\n\"\"\"\n\nRETURN = '''\n  channel:\n    description: The channel specified in the module parameters\n    returned: success\n    type: str\n    sample: \"xsettings\"\n  property:\n    description: The property specified in the module parameters\n    returned: success\n    type: str\n    sample: \"/Xft/DPI\"\n  value_type:\n    description:\n    - The type of the value that was changed (C(none) for C(get) and C(reset)\n      state). Either a single string value or a list of strings for array\n      types.\n    returned: success\n    type: string or list of strings\n    sample: '\"int\" or [\"str\", \"str\", \"str\"]'\n  value:\n    description:\n    - The value of the preference key after executing the module. Either a\n      single string value or a list of strings for array types.\n    returned: success\n    type: string or list of strings\n    sample: '\"192\" or [\"orange\", \"yellow\", \"violet\"]'\n  previous_value:\n    description:\n    - The value of the preference key before executing the module (C(none) for\n      C(get) state). Either a single string value or a list of strings for array\n      types.\n    returned: success\n    type: string or list of strings\n    sample: '\"96\" or [\"red\", \"blue\", \"green\"]'\n'''\n\nfrom ansible_collections.community.general.plugins.module_utils.module_helper import (\n    ModuleHelper, CmdMixin, StateMixin, ArgFormat\n)\n\n\ndef fix_bool(value):\n    vl = value.lower()\n    return vl if vl in (\"true\", \"false\") else value\n\n\n@ArgFormat.stars_deco(1)\ndef values_fmt(values, value_types):\n    result = []\n    for value, value_type in zip(values, value_types):\n        if value_type == 'bool':\n            value = fix_bool(value)\n        result.append('--type')\n        result.append('{0}'.format(value_type))\n        result.append('--set')\n        result.append('{0}'.format(value))\n    return result\n\n\nclass XFConfException(Exception):\n    pass\n\n\nclass XFConfProperty(CmdMixin, StateMixin, ModuleHelper):\n    module = dict(\n        argument_spec=dict(\n            state=dict(default=\"present\",\n                       choices=(\"present\", \"get\", \"absent\"),\n                       type='str'),\n            channel=dict(required=True, type='str'),\n            property=dict(required=True, type='str'),\n            value_type=dict(required=False, type='list',\n                            elements='str', choices=('int', 'uint', 'bool', 'float', 'double', 'string')),\n            value=dict(required=False, type='list', elements='raw'),\n            force_array=dict(default=False, type='bool', aliases=['array']),\n        ),\n        required_if=[('state', 'present', ['value', 'value_type'])],\n        required_together=[('value', 'value_type')],\n        supports_check_mode=True,\n    )\n\n    facts_name = \"xfconf\"\n    default_state = 'present'\n    command = 'xfconf-query'\n    command_args_formats = dict(\n        channel=dict(fmt=('--channel', '{0}'),),\n        property=dict(fmt=('--property', '{0}'),),\n        is_array=dict(fmt=\"--force-array\", style=ArgFormat.BOOLEAN),\n        reset=dict(fmt=\"--reset\", style=ArgFormat.BOOLEAN),\n        create=dict(fmt=\"--create\", style=ArgFormat.BOOLEAN),\n        values_and_types=dict(fmt=values_fmt)\n    )\n\n    def update_xfconf_output(self, **kwargs):\n        self.update_output(**kwargs)\n        self.update_facts(**kwargs)\n\n    def __init_module__(self):\n        self.does_not = 'Property \"{0}\" does not exist on channel \"{1}\".'.format(self.module.params['property'],\n                                                                                 self.module.params['channel'])\n        self.vars.previous_value = self._get()\n        self.update_xfconf_output(property=self.module.params['property'],\n                                  channel=self.module.params['channel'],\n                                  previous_value=None)\n\n    def process_command_output(self, rc, out, err):\n        if err.rstrip() == self.does_not:\n            return None\n        if rc or len(err):\n            raise XFConfException('xfconf-query failed with error (rc={0}): {1}'.format(rc, err))\n\n        result = out.rstrip()\n        if \"Value is an array with\" in result:\n            result = result.split(\"\\n\")\n            result.pop(0)\n            result.pop(0)\n\n        return result\n\n    @property\n    def changed(self):\n        if self.vars.previous_value is None:\n            return self.vars.value is not None\n        elif self.vars.value is None:\n            return self.vars.previous_value is not None\n        else:\n            return set(self.vars.previous_value) != set(self.vars.value)\n\n    def _get(self):\n        return self.run_command(params=('channel', 'property'))\n\n    def state_get(self):\n        self.vars.value = self.vars.previous_value\n        self.update_xfconf_output(value=self.vars.value)\n\n    def state_absent(self):\n        self.vars.value = None\n        self.run_command(params=('channel', 'property', 'reset'), extra_params={\"reset\": True})\n        self.update_xfconf_output(previous_value=self.vars.previous_value,\n                                  value=None)\n\n    def state_present(self):\n        # stringify all values - in the CLI they will all be happy strings anyway\n        # and by doing this here the rest of the code can be agnostic to it\n        self.vars.value = [str(v) for v in self.module.params['value']]\n        value_type = self.module.params['value_type']\n\n        values_len = len(self.vars.value)\n        types_len = len(value_type)\n\n        if types_len == 1:\n            # use one single type for the entire list\n            value_type = value_type * values_len\n        elif types_len != values_len:\n            # or complain if lists' lengths are different\n            raise XFConfException('Number of elements in \"value\" and \"value_type\" must be the same')\n\n        # fix boolean values\n        self.vars.value = [fix_bool(v[0]) if v[1] == 'bool' else v[0] for v in zip(self.vars.value, value_type)]\n\n        # calculates if it is an array\n        self.vars.is_array = \\\n            bool(self.module.params['force_array']) or \\\n            isinstance(self.vars.previous_value, list) or \\\n            values_len > 1\n\n        params = ['channel', 'property', 'create']\n        if self.vars.is_array:\n            params.append('is_array')\n        params.append('values_and_types')\n\n        extra_params = dict(values_and_types=(self.vars.value, value_type))\n        extra_params['create'] = True\n        extra_params['is_array'] = self.vars.is_array\n\n        if not self.module.check_mode:\n            self.run_command(params=params, extra_params=extra_params)\n\n        if not self.vars.is_array:\n            self.vars.value = self.vars.value[0]\n            value_type = value_type[0]\n\n        self.update_xfconf_output(previous_value=self.vars.previous_value,\n                                  value=self.vars.value,\n                                  type=value_type)\n\n\ndef main():\n    xfconf = XFConfProperty()\n    xfconf.run()\n\n\nif __name__ == '__main__':\n    main()\n", "path": "plugins/modules/system/xfconf.py"}]}