Skip to content

Commit c01bb3a

Browse files
authored
Merge pull request #186 from sommersoft/run_pylint
Add Validator To Run Pylint On Libraries
2 parents b17b8fd + 4b87cac commit c01bb3a

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

adabot/lib/circuitpython_library_validators.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,18 @@
2020
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2121
# THE SOFTWARE.
2222
import datetime
23+
import json
24+
import pathlib
2325
import re
26+
from tempfile import TemporaryDirectory
27+
28+
from pylint import epylint as linter
2429

2530
import requests
2631

32+
import sh
33+
from sh.contrib import git
34+
2735
from adabot import github_requests as github
2836
from adabot import pypi_requests as pypi
2937
from adabot.lib import common_funcs
@@ -99,6 +107,7 @@
99107
ERROR_NOT_ON_PYPI = "Not listed on PyPi for CPython use"
100108
ERROR_PYLINT_VERSION_NOT_FIXED = "PyLint version not fixed"
101109
ERROR_PYLINT_VERSION_NOT_LATEST = "PyLint version not latest"
110+
ERROR_PYLINT_FAILED_LINTING = "Failed PyLint checks"
102111
ERROR_NEW_REPO_IN_WORK = "New repo(s) currently in work, and unreleased"
103112

104113
# Temp category for GitHub Actions migration.
@@ -1041,3 +1050,51 @@ def validate_labels(self, repo):
10411050
errors.append(ERROR_MISSING_STANDARD_LABELS)
10421051

10431052
return errors
1053+
1054+
def validate_passes_linting(self, repo):
1055+
""" Clones the repo and runs pylint on the Python files"""
1056+
if not repo["name"].startswith("Adafruit_CircuitPython"):
1057+
return []
1058+
1059+
ignored_py_files = ["setup.py", "conf.py"]
1060+
1061+
with TemporaryDirectory() as tempdir:
1062+
repo_dir = pathlib.Path(tempdir) / repo["name"]
1063+
try:
1064+
git.clone("--depth=1", repo["git_url"], repo_dir)
1065+
except sh.ErrorReturnCode as err:
1066+
self.output_file_data.append(
1067+
f"Failed to clone repo for linting: {repo['full_name']}\n {err.stderr}"
1068+
)
1069+
return [ERROR_OUTPUT_HANDLER]
1070+
1071+
for file in repo_dir.rglob("*.py"):
1072+
if not file.name in ignored_py_files and not str(file.parent).endswith("examples"):
1073+
py_run_args = f"{file} --output-format=json"
1074+
if (repo_dir / '.pylintrc').exists():
1075+
py_run_args += (
1076+
f" --rcfile={str(repo_dir / '.pylintrc')}"
1077+
)
1078+
1079+
pylint_stdout, pylint_stderr = linter.py_run(
1080+
py_run_args,
1081+
return_std=True
1082+
)
1083+
1084+
if pylint_stderr.getvalue():
1085+
self.output_file_data.append(
1086+
f"PyLint error ({repo['name']}): '{pylint_stderr.getvalue()}'"
1087+
)
1088+
return [ERROR_OUTPUT_HANDLER]
1089+
1090+
try:
1091+
pylint_result = json.loads(pylint_stdout.getvalue())
1092+
except json.JSONDecodeError as json_err:
1093+
self.output_file_data.append(
1094+
f"PyLint output JSONDecodeError: {json_err.msg}"
1095+
)
1096+
return [ERROR_OUTPUT_HANDLER]
1097+
1098+
if pylint_result:
1099+
return [ERROR_PYLINT_FAILED_LINTING]
1100+
return []

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ certifi==2017.11.5
22
chardet==3.0.4
33
idna==2.6
44
packaging==20.3
5+
pylint
56
redis==2.10.6
67
requests==2.20.0
78
sh==1.12.14

0 commit comments

Comments
 (0)