180 lines
5.4 KiB
Python
Executable File
180 lines
5.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import os
|
|
import sys
|
|
import subprocess
|
|
import argparse
|
|
from pathlib import Path
|
|
|
|
# Import helper functions
|
|
sys.path.append(os.path.join(os.path.dirname(os.path.dirname(__file__))))
|
|
from helpers.functions import printfe, command_exists
|
|
|
|
DOTFILES_ROOT = os.path.expanduser("~/.dotfiles")
|
|
|
|
|
|
def lint_ansible(fix=False):
|
|
"""Run ansible-lint on Ansible files"""
|
|
ansible_dir = os.path.join(DOTFILES_ROOT, "config/ansible")
|
|
|
|
if not os.path.isdir(ansible_dir):
|
|
printfe("yellow", "No ansible directory found at config/ansible")
|
|
return 0
|
|
|
|
# Find all YAML files in the ansible directory
|
|
yaml_files = []
|
|
for ext in [".yml", ".yaml"]:
|
|
yaml_files.extend(list(Path(ansible_dir).glob(f"**/*{ext}")))
|
|
|
|
if not yaml_files:
|
|
printfe("yellow", "No Ansible files found in config/ansible to lint")
|
|
return 0
|
|
|
|
if not command_exists("ansible-lint"):
|
|
printfe(
|
|
"red",
|
|
"ansible-lint is not installed. Please install it with pip or your package manager.",
|
|
)
|
|
return 1
|
|
|
|
printfe("blue", f"Running ansible-lint{' with auto-fix' if fix else ''}...")
|
|
files_to_lint = [str(f) for f in yaml_files]
|
|
|
|
command = ["ansible-lint"]
|
|
if fix:
|
|
command.append("--fix")
|
|
command.extend(files_to_lint)
|
|
|
|
result = subprocess.run(command, check=False)
|
|
return result.returncode
|
|
|
|
|
|
def lint_nix():
|
|
"""Run nixfmt on Nix files"""
|
|
nix_files = list(Path(DOTFILES_ROOT).glob("**/*.nix"))
|
|
|
|
if not nix_files:
|
|
printfe("yellow", "No Nix files found to lint")
|
|
return 0
|
|
|
|
if not command_exists("nixfmt"):
|
|
printfe(
|
|
"red",
|
|
"nixfmt is not installed. Please install it with nix-env or your package manager.",
|
|
)
|
|
return 1
|
|
|
|
printfe("blue", "Running nixfmt...")
|
|
exit_code = 0
|
|
for nix_file in nix_files:
|
|
printfe("cyan", f"Formatting {nix_file}")
|
|
result = subprocess.run(["nixfmt", str(nix_file)], check=False)
|
|
if result.returncode != 0:
|
|
exit_code = 1
|
|
|
|
return exit_code
|
|
|
|
|
|
def lint_python(fix=False):
|
|
"""Run pylint and black on Python files"""
|
|
python_files = list(Path(DOTFILES_ROOT).glob("**/*.py"))
|
|
|
|
if not python_files:
|
|
printfe("yellow", "No Python files found to lint")
|
|
return 0
|
|
|
|
exit_code = 0
|
|
|
|
# Check for pylint
|
|
if command_exists("pylint"):
|
|
printfe("blue", "Running pylint...")
|
|
files_to_lint = [str(f) for f in python_files]
|
|
result = subprocess.run(["pylint"] + files_to_lint, check=False)
|
|
if result.returncode != 0:
|
|
exit_code = 1
|
|
else:
|
|
printfe("yellow", "pylint is not installed. Skipping Python linting.")
|
|
|
|
# Check for black
|
|
if command_exists("black"):
|
|
printfe(
|
|
"blue", f"Running black{'--check' if not fix else ''} on Python files..."
|
|
)
|
|
black_args = ["black"]
|
|
if not fix:
|
|
black_args.append("--check")
|
|
black_args.extend([str(f) for f in python_files])
|
|
|
|
result = subprocess.run(black_args, check=False)
|
|
if result.returncode != 0:
|
|
exit_code = 1
|
|
else:
|
|
printfe("yellow", "black is not installed. Skipping Python formatting.")
|
|
|
|
if not command_exists("pylint") and not command_exists("black"):
|
|
printfe(
|
|
"red",
|
|
"Neither pylint nor black is installed. Please run: `pip install pylint black`",
|
|
)
|
|
return 1
|
|
|
|
return exit_code
|
|
|
|
|
|
def main():
|
|
"""
|
|
Entry point for running linters on dotfiles.
|
|
|
|
This function parses command-line arguments to determine which linters to run
|
|
and whether to apply auto-fixes. It supports running linters for Ansible, Nix,
|
|
and Python files. If no specific linter is specified, all linters are executed.
|
|
|
|
Command-line arguments:
|
|
--ansible: Run only ansible-lint.
|
|
--nix: Run only nixfmt.
|
|
--python: Run only Python linters (pylint, black).
|
|
--fix: Auto-fix issues where possible.
|
|
|
|
Returns:
|
|
int: Exit code indicating the success or failure of the linting process.
|
|
A non-zero value indicates that one or more linters reported issues.
|
|
"""
|
|
parser = argparse.ArgumentParser(description="Run linters on dotfiles")
|
|
parser.add_argument("--ansible", action="store_true", help="Run only ansible-lint")
|
|
parser.add_argument("--nix", action="store_true", help="Run only nixfmt")
|
|
parser.add_argument(
|
|
"--python", action="store_true", help="Run only Python linters (pylint, black)"
|
|
)
|
|
parser.add_argument(
|
|
"--fix", action="store_true", help="Auto-fix issues where possible"
|
|
)
|
|
args = parser.parse_args()
|
|
|
|
# If no specific linter is specified, run all
|
|
run_ansible = args.ansible or not (args.ansible or args.nix or args.python)
|
|
run_nix = args.nix or not (args.ansible or args.nix or args.python)
|
|
run_python = args.python or not (args.ansible or args.nix or args.python)
|
|
|
|
exit_code = 0
|
|
|
|
if run_ansible:
|
|
ansible_result = lint_ansible(fix=args.fix)
|
|
if ansible_result != 0:
|
|
exit_code = ansible_result
|
|
|
|
if run_nix:
|
|
nix_result = lint_nix()
|
|
if nix_result != 0:
|
|
exit_code = nix_result
|
|
|
|
if run_python:
|
|
python_result = lint_python(fix=args.fix)
|
|
if python_result != 0:
|
|
exit_code = python_result
|
|
|
|
return exit_code
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|