Repository: ansible/ansible

Issue:
Pip module with empty names list
<!---
Verify first that your issue/request is not already reported on GitHub.
Also test if the latest release, and devel branch are affected too.
Always add information AFTER of these html comments.
-->

##### ISSUE TYPE
<!--- Pick one below and delete the rest -->
 - Bug Report

##### COMPONENT NAME
<!---
Insert below this comment the name of the module, plugin, task or feature.
Do not include extra details here, e.g. "vyos_command" not "the network module vyos_command" or the full path
-->
pip

##### ANSIBLE VERSION
<!--- Paste verbatim output from "ansible --version" between quotes below -->
```
ansible 2.5.0
  config file = /home/kbiernat/X/ansible/ansible.cfg
  configured module search path = ['/home/kbiernat/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.6/dist-packages/ansible
  executable location = /usr/local/bin/ansible
  python version = 3.6.3 (default, Oct  3 2017, 21:45:48) [GCC 7.2.0]
```

##### CONFIGURATION
<!---
If using Ansible 2.4 or above, paste the results of "ansible-config dump --only-changed"
Otherwise, mention any settings you have changed/added/removed in ansible.cfg
(or using the ANSIBLE_* environment variables).
-->

##### OS / ENVIRONMENT
<!---
Mention the OS you are running Ansible from, and the OS you are
managing, or say "N/A" for anything that is not platform-specific.
Also mention the specific version of what you are trying to control,
e.g. if this is a network bug the version of firmware on the network device.
-->
N/A

##### SUMMARY
<!--- Explain the problem briefly -->
This isn't purely Ansible problem, but I think handling of this is purely Ansible side.
After recent release of pip10, it's behaviour changed when list of packages is not provided.
Throws an error with empty list.

##### STEPS TO REPRODUCE
<!---
For bugs, show exactly how to reproduce the problem, using a minimal test-case.
For new features, show how the feature would be used.
-->

<!--- Paste example playbooks or commands between quotes below -->
```yaml
  - name: Install extra requirements bypassing project requirements
    pip:
      name: '{{ pip_requirements|default([]) }}'
```

The problem emerges when trying to do normal `pip install`.
It used to exit 0 with warning. Now it exits 1 with error.
I'm guessing pip command shouldn't even be invoked when requirements is None and name is None, or empty.

<!--- You can also paste gist.github.com links for larger files -->

##### EXPECTED RESULTS
<!--- What did you expect to happen when running the steps above? -->
Playbook passes, with `ok` status, as nothing should change with empty package list.

##### ACTUAL RESULTS
<!--- What actually happened? If possible run with extra verbosity (-vvvv) -->

<!--- Paste verbatim command output between quotes below -->
```
TASK [watchdogpolska.django.deploy : Install extra requirements bypassing project requirements] **********************************
Saturday 14 April 2018  19:24:00 +0200 (0:02:13.537)       0:02:41.144 ******** 
fatal: [X]: FAILED! => {"changed": false, "cmd": "/home/Y/env/bin/pip install", "msg": "\n:stderr: ERROR: You must give at least one requirement to install (see \"pip help install\")\n"}
```



Discussion:
Files identified in the description:
* [lib/ansible/modules/packaging/language/pip.py](https://github.com/ansible/ansible/blob/devel/lib/ansible/modules/packaging/language/pip.py)

If these files are inaccurate, please update the `component name` section of the description or use the `!component` bot command.

[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
cc @lujeni @mattupstate @robinro
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->

Resolving patch:
diff --git a/lib/ansible/modules/packaging/language/pip.py b/lib/ansible/modules/packaging/language/pip.py
--- a/lib/ansible/modules/packaging/language/pip.py
+++ b/lib/ansible/modules/packaging/language/pip.py
@@ -491,9 +491,13 @@ def main():
         if name:
             for pkg in name:
                 cmd += ' %s' % _get_full_name(pkg, version)
+        elif requirements:
+            cmd += ' -r %s' % requirements
         else:
-            if requirements:
-                cmd += ' -r %s' % requirements
+            module.exit_json(
+                changed=False,
+                warnings=["No valid name or requirements file found."],
+            )
 
         if module.check_mode:
             if extra_args or requirements or state == 'latest' or not name:


Test patch:
diff --git a/test/integration/targets/pip/tasks/pip.yml b/test/integration/targets/pip/tasks/pip.yml
--- a/test/integration/targets/pip/tasks/pip.yml
+++ b/test/integration/targets/pip/tasks/pip.yml
@@ -208,3 +208,14 @@
   assert:
     that:
       - "venv_chdir.changed"
+
+# ansible#38785
+- name: allow empty list of packages
+  pip:
+    name: []
+  register: pip_install_empty
+
+- name: ensure empty install is successful
+  assert:
+    that:
+      - not pip_install_empty.changed