Skip to content

Commit

Permalink
chore: linter improvements (#25)
Browse files Browse the repository at this point in the history
* fix pylint issues
* pymarkdownlnt instead of doc8
* usage of ruff instead of flake8 and isort
  • Loading branch information
hille721 authored May 21, 2023
1 parent bd79e56 commit d706f8e
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 99 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/tox.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Tox

on:
push:
branches: ["*"]
branches: ["main"]
pull_request:
branches: ["main"]

Expand Down
30 changes: 17 additions & 13 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,30 +30,34 @@ repos:
- id: black
exclude: ".ci/hack"

- repo: https://github.com/pycqa/flake8.git
rev: 6.0.0
- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: 'v0.0.269'
hooks:
- id: flake8
- id: ruff
args:
- --fix
- --exit-non-zero-on-fix

- repo: https://github.com/pycqa/doc8
rev: v1.1.1
- repo: https://github.com/jackdewinter/pymarkdown
rev: v0.9.11
hooks:
- id: doc8
- id: pymarkdown
args:
- -c
- .pymarkdown.json
- scan
exclude: CHANGELOG.md # is autogenerated

- repo: https://github.com/pycqa/pylint
rev: v3.0.0a6
hooks:
- id: pylint
pass_filenames: false
entry: pylint lib tests
args:
- --output-format=colorized
additional_dependencies:
- .
- ansible-core>=2.11.0
- rich
- pytest
stages: [manual] # not working if only single files are passed

- repo: https://github.com/pycqa/isort
rev: 5.12.0
hooks:
- id: isort
name: isort
13 changes: 13 additions & 0 deletions .pymarkdown.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"plugins": {
"line-length": {
"enabled": true,
"line_length": 120,
"heading_line_length": 80,
"code_block_line_length": 80
},
"ul-indent": {
"indent": 4
}
}
}
20 changes: 14 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
[![pre-commit][pre-commit-badge]][pre-commit-link]

