Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cpanm: using CmdRunner #5485

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions changelogs/fragments/5485-cpanm-cmd-runner.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
minor_changes:
- cpanm - refactored module to use ``CmdRunner`` to execute ``cpanm`` (https://github.com/ansible-collections/community.general/pull/5485).
50 changes: 25 additions & 25 deletions plugins/modules/cpanm.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,12 +134,11 @@

import os

from ansible_collections.community.general.plugins.module_utils.module_helper import (
ModuleHelper, CmdMixin, ArgFormat
)
from ansible_collections.community.general.plugins.module_utils.cmd_runner import CmdRunner, cmd_runner_fmt
from ansible_collections.community.general.plugins.module_utils.module_helper import ModuleHelper


class CPANMinus(CmdMixin, ModuleHelper):
class CPANMinus(ModuleHelper):
output_params = ['name', 'version']
module = dict(
argument_spec=dict(
Expand All @@ -160,13 +159,13 @@ class CPANMinus(CmdMixin, ModuleHelper):
)
command = 'cpanm'
command_args_formats = dict(
notest=dict(fmt="--notest", style=ArgFormat.BOOLEAN),
locallib=dict(fmt=('--local-lib', '{0}'),),
mirror=dict(fmt=('--mirror', '{0}'),),
mirror_only=dict(fmt="--mirror-only", style=ArgFormat.BOOLEAN),
installdeps=dict(fmt="--installdeps", style=ArgFormat.BOOLEAN),
notest=cmd_runner_fmt.as_bool("--notest"),
locallib=cmd_runner_fmt.as_opt_val('--local-lib'),
mirror=cmd_runner_fmt.as_opt_val('--mirror'),
mirror_only=cmd_runner_fmt.as_bool("--mirror-only"),
installdeps=cmd_runner_fmt.as_bool("--installdeps"),
pkg_spec=cmd_runner_fmt.as_list(),
)
check_rc = True

def __init_module__(self):
v = self.vars
Expand All @@ -181,15 +180,17 @@ def __init_module__(self):
self.vars.set("binary", self.command)

def _is_package_installed(self, name, locallib, version):
def process(rc, out, err):
return rc == 0

if name is None or name.endswith('.tar.gz'):
return False
version = "" if version is None else " " + version

env = {"PERL5LIB": "%s/lib/perl5" % locallib} if locallib else {}
cmd = ['perl', '-le', 'use %s%s;' % (name, version)]
rc, out, err = self.module.run_command(cmd, check_rc=False, environ_update=env)

return rc == 0
runner = CmdRunner(self.module, ["perl", "-le"], {"mod": cmd_runner_fmt.as_list()}, check_rc=False, environ_update=env)
with runner("mod", output_process=process) as ctx:
return ctx.run(mod='use %s%s;' % (name, version))

def sanitize_pkg_spec_version(self, pkg_spec, version):
if version is None:
Expand All @@ -207,29 +208,28 @@ def sanitize_pkg_spec_version(self, pkg_spec, version):
return pkg_spec + version

def __run__(self):
def process(rc, out, err):
if self.vars.mode == "compatibility" and rc != 0:
self.do_raise(msg=err, cmd=self.vars.cmd_args)
return 'is up to date' not in err and 'is up to date' not in out

runner = CmdRunner(self.module, self.command, self.command_args_formats, check_rc=True)

v = self.vars
pkg_param = 'from_path' if v.from_path else 'name'

if v.mode == 'compatibility':
if self._is_package_installed(v.name, v.locallib, v.version):
return
pkg_spec = v[pkg_param]
self.changed = self.run_command(
params=['notest', 'locallib', 'mirror', 'mirror_only', 'installdeps', {'name': pkg_spec}],
)
else:
installed = self._is_package_installed(v.name_check, v.locallib, v.version) if v.name_check else False
if installed:
return
pkg_spec = self.sanitize_pkg_spec_version(v[pkg_param], v.version)
self.changed = self.run_command(
params=['notest', 'locallib', 'mirror', 'mirror_only', 'installdeps', {'name': pkg_spec}],
)

def process_command_output(self, rc, out, err):
if self.vars.mode == "compatibility" and rc != 0:
self.do_raise(msg=err, cmd=self.vars.cmd_args)
return 'is up to date' not in err and 'is up to date' not in out

with runner(['notest', 'locallib', 'mirror', 'mirror_only', 'installdeps', 'pkg_spec'], output_process=process) as ctx:
self.changed = ctx.run(pkg_spec=pkg_spec)


def main():
Expand Down
11 changes: 6 additions & 5 deletions tests/unit/plugins/modules/test_cpanm.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
# Author: Alexei Znamensky ([email protected])
# Largely adapted from test_redhat_subscription by
# Jiri Hnidek ([email protected])
Expand Down Expand Up @@ -25,7 +26,7 @@ def patch_cpanm(mocker):
"""
Function used for mocking some parts of redhat_subscription module
"""
mocker.patch('ansible_collections.community.general.plugins.module_utils.module_helper.AnsibleModule.get_bin_path',
mocker.patch('ansible.module_utils.basic.AnsibleModule.get_bin_path',
return_value='/testbin/cpanm')


Expand All @@ -36,8 +37,8 @@ def patch_cpanm(mocker):
'id': 'install_dancer_compatibility',
'run_command.calls': [
(
['perl', '-le', 'use Dancer;'],
{'environ_update': {}, 'check_rc': False},
['/testbin/cpanm', '-le', 'use Dancer;'],
{'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False},
(2, '', 'error, not installed',), # output rc, out, err
),
(
Expand All @@ -55,8 +56,8 @@ def patch_cpanm(mocker):
'id': 'install_dancer_already_installed_compatibility',
'run_command.calls': [
(
['perl', '-le', 'use Dancer;'],
{'environ_update': {}, 'check_rc': False},
['/testbin/cpanm', '-le', 'use Dancer;'],
{'environ_update': {'LANGUAGE': 'C', 'LC_ALL': 'C'}, 'check_rc': False},
(0, '', '',), # output rc, out, err
),
],
Expand Down