Source code for _repobee.ext.pylint

"""Plugin that runs pylint on all files in a repo.

.. important::

    Requires ``pylint`` to be installed and accessible by the script!

This plugin is mostly for demonstrational purposes, showing how to make the
most barebones of plugins using only a single function. It finds all ``.py``
files in a repo, and runs pylint on them, storing the results in files named
``<filename>.lint`` for any ``.py`` file named ``filename``.

.. module:: pylint
    :synopsis: Plugin that runs pylint on all .py files in a repo.

.. moduleauthor:: Simon Larsén
"""

import subprocess
import pathlib
from typing import Tuple, Union, Iterable


import repobee_plug as plug


PLUGIN_DESCRIPTION = "Runs pylint on student repos after cloning"
SECTION = "pylint"


[docs]@plug.repobee_hook def post_clone(repo: plug.StudentRepo, api: plug.PlatformAPI): """Run pylint on all Python files in a repo. Args: path: Path to the repo. api: A platform API class instance. Returns: a plug.Result specifying the outcome. """ path = repo.path python_files = list(path.rglob("*.py")) if not python_files: msg = "no .py files found" return plug.Result(SECTION, plug.Status.WARNING, msg) status, msg = _pylint(python_files) return plug.Result(name=SECTION, status=status, msg=msg)
def _pylint(python_files: Iterable[Union[pathlib.Path]]) -> Tuple[str, str]: """Run ``pylint`` on all of the specified files. Args: python_files: paths to ``.py`` files. Returns: (status, msg), where status is e.g. :py:const:`plugin.ERROR` and the message describes the outcome in plain text. """ linted_files = [] for py_file in python_files: plug.echo("Running pylint on {!s}".format(py_file)) command = "pylint {!s}".format(py_file).split() proc = subprocess.run( command, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) outfile = pathlib.Path( "{}/{}.lint".format(py_file.parent, py_file.name) ) outfile.touch() outfile.write_bytes(proc.stdout) linted_files.append(str(py_file)) msg = "linted files: {}".format(", ".join(linted_files)) return plug.Result(name=SECTION, status=plug.Status.SUCCESS, msg=msg)