The Ansible inventory provides a very powerful framework to declare variables in a hierarchical manner.
There a lof of different places where a variable can be defined (inventory, host_vars, groups_vars, ...) and Ansible will merge them in a specific order ([variable precedence](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html#understanding-variable-precedence)).
There a lof of different places where a variable can be defined (inventory, host_vars, groups_vars, ...)
and Ansible will merge them in a specific order
([variable precedence](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_variables.html#understanding-variable-precedence)).

`ansible-variables` will help to keep track of your host context variables:

Expand All @@ -27,7 +29,8 @@ pip install ansible-variables

## Usage

The command line usage is similar to the official Ansible CLI tools, especially like ansible-inventory, thus to see all possible commands and options run
The command line usage is similar to the official Ansible CLI tools, especially like ansible-inventory,
thus to see all possible commands and options run

```plain
ansible-variables --help
Expand Down Expand Up @@ -73,15 +76,20 @@ ansible-variables mywebserver -i /path/to/inventory
## Implementation

This tool is tightly coupled to the Ansible library (`ansible-core`) and simple reuses what is already there.
The whole structure and implementation was inspired and oriented by the implementation of [`ansible-inventory`](https://github.com/ansible/ansible/blob/devel/lib/ansible/cli/inventory.py).
The whole structure and implementation was inspired and oriented by the implementation of
[`ansible-inventory`](https://github.com/ansible/ansible/blob/devel/lib/ansible/cli/inventory.py).

To get the source and the inventory files in which Ansible will look for a variable, we are using a [debug flag](https://github.com/ansible/ansible/blob/devel/lib/ansible/vars/manager.py#L187) in Ansible's `get_vars` method.
To get the source and the inventory files in which Ansible will look for a variable,
we are using a [debug flag](https://github.com/ansible/ansible/blob/devel/lib/ansible/vars/manager.py#L187)
in Ansible's `get_vars` method.

As as result, the output of `ansible-variables` can be fully trusted as it uses the same methods as Ansible to get the variable precedence.
As as result, the output of `ansible-variables` can be fully trusted
as it uses the same methods as Ansible to get the variable precedence.

## Limitations

* as written in the description, this tool only shows host context variables and does not know anything about playbook or role variables or command line options.
* as written in the description, this tool only shows host context variables and
does not know anything about playbook or role variables or command line options.

## Credits

Expand Down
137 changes: 68 additions & 69 deletions lib/ansible_variables/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,82 +23,81 @@ class CLI(ACLI):
"""

@classmethod
def cli_executor(cls, args=None):
def cli_executor(cls, args=None): # pylint: disable=too-many-branches,too-many-statements
# no change for ansible-core >= 2.13
if hasattr(super(), "cli_executor"):
return super().cli_executor(args=args)

# backporting code from https://github.com/ansible/ansible/blob/v2.13.9/lib/ansible/cli/__init__.py#L574
else:
if args is None:
args = sys.argv
if args is None:
args = sys.argv

try:
display.debug("starting run")

ansible_dir = Path("~/.ansible").expanduser()
try:
ansible_dir.mkdir(mode=0o700)
except OSError as exc:
if exc.errno != errno.EEXIST:
display.warning(
"Failed to create the directory '%s': %s"
% (ansible_dir, to_text(exc, errors="surrogate_or_replace"))
)
else:
display.debug("Created the '%s' directory" % ansible_dir)
try:
display.debug("starting run")

try:
args = [to_text(a, errors="surrogate_or_strict") for a in args]
except UnicodeError:
display.error(
"""Command line args are not in utf-8, unable to continue.
Ansible currently only understands utf-8"""
ansible_dir = Path("~/.ansible").expanduser()
try:
ansible_dir.mkdir(mode=0o700)
except OSError as exc:
if exc.errno != errno.EEXIST:
display.warning(
"Failed to create the directory '%s': %s"
% (ansible_dir, to_text(exc, errors="surrogate_or_replace"))
)
display.display("The full traceback was:\n\n%s" % to_text(traceback.format_exc()))
exit_code = 6
else:
cli = cls(args)
exit_code = cli.run()
else:
display.debug("Created the '%s' directory" % ansible_dir)

try:
args = [to_text(a, errors="surrogate_or_strict") for a in args]
except UnicodeError:
display.error(
"""Command line args are not in utf-8, unable to continue.
Ansible currently only understands utf-8"""
)
display.display("The full traceback was:\n\n%s" % to_text(traceback.format_exc()))
exit_code = 6
else:
cli = cls(args)
exit_code = cli.run()

except AnsibleOptionsError as exc:
cli.parser.print_help()
display.error(to_text(exc), wrap_text=False)
exit_code = 5
except AnsibleParserError as exc:
display.error(to_text(exc), wrap_text=False)
exit_code = 4
# TQM takes care of these, but leaving comment to reserve the exit codes
# except AnsibleHostUnreachable as e:
# display.error(str(e))
# exit_code = 3
# except AnsibleHostFailed as e:
# display.error(str(e))
# exit_code = 2
except AnsibleError as e:
display.error(to_text(e), wrap_text=False)
exit_code = 1
except KeyboardInterrupt:
display.error("User interrupted execution")
exit_code = 99
except Exception as e:
if C.DEFAULT_DEBUG:
# Show raw stacktraces in debug mode, It also allow pdb to
# enter post mortem mode.
raise
have_cli_options = bool(context.CLIARGS)
display.error("Unexpected Exception, this is probably a bug: %s" % to_text(e), wrap_text=False)
if not have_cli_options or have_cli_options and context.CLIARGS["verbosity"] > 2:
log_only = False
if hasattr(e, "orig_exc"):
display.vvv("\nexception type: %s" % to_text(type(e.orig_exc)))
why = to_text(e.orig_exc)
if to_text(e) != why:
display.vvv("\noriginal msg: %s" % why)
else:
display.display("to see the full traceback, use -vvv")
log_only = True
display.display("the full traceback was:\n\n%s" % to_text(traceback.format_exc()), log_only=log_only)
exit_code = 250
except AnsibleOptionsError as exc:
cli.parser.print_help()
display.error(to_text(exc), wrap_text=False)
exit_code = 5
except AnsibleParserError as exc:
display.error(to_text(exc), wrap_text=False)
exit_code = 4
# TQM takes care of these, but leaving comment to reserve the exit codes
# except AnsibleHostUnreachable as exc:
# display.error(str(exc))
# exit_code = 3
# except AnsibleHostFailed as exc:
# display.error(str(exc))
# exit_code = 2
except AnsibleError as exc:
display.error(to_text(exc), wrap_text=False)
exit_code = 1
except KeyboardInterrupt:
display.error("User interrupted execution")
exit_code = 99
except Exception as exc: # pylint: disable=broad-exception-caught
if C.DEFAULT_DEBUG:
# Show raw stacktraces in debug mode, It also allow pdb to
# enter post mortem mode.
raise
have_cli_options = bool(context.CLIARGS)
display.error("Unexpected Exception, this is probably a bug: %s" % to_text(exc), wrap_text=False)
if not have_cli_options or have_cli_options and context.CLIARGS["verbosity"] > 2:
log_only = False
if hasattr(exc, "orig_exc"):
display.vvv("\nexception type: %s" % to_text(type(exc.orig_exc)))
why = to_text(exc.orig_exc)
if to_text(exc) != why:
display.vvv("\noriginal msg: %s" % why)
else:
display.display("to see the full traceback, use -vvv")
log_only = True
display.display("the full traceback was:\n\n%s" % to_text(traceback.format_exc()), log_only=log_only)
exit_code = 250

sys.exit(exit_code)
sys.exit(exit_code)
21 changes: 15 additions & 6 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
# for now only be used for black config
# for now only be used for black and ruff config
# maybe in the future we will use it instead of setup.py / setup.cfg
[tool.black]
line-length = 120

[tool.isort]
profile = "black"
known_first_party = "ansible_variables"
known_third_party = "ansible,pytest,pkg_resources,setuptools,rich"
line_length = 120
[tool.ruff]
line-length = 120
select = [
# Pyflakes
"F",
# Pycodestyle
"E",
"W",
# isort
"I001"
]

[tool.ruff.isort]
known-first-party = ["ansible_variables"]
2 changes: 1 addition & 1 deletion requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
tox
black
pylint
flake8
ruff
pytest
pre-commit
3 changes: 0 additions & 3 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,6 @@ exclude =
console_scripts =
ansible-variables = ansible_variables.cli.variables:main

[flake8]
max-line-length = 120

[pylint.format]
max-line-length = 120

Expand Down

0 comments on commit d706f8e

Please sign in to comment.