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

v0.1.6 #16

Merged
merged 12 commits into from
Dec 9, 2023
6 changes: 3 additions & 3 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Release Drafter
name: Release & PyPI Publish
on:
workflow_dispatch:
push:
Expand Down Expand Up @@ -55,8 +55,8 @@ jobs:
with:
name: release-dists
path: dist/
test-pypi-publish: # https://github.com/pypa/gh-action-pypi-publish
name: Upload release to TestPyPI
pypi-publish: # https://github.com/pypa/gh-action-pypi-publish
name: Upload release to PyPI
runs-on: ubuntu-latest
needs:
- release-build
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release_test.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
name: Release Drafter (autolabeler & check release tag)
name: TestPyPI Publish
on:
workflow_dispatch:
push:
Expand Down
94 changes: 56 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,48 +15,60 @@ Strict naming rule is useful to avoid name collision and to search defined posit

## Rules

### var_name_prefix

- [x] `<role_name>_role__` , `<task_name>_tasks__`

- | prefix | Variables defined in |
| :-------------------- | :------------------------- |
| `<role_name>_role__` | `roles/<role_name>/tasks/` |
| `<role_name>_tasks__` | `<not_roles>/**/tasks/` |

- In ansible-lint, `var-naming[no-role-prefix]` require to use `<role_name>_` as prefix. But it is not enough to avoid name collision or search defined position. So, I add `_role__` or `_tasks__` to the prefix.

- [ ] `var__`, `const__`
- | prefix | description |
| :-------- | :-------------------------------------------------------------------------------------- |
| `var__` | Variables dynamically defined by `ansible.builtin.set_fact` or `register` |
| `const__` | Variables statistically defined in such like inventory's vars, group_vars and host_vars |
- [ ] prefix precedence

- descending order
- role or task prefix
- var or const prefix
- examples

| var | description |
| :------------------------ | :-------------------------------------------------------------------------------------------------------- |
| `var__fizz` | defined in playbook by `ansible.builtin.set_fact` or `register` |
| `some_role__var__fizz` | defined in `roles/<role_name>/tasks` by `ansible.builtin.set_fact` or `register` |
| `some_role__arg__fizz` | defined by `ansible.builtin.include_role`'s `vars` key and shouldn't changed in `roles/<role_name>/tasks` |
| `some_role__const__fizz` | defined only in `roles/<role_name>/vars/`. |
| `some_tasks__var__fizz` | defined in `tasks` by `ansible.builtin.set_fact` or `register` |
| `some_tasks__const__fizz` | defined by `ansible.builtin.include_role`'s vars key and not changed in `tasks` |
## var_name_prefix

### `<role_name>_role__` , `<task_name>_tasks__`

- | prefix | Variables defined in |
| :-------------------- | :------------------------- |
| `<role_name>_role__` | `roles/<role_name>/tasks/` |
| `<role_name>_tasks__` | `<not_roles>/**/tasks/` |

- In ansible-lint, `var-naming[no-role-prefix]` require to use `<role_name>_` as prefix. But it is not enough to avoid name collision or search defined position. So, I add `_role__` or `_tasks__` to the prefix.

### `var__`, `const__`

- `var__` prefix
- Variables dynamically defined by `ansible.builtin.set_fact` or `register`
- `const__` prefix
- Variables dynamically defined by `ansible.builtin.set_fact` or `register`
- Variables statically defined in such like inventory's vars, group_vars, host_vars and etc.

### Vars in `tasks/<name>.yml` or `roles/<name>/tasks/main.yml`

- `<name>_role__var__` prefix
- These variables are dynamically defined in `roles/<name>/tasks/main.yml`.
- `<name>_role__const__` prefix
- These variables are defined in `roles/<name>/vars/main.yml` and shouldn't be changed dynamically.
- `some_role__arg__` prefix
- These variables are defined by `ansible.builtin.include_role`'s `vars` key and shouldn't be changed dynamically.
- `some_role__args`

- These variables are defined by `ansible.builtin.include_role`'s `vars` key and shouldn't be changed dynamically.
- This is useful when you want to send vars as dict.

```yaml
tasks:
- name: Some task
ansible.builtin.include_role:
name: <role_name>
vars:
some_role__const__one: value1
some_role__const__two: value2
- name: Sample
ansible.builtin.include_role:
name: some_role
vars:
some_role__args:
key1: value1
key2: value2
```
### examples
```yaml
tasks:
- name: Some task
ansible.builtin.include_role:
name: <role_name>
vars:
some_role__const__one: value1
some_role__const__two: value2
```
## Others
### Double underscores?
Expand All @@ -68,3 +80,9 @@ Strict naming rule is useful to avoid name collision and to search defined posit
- `some_role__const__app_config__name`
- `some_role__const__app_config__token`
- `some_role__const__app_config__version`

## Docs

### Articles

- [ansible-lint のカスタムルールを利用して Ansible 内での変数命名規則を縛ってみた話](https://zenn.dev/pollenjp/articles/2023-12-03-ansible-lint-custom-strict-naming)
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "ansible-lint-custom-strict-naming"
version = "0.1.5"
version = "0.1.6"
description = "Add your description here"
authors = [{ name = "pollenjp", email = "polleninjp@gmail.com" }]
dependencies = ["ansible-lint>=6.21.1"]
Expand Down
30 changes: 26 additions & 4 deletions src/rules/var_name_prefix.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,25 @@ def match_task_for_include_role_module(self, task: Task, file: Lintable | None =

# check vars
prefix = f"{role_name}_role__arg__"
completely_matched_name = f"{role_name}_role__args"
def validate_key_name(key: str):
"""keyが条件を満たすか"""
if is_registered_key(key):
return True
if key.startswith(f"{prefix}"):
return True
if key == completely_matched_name:
return True
return False

return [
self.create_matcherror(
message=f"Variables in 'include_role' should have a '{prefix}' prefix.",
message=f"Variable name in 'include_role' should have a '{prefix}' prefix or '{completely_matched_name}' as dict.",
lineno=task_vars.get(LINE_NUMBER_KEY),
filename=file,
)
for key in task_vars.keys()
if not is_registered_key(key) and not key.startswith(f"{prefix}")
if not validate_key_name(key)
]

def match_task_for_include_tasks_module(self, task: Task, file: Lintable | None = None) -> bool | list[MatchError]:
Expand All @@ -108,12 +119,23 @@ def match_task_for_include_tasks_module(self, task: Task, file: Lintable | None

# check vars
prefix = f"{role_name}_tasks__arg__"
completely_matched_name = f"{role_name}_tasks__args"
def validate_key_name(key: str):
"""keyが条件を満たすか"""
if is_registered_key(key):
return True
if key.startswith(f"{prefix}"):
return True
if key == completely_matched_name:
return True
return False

return [
self.create_matcherror(
message=f"Variables in 'include_tasks' should have a '{prefix}' prefix.",
message=f"Variable name in 'include_tasks' should have a '{prefix}' prefix or '{completely_matched_name}' as dict.",
lineno=task_vars.get(LINE_NUMBER_KEY),
filename=file,
)
for key in task_vars.keys()
if not is_registered_key(key) and not key.startswith(f"{prefix}")
if not validate_key_name(key)
]
Loading