Repository: ansible/ansible

Issue:
Modules with creates= / removes= could support check mode
##### ISSUE TYPE
Feature Idea

##### COMPONENT NAME
core

##### ANSIBLE VERSION
2.2

##### CONFIGURATION


##### OS / ENVIRONMENT


##### SUMMARY
Currently modules that do not support check mode (e.g. the `command` module) report that the "remote module does not support check mode", however if they use `creates=` or `removes=` Ansible could perform a check-mode, or at least evaluate whether it would not run.

##### STEPS TO REPRODUCE


##### EXPECTED RESULTS


##### ACTUAL RESULTS





Discussion:
Just had the same idea. It's a good idea. 


Resolving patch:
diff --git a/lib/ansible/modules/commands/command.py b/lib/ansible/modules/commands/command.py
--- a/lib/ansible/modules/commands/command.py
+++ b/lib/ansible/modules/commands/command.py
@@ -64,6 +64,8 @@
        use the C(command) module when possible.
     -  " C(creates), C(removes), and C(chdir) can be specified after the command.
        For instance, if you only want to run a command if a certain file does not exist, use this."
+    -  Check mode is supported when passing C(creates) or C(removes). If running in check mode and either of these are specified, the module will
+       check for the existence of the file and report the correct changed status. If these are not supplied, the task will be skipped.
     -  The C(executable) parameter is removed since version 2.4. If you have a need for this parameter, use the M(shell) module instead.
     -  For Windows targets, use the M(win_command) module instead.
 author:
@@ -185,7 +187,8 @@ def main():
             # The default for this really comes from the action plugin
             warn=dict(type='bool', default=True),
             stdin=dict(required=False),
-        )
+        ),
+        supports_check_mode=True,
     )
     shell = module.params['_uses_shell']
     chdir = module.params['chdir']
@@ -245,7 +248,13 @@ def main():
 
     startd = datetime.datetime.now()
 
-    rc, out, err = module.run_command(args, executable=executable, use_unsafe_shell=shell, encoding=None, data=stdin)
+    if not module.check_mode:
+        rc, out, err = module.run_command(args, executable=executable, use_unsafe_shell=shell, encoding=None, data=stdin)
+    elif creates or removes:
+        rc = 0
+        out = err = b'Command would have run if not in check mode'
+    else:
+        module.exit_json(msg="skipped, running in check mode", skipped=True)
 
     endd = datetime.datetime.now()
     delta = endd - startd
diff --git a/lib/ansible/modules/commands/shell.py b/lib/ansible/modules/commands/shell.py
--- a/lib/ansible/modules/commands/shell.py
+++ b/lib/ansible/modules/commands/shell.py
@@ -61,6 +61,10 @@
      playbooks will follow the trend of using M(command) unless the C(shell)
      module is explicitly required. When running ad-hoc commands, use your best
      judgement.
+  -  Check mode is supported when passing C(creates) or C(removes). If running
+     in check mode and either of these are specified, the module will check for
+     the existence of the file and report the correct changed status. If these
+     are not supplied, the task will be skipped.
   -  To sanitize any variables passed to the shell module, you should use
      "{{ var | quote }}" instead of just "{{ var }}" to make sure they don't include evil things like semicolons.
   - For Windows targets, use the M(win_shell) module instead.


Test patch: