Skip to content

Commit

Permalink
Merge pull request #55492 from Akm0d/pip_arbitrary_args
Browse files Browse the repository at this point in the history
Allow arbitrary arguments to be bassed through the pip module
  • Loading branch information
dwoz authored Dec 4, 2019
2 parents c232896 + e73c4c9 commit e96c0fa
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 2 deletions.
37 changes: 37 additions & 0 deletions salt/modules/pip.py
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,7 @@ def install(pkgs=None, # pylint: disable=R0912,R0913,R0914
use_vt=False,
trusted_host=None,
no_cache_dir=False,
extra_args=None,
cache_dir=None,
no_binary=None,
disable_version_check=False,
Expand Down Expand Up @@ -605,6 +606,24 @@ def install(pkgs=None, # pylint: disable=R0912,R0913,R0914
no_cache_dir
Disable the cache.
extra_args
pip keyword and positional arguments not yet implemented in salt
.. code-block:: yaml
salt '*' pip.install pandas extra_args="[{'--latest-pip-kwarg':'param'}, '--latest-pip-arg']"
.. warning::
If unsupported options are passed here that are not supported in a
minion's version of pip, a `No such option error` will be thrown.
Will be translated into the following pip command:
.. code-block:: bash
pip install pandas --latest-pip-kwarg param --latest-pip-arg
disable_version_check
Pip may periodically check PyPI to determine whether a new version of
pip is available to download. Passing True for this option disables
Expand Down Expand Up @@ -896,6 +915,24 @@ def install(pkgs=None, # pylint: disable=R0912,R0913,R0914
if trusted_host:
cmd.extend(['--trusted-host', trusted_host])

if extra_args:
# These are arguments from the latest version of pip that
# have not yet been implemented in salt
for arg in extra_args:
# It is a keyword argument
if isinstance(arg, dict):
# There will only ever be one item in this dictionary
key, val = arg.popitem()
# Don't allow any recursion into keyword arg definitions
# Don't allow multiple definitions of a keyword
if isinstance(val, (dict, list)):
raise TypeError("Too many levels in: {}".format(key))
# This is a a normal one-to-one keyword argument
cmd.extend([key, val])
# It is a positional argument, append it to the list
else:
cmd.append(arg)

cmd_kwargs = dict(saltenv=saltenv, use_vt=use_vt, runas=user)

if kwargs:
Expand Down
19 changes: 19 additions & 0 deletions salt/states/pip_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,7 @@ def installed(name,
no_cache_dir=False,
cache_dir=None,
no_binary=None,
extra_args=None,
**kwargs):
'''
Make sure the package is installed
Expand Down Expand Up @@ -665,6 +666,23 @@ def installed(name,
- reload_modules: True
- exists_action: i
extra_args
pip keyword and positional arguments not yet implemented in salt
.. code-block:: yaml
pandas:
pip.installed:
- name: pandas
- extra_args:
- --latest-pip-kwarg: param
- --latest-pip-arg
.. warning::
If unsupported options are passed here that are not supported in a
minion's version of pip, a `No such option error` will be thrown.
.. _`virtualenv`: http://www.virtualenv.org/en/latest/
'''
Expand Down Expand Up @@ -901,6 +919,7 @@ def installed(name,
use_vt=use_vt,
trusted_host=trusted_host,
no_cache_dir=no_cache_dir,
extra_args=extra_args,
disable_version_check=True,
**kwargs
)
Expand Down
38 changes: 36 additions & 2 deletions tests/unit/modules/test_pip.py
Original file line number Diff line number Diff line change
Expand Up @@ -803,6 +803,41 @@ def test_install_multiple_requirements_arguments_in_resulting_command(self):
python_shell=False,
)

def test_install_extra_args_arguments_in_resulting_command(self):
pkg = 'pep8'
mock = MagicMock(return_value={'retcode': 0, 'stdout': ''})
with patch.dict(pip.__salt__, {'cmd.run_all': mock}):
pip.install(pkg, extra_args=[
{"--latest-pip-kwarg": "param"},
"--latest-pip-arg"
])
expected = [
sys.executable, '-m', 'pip', 'install', pkg,
"--latest-pip-kwarg", "param", "--latest-pip-arg"
]
mock.assert_called_with(
expected,
saltenv='base',
runas=None,
use_vt=False,
python_shell=False,
)

def test_install_extra_args_arguments_recursion_error(self):
pkg = 'pep8'
mock = MagicMock(return_value={'retcode': 0, 'stdout': ''})
with patch.dict(pip.__salt__, {'cmd.run_all': mock}):

self.assertRaises(TypeError, lambda: pip.install(
pkg, extra_args=[
{"--latest-pip-kwarg": ["param1", "param2"]},
]))

self.assertRaises(TypeError, lambda: pip.install(
pkg, extra_args=[
{"--latest-pip-kwarg": [{"--too-deep": dict()}]},
]))

def test_uninstall_multiple_requirements_arguments_in_resulting_command(self):
with patch('salt.modules.pip._get_cached_requirements') as get_cached_requirements:
cached_reqs = [
Expand Down Expand Up @@ -1280,8 +1315,7 @@ def test_is_installed_false(self):

def test_install_pre_argument_in_resulting_command(self):
pkg = 'pep8'
# Lower than 1.4 versions don't end-up with `--pre` in the resulting
# output
# Lower than 1.4 versions don't end up with `--pre` in the resulting output
mock = MagicMock(side_effect=[
{'retcode': 0, 'stdout': 'pip 1.2.0 /path/to/site-packages/pip'},
{'retcode': 0, 'stdout': ''}
Expand Down

0 comments on commit e96c0fa

Please sign in to comment.