Skip to content

Commit

Permalink
Transform functionality for command_instead_of_shell (#3675)
Browse files Browse the repository at this point in the history
  • Loading branch information
audgirka authored Aug 21, 2023
1 parent 225366a commit f6961ff
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 3 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/tox.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ jobs:
WSLENV: FORCE_COLOR:PYTEST_REQPASS:TOXENV:GITHUB_STEP_SUMMARY
# Number of expected test passes, safety measure for accidental skip of
# tests. Update value if you add/remove tests.
PYTEST_REQPASS: 811
PYTEST_REQPASS: 812
steps:
- name: Activate WSL1
if: "contains(matrix.shell, 'wsl')"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
- name: Fixture
hosts: localhost
tasks:
- name: Shell no pipe
ansible.builtin.command:
cmd: echo hello
changed_when: false

- name: Shell with jinja filter
ansible.builtin.command:
cmd: echo {{ "hello" | upper }}
changed_when: false

- name: Shell with jinja filter (fqcn)
ansible.builtin.command:
cmd: echo {{ "hello" | upper }}
changed_when: false

- name: Command with executable parameter
ansible.builtin.shell:
cmd: clear
args:
executable: /bin/bash
changed_when: false
25 changes: 25 additions & 0 deletions examples/playbooks/transform_command_instead_of_shell.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
- name: Fixture
hosts: localhost
tasks:
- name: Shell no pipe
ansible.builtin.shell:
cmd: echo hello
changed_when: false

- name: Shell with jinja filter
ansible.builtin.shell:
cmd: echo {{ "hello" | upper }}
changed_when: false

- name: Shell with jinja filter (fqcn)
ansible.builtin.shell:
cmd: echo {{ "hello" | upper }}
changed_when: false

- name: Command with executable parameter
ansible.builtin.shell:
cmd: clear
args:
executable: /bin/bash
changed_when: false
20 changes: 18 additions & 2 deletions src/ansiblelint/rules/command_instead_of_shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,18 @@
import sys
from typing import TYPE_CHECKING

from ansiblelint.rules import AnsibleLintRule
from ansiblelint.rules import AnsibleLintRule, TransformMixin
from ansiblelint.utils import get_cmd_args

if TYPE_CHECKING:
from ruamel.yaml.comments import CommentedMap, CommentedSeq

from ansiblelint.errors import MatchError
from ansiblelint.file_utils import Lintable
from ansiblelint.utils import Task


class UseCommandInsteadOfShellRule(AnsibleLintRule):
class UseCommandInsteadOfShellRule(AnsibleLintRule, TransformMixin):
"""Use shell only when shell functionality is required."""

id = "command-instead-of-shell"
Expand Down Expand Up @@ -62,6 +65,19 @@ def matchtask(
return not any(ch in jinja_stripped_cmd for ch in "&|<>;$\n*[]{}?`")
return False

def transform(
self,
match: MatchError,
lintable: Lintable,
data: CommentedMap | CommentedSeq | str,
) -> None:
if match.tag == "command-instead-of-shell":
target_task = self.seek(match.yaml_path, data)
for _ in range(len(target_task)):
k, v = target_task.popitem(False)
target_task["ansible.builtin.command" if "shell" in k else k] = v
match.fixed = True


# testing code to be loaded only with pytest or when executed the rule file
if "pytest" in sys.modules:
Expand Down
6 changes: 6 additions & 0 deletions test/test_transformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,12 @@ def fixture_runner_result(
pytest.param("examples/playbooks/vars/empty.yml", 1, False, id="empty"),
pytest.param("examples/playbooks/name-case.yml", 1, True, id="name_case"),
pytest.param("examples/playbooks/fqcn.yml", 3, True, id="fqcn"),
pytest.param(
"examples/playbooks/transform_command_instead_of_shell.yml",
3,
True,
id="cmd_instead_of_shell",
),
),
)
def test_transformer( # pylint: disable=too-many-arguments, too-many-locals
Expand Down

0 comments on commit f6961ff

Please sign in to comment.