Skip to content

Commit

Permalink
Create the task-values[name-word-misspelled] rule
Browse files Browse the repository at this point in the history
The convention 'Do not use abbreviations in task names.' will be
enforced by this new rule.

The regular expression used underneath the split_words method treats a
hyphened word as separate words. For example, the word libvirt-ro
would be split into libvirt and ro words. Hence, why the dictionary.txt
file may appear to contain abbreviations. Also, the words loaded into
the dictionary.txt file are case-insensitive because I want to use 'en'
language dictionary.
  • Loading branch information
cavcrosby committed Dec 23, 2024
1 parent c77994b commit 2d917ca
Show file tree
Hide file tree
Showing 8 changed files with 153 additions and 22 deletions.
9 changes: 9 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ repos:
additional_dependencies:
- ansible-core ==2.17.0
- jmespath ==1.0.1
- pyspellchecker ==0.8.1

- repo: https://github.com/adrienverge/yamllint.git
rev: v1.35.1
Expand Down Expand Up @@ -45,6 +46,14 @@ repos:
additional_dependencies:
- [email protected]

- id: gendict.py
name: gendict.py
entry: ./scripts/gendict.py
language: python
additional_dependencies:
- ansible-lint ==24.9.0
- pyspellchecker ==0.8.1

- repo: https://github.com/gitleaks/gitleaks.git
rev: v8.18.3
hooks:
Expand Down
2 changes: 0 additions & 2 deletions docs/code.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,6 @@

## Conventions

- [Do not use abbreviations in task names.](../examples/playbooks/single_quote_patterns.yml)
- Notice how distribution was used instead of distro.
- [Group package installations based on the need.](../examples/playbooks/append_distro_specificness.yml)
- [Utilize the local relative path searching when specifying the src parameter to ansible.builtin.template tasks.](../examples/playbooks/utilize_tpl_searching_controller.yml)
- [Prefix all `ansible` tags with a verb.](../examples/playbooks/utilize_tpl_searching_controller.yml)
Expand Down
95 changes: 95 additions & 0 deletions docs/dictionary.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
admin
ansible_user
api
apt's
apt_inst
apt_pkg
aptsources
arptables
authorized_keys
bgp
br_netfilter
ca
calicoctl
cfg
cni
conf
containerd
crds
cri
cronjobs
csrs
debian
dhcp
dns
dnsmasq
dotfile
ebtables
en_us
etcd
etcdctl
fail2ban
foo
glibc's
gpg
grub_cmdline_linux_default
haproxy
homelab
hostname
ifnames
init
inode
inventory_hostname
ip6tables
iptables
irc
k8s_controller
k8s_first_controller
k8s_ha_controller
k8s_worker
keepalived
kube
kube_apiservers
kubeadm
kubeconfig
kubectl
kubelet
kubelets
kubernetes
kubernetes's
kvm
libexec
libvirt
libvirtd
lockdown
locpath
logind
namespace
networkd
nginx
nodeport
pam_access
permitrootlogin
poseidon
poseidon_ingress_nginx_node_http_port
python3
qemu
readyz
resolv
ro
schedulable
sigterm
sshd
systemd
tarball
tigera
tmux
udev
uri
userland
utf
vrrp
weechat
weechat's
whoami
x86_64
17 changes: 0 additions & 17 deletions examples/playbooks/single_quote_patterns.yml

This file was deleted.

3 changes: 0 additions & 3 deletions extensions/molecule/examples_resources/playbooks/converge.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@
- name: Verify the append_distro_specificness playbook execution # noqa tag-plays
ansible.builtin.import_playbook: ../../../../examples/playbooks/append_distro_specificness.yml

- name: Verify the single_quote_patterns playbook execution # noqa tag-plays
ansible.builtin.import_playbook: ../../../../examples/playbooks/single_quote_patterns.yml

- name: Verify the use_keywords_order_plays playbook execution # noqa tag-plays
ansible.builtin.import_playbook: ../../../../examples/playbooks/use_keywords_order_plays.yml

Expand Down
1 change: 1 addition & 0 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ molecule ==24.6.0
molecule-plugins[docker] ==23.5.3
mypy ==1.13.0
pre-commit ==3.7.1
pyspellchecker ==0.8.1
ruff ==0.8.0
19 changes: 19 additions & 0 deletions rules/task_values.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from __future__ import annotations

from pathlib import Path
from typing import TYPE_CHECKING

from ansiblelint.constants import (
Expand All @@ -12,6 +13,7 @@
from ansiblelint.yaml_utils import nested_items_path
from jinja2 import Environment
from jinja2.nodes import Filter
from spellchecker import SpellChecker # type: ignore # spellchecker stubs don't exist

from ansible.parsing.yaml.objects import ( # type: ignore # ansible.parsing.yaml.objects stubs don't exist
AnsibleUnicode,
Expand All @@ -30,7 +32,9 @@
from jinja2.nodes import Node

AnsibleUnicodeItems: TypeAlias = dict[int, AnsibleUnicode]
spell_checker = SpellChecker()
init_plugin_loader() # required before using loaders
spell_checker.word_frequency.load_text_file(Path("./docs/dictionary.txt"))


class TaskValuesRule(AnsibleLintRule):
Expand All @@ -41,6 +45,7 @@ class TaskValuesRule(AnsibleLintRule):
tags = ["homelab-cm"]
_ids = {
"task-values[shell-options]": "Start ansible.builtin.shell task with setting errexit and pipefail options (bash).", # noqa E501
"task-values[name-word-misspelled]": "Correct any misspelled words in task name ({word}).", # noqa E501
"task-values[system-user-verbiage]": "Use 'system user' verbiage only for operating system system-level user accounts.", # noqa E501
"task-values[hardcode-users-name]": "Hardcode the operating system user's name in the task name.", # noqa E501
"task-values[append-distro]": "Append distribution specificness to tasks where appropriate.", # noqa E501
Expand Down Expand Up @@ -122,6 +127,20 @@ def matchtask(
)
)

if task.name:
_id = f"{self.id}[name-word-misspelled]"
for unknown_word in spell_checker.unknown(
[word for word in spell_checker.split_words(task.name)]
):
errors.append(
self.create_matcherror(
message=self._ids[_id].format(word=unknown_word),
filename=file,
lineno=task[LINE_NUMBER_KEY],
tag=_id,
)
)

if task.action == "ansible.builtin.user" and task.name:
if (
"system user" in task.name
Expand Down
29 changes: 29 additions & 0 deletions scripts/gendict.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/usr/bin/env python3
"""Creates the Ansible tasks' name dictionary."""

import sys
from pathlib import Path

from ansiblelint.config import Options
from ansiblelint.rules import RulesCollection
from ansiblelint.runner import Runner
from ansiblelint.utils import get_lintables, task_in_list
from spellchecker import SpellChecker # type: ignore # spellchecker stubs don't exist

spell_checker, unknown_words = SpellChecker(), set()
for lintable in Runner(
*get_lintables(Options()), rules=RulesCollection([Path("./rules")])
).lintables:
if lintable.kind in ["handlers", "tasks", "playbook"]:
for task in task_in_list(lintable.data, lintable, lintable.kind):
if task.name:
for unknown_word in spell_checker.unknown(
spell_checker.split_words(task.name)
):
unknown_words.add(unknown_word)

with open(Path("./docs/dictionary.txt"), "w") as file:
for unknown_word in sorted(unknown_words):
file.write(f"{unknown_word}\n")

sys.exit(0)

0 comments on commit 2d917ca

Please sign in to comment.