Refactored linting process and error handling in commands.

This commit is contained in:
Paul Gauthier 2024-05-20 08:55:49 -07:00
parent deb13c060c
commit 9c28bbc98e
5 changed files with 64 additions and 29 deletions

View file

@ -82,10 +82,19 @@ class Coder:
) )
if not main_model: if not main_model:
main_model = models.Model(models.DEFAULT_MODEL_NAME) if from_coder:
main_model = from_coder.main_model
else:
main_model = models.Model(models.DEFAULT_MODEL_NAME)
if edit_format is None: if edit_format is None:
edit_format = main_model.edit_format if from_coder:
edit_format = from_coder.edit_format
else:
edit_format = main_model.edit_format
if not io and from_coder:
io = from_coder.io
if from_coder: if from_coder:
use_kwargs = dict(from_coder.original_kwargs) # copy orig kwargs use_kwargs = dict(from_coder.original_kwargs) # copy orig kwargs
@ -125,6 +134,9 @@ class Coder:
return res return res
def clone(self, **kwargs):
return Coder.create(from_coder=self, **kwargs)
def get_announcements(self): def get_announcements(self):
lines = [] lines = []
lines.append(f"Aider v{__version__}") lines.append(f"Aider v{__version__}")

View file

@ -153,40 +153,51 @@ class Commands:
commit_message = args.strip() commit_message = args.strip()
self.coder.repo.commit(message=commit_message) self.coder.repo.commit(message=commit_message)
def cmd_lint(self, args): def cmd_lint(self, args="", fnames=None):
"Commit, run the linter on all dirty files, fix problems and commit again" "Commit, run the linter on all dirty files, fix problems and commit again"
if not self.coder.repo: if not self.coder.repo:
self.io.tool_error("No git repository found.") self.io.tool_error("No git repository found.")
return return
if not self.coder.repo.is_dirty(): if not fnames:
self.io.tool_error("No more changes to commit.") fnames = self.coder.repo.get_dirty_files()
return
fnames = self.coder.repo.get_dirty_files() if not fnames:
linted = False self.io.tool_error("No dirty files to lint.")
return
lint_coder = None
for fname in fnames: for fname in fnames:
try: try:
errors = self.coder.linter.lint(fname, cmd=args) errors = self.coder.linter.lint(fname, cmd=args)
linted = True
except FileNotFoundError as err: except FileNotFoundError as err:
self.io.tool_error(f"Unable to lint {fname}") self.io.tool_error(f"Unable to lint {fname}")
self.io.tool_error(str(err)) self.io.tool_error(str(err))
continue continue
if errors: if not errors:
# Commit everything before we start fixing lint errors continue
if self.coder.repo.is_dirty():
self.cmd_commit("")
self.io.tool_error(errors) # Commit everything before we start fixing lint errors
if self.coder.repo.is_dirty():
self.cmd_commit("")
abs_file_path = self.coder.abs_root_path(fname) self.io.tool_error(errors)
self.coder.abs_fnames.add(abs_file_path)
self.coder.run(errors)
if linted and self.coder.repo.is_dirty(): if not lint_coder:
lint_coder = self.coder.clone(
# Clear the chat history, fnames
cur_messages=[],
done_messages=[],
fnames=None,
)
lint_coder.add_rel_fname(fname)
lint_coder.run(errors)
lint_coder.abs_fnames = set()
if lint_coder and self.coder.repo.is_dirty():
self.cmd_commit("") self.cmd_commit("")
def cmd_clear(self, args): def cmd_clear(self, args):

View file

@ -325,7 +325,7 @@ class InputOutput:
return res return res
def tool_error(self, message, strip=True): def tool_error(self, message="", strip=True):
self.num_error_outputs += 1 self.num_error_outputs += 1
if message.strip(): if message.strip():

View file

@ -13,7 +13,6 @@ from tree_sitter_languages import get_parser # noqa: E402
warnings.simplefilter("ignore", category=FutureWarning) warnings.simplefilter("ignore", category=FutureWarning)
class Linter: class Linter:
def __init__(self, encoding="utf-8", root=None): def __init__(self, encoding="utf-8", root=None):
self.encoding = encoding self.encoding = encoding
@ -22,9 +21,14 @@ class Linter:
self.languages = dict( self.languages = dict(
python=self.py_lint, python=self.py_lint,
) )
self.all_lint_cmd = None
def set_linter(self, lang, cmd): def set_linter(self, lang, cmd):
self.languages[lang] = cmd if lang:
self.languages[lang] = cmd
return
self.all_lint_cmd = cmd
def get_rel_fname(self, fname): def get_rel_fname(self, fname):
if self.root: if self.root:
@ -66,7 +70,10 @@ class Linter:
lang = filename_to_lang(fname) lang = filename_to_lang(fname)
if not lang: if not lang:
return return
cmd = self.languages.get(lang) if self.all_lint_cmd:
cmd = self.all_lint_cmd
else:
cmd = self.languages.get(lang)
if callable(cmd): if callable(cmd):
linkres = cmd(fname, rel_fname, code) linkres = cmd(fname, rel_fname, code)

View file

@ -1,5 +1,6 @@
import configparser import configparser
import os import os
import re
import sys import sys
from pathlib import Path from pathlib import Path
@ -181,14 +182,18 @@ def parse_lint_cmds(lint_cmds, io):
err = False err = False
res = dict() res = dict()
for lint_cmd in lint_cmds: for lint_cmd in lint_cmds:
pieces = lint_cmd.split(":") if re.match(r"^[a-z]+:.*", lint_cmd):
lang = pieces[0] pieces = lint_cmd.split(":")
cmd = lint_cmd[len(lang) + 1 :] lang = pieces[0]
cmd = lint_cmd[len(lang) + 1 :]
lang = lang.strip()
else:
lang = None
cmd = lint_cmd
lang = lang.strip()
cmd = cmd.strip() cmd = cmd.strip()
if lang and cmd: if cmd:
res[lang] = cmd res[lang] = cmd
else: else:
io.tool_error(f'Unable to parse --lint-cmd "{lint_cmd}"') io.tool_error(f'Unable to parse --lint-cmd "{lint_cmd}"')
@ -383,11 +388,11 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F
return return
if args.commit: if args.commit:
coder.commands.cmd_commit("") coder.commands.cmd_commit()
return return
if args.lint: if args.lint:
coder.commands.cmd_lint("") coder.commands.cmd_lint(fnames=fnames)
return return
if args.test: if args.test: