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

Check that the linters exist before using them #32

Merged
merged 3 commits into from
Sep 20, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 41 additions & 11 deletions vcs-diff-lint
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ def file_type(filename):


class _Linter:
name = "unknown"
filetype = None
path_filters = None
linter_tags: List[str] = []
Expand All @@ -79,6 +80,11 @@ class _Linter:
""" if the paths in linter output need adjustments """
return old, new

@classmethod
def is_ready(cls):
""" Return True if the linter is available on host and working """
return True

def _sed_filter(self):
if not self.renames:
return None
Expand Down Expand Up @@ -116,12 +122,13 @@ class _Linter:
os.chdir(abs_projectdir)
sha1_cmd = ['git', 'rev-parse', '--short', 'HEAD']
sha1 = check_output(sha1_cmd).decode("utf-8").strip()
log.info("linting in %s - commit %s", abs_projectdir, sha1)
log.info("%s is linting in %s - commit %s", self.name,
abs_projectdir, sha1)
files = [f.filename for f in files if self.is_compatible(f)]
if not files and not self.full_project_scan:
return
linter_cmd, linter_env = self.command(projectdir, files)
log.debug("Running linter command: %s", linter_cmd)
log.debug("%s command: %s", self.name, linter_cmd)
env = os.environ.copy()
env.update(linter_env)
sed_cmd = self._sed_filter()
Expand All @@ -141,6 +148,7 @@ class PylintLinter(_Linter):
"""
Generate pyilnt error output that is compatible with 'csdiff'.
"""
name = "Pylint"
linter_tags = [
"pylint",
"python",
Expand All @@ -149,6 +157,10 @@ class PylintLinter(_Linter):
def is_compatible(self, file):
return file.type == 'python'

@classmethod
def is_ready(cls):
return os.path.exists("/usr/bin/pylint")

def command(self, projectdir, filenames):
abs_pylintrc = os.path.join(self.gitroot, projectdir, 'pylintrc')
pylintrc = os.path.realpath(abs_pylintrc)
Expand All @@ -163,6 +175,7 @@ class MypyLinter(_Linter):
"""
Generate Mypy error output compatible with 'csdiff'.
"""
name = "Mypy"
linter_tags = [
"mypy",
"python",
Expand All @@ -171,6 +184,10 @@ class MypyLinter(_Linter):
def is_compatible(self, file):
return file.type == 'python'

@classmethod
def is_ready(cls):
return os.path.exists("/usr/bin/mypy")

def command(self, projectdir, filenames):
cmd = [CSDIFF_MYPY] + filenames
return cmd, {}
Expand All @@ -180,12 +197,17 @@ class RuffLinter(_Linter):
"""
Generate Ruff error output compatible with 'csdiff'.
"""
name = "Ruff"
linter_tags = [
"ruff",
"python",
]
full_project_scan = True

@classmethod
def is_ready(cls):
return os.path.exists("/usr/bin/ruff")

def is_compatible(self, file):
return file.type == 'python'

Expand Down Expand Up @@ -292,12 +314,7 @@ class _Worker: # pylint: disable=too-few-public-methods
return
path = os.path.normpath(os.path.join(path, '..'))

def _run_linters(self, old_report_fd, new_report_fd):
# pylint: disable=too-many-locals
lookup = get_rename_map(self.options, self.projectsubdir)
if not lookup:
return

def _prepare_linted_dirs(self):
# prepare the old checkout
old_gitroot = os.path.join(self.workdir, 'old_dir')
new_gitroot = os.path.join(self.workdir, 'new_dir')
Expand All @@ -311,18 +328,28 @@ class _Worker: # pylint: disable=too-few-public-methods
finally:
os.chdir(ret_cwd)

# prepare the new checkout
try:
os.chdir(new_gitroot)
with Popen(["git", "-C", origin_from, "diff", "--cached"],
stdout=PIPE) as diff:
check_call(["git", "apply", "--allow-empty", "--index", "-"],
stdin=diff.stdout)
stdin=diff.stdout)
with Popen(["git", "-C", origin_from, "diff"],
stdout=PIPE) as diff:
check_call(["git", "apply", "--allow-empty", "-"],
stdin=diff.stdout)
stdin=diff.stdout)
finally:
os.chdir(ret_cwd)
return old_gitroot, new_gitroot

def _run_linters(self, old_report_fd, new_report_fd):
# pylint: disable=too-many-locals
lookup = get_rename_map(self.options, self.projectsubdir)
if not lookup:
return

old_gitroot, new_gitroot = self._prepare_linted_dirs()

def add_file(gitroot, files, filename):
if not filename:
Expand Down Expand Up @@ -357,10 +384,13 @@ class _Worker: # pylint: disable=too-few-public-methods
for pattern in self.options.linter_tags:
for tag in linter.linter_tags:
if fnmatch.fnmatch(tag, pattern):
selected_linters.add(linter)
found = True
break
if found:
if linter.is_ready():
selected_linters.add(linter)
else:
log.info("Not adding %s, not ready", linter.name)
break

for linterClass in selected_linters:
Expand Down