From 62c06bb081b9258c0626c0ff77ce312ebe1c2cd1 Mon Sep 17 00:00:00 2001 From: Roberto Leinardi Date: Sat, 26 Feb 2022 13:49:55 +0100 Subject: [PATCH] Show notification when Mypy exits abnormally --- .../pycharm/pylint/checker/ScanFiles.java | 6 +++-- .../pycharm/pylint/plapi/PylintRunner.java | 25 ++++++++++++++++--- .../pycharm/pylint/util/Notifications.java | 8 ++++++ .../pycharm/pylint/PylintBundle.properties | 1 + 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/leinardi/pycharm/pylint/checker/ScanFiles.java b/src/main/java/com/leinardi/pycharm/pylint/checker/ScanFiles.java index 754944b..f224f31 100644 --- a/src/main/java/com/leinardi/pycharm/pylint/checker/ScanFiles.java +++ b/src/main/java/com/leinardi/pycharm/pylint/checker/ScanFiles.java @@ -92,7 +92,8 @@ private Map mapFilesToElements(final List filesT return filePathsToElements; } - private Map> checkFiles(final Set filesToScan) throws InterruptedIOException { + private Map> checkFiles(final Set filesToScan) + throws InterruptedIOException, InterruptedException { final List scannableFiles = new ArrayList<>(); try { scannableFiles.addAll(ScannableFile.createAndValidate(filesToScan, plugin)); @@ -103,7 +104,8 @@ private Map> checkFiles(final Set filesToScan) t } } - private Map> scan(final List filesToScan) throws InterruptedIOException { + private Map> scan(final List filesToScan) + throws InterruptedIOException, InterruptedException { Map fileNamesToPsiFiles = mapFilesToElements(filesToScan); List errors = PylintRunner.scan(plugin.getProject(), fileNamesToPsiFiles.keySet()); String baseDir = plugin.getProject().getBasePath(); diff --git a/src/main/java/com/leinardi/pycharm/pylint/plapi/PylintRunner.java b/src/main/java/com/leinardi/pycharm/pylint/plapi/PylintRunner.java index 28fa51f..d2fe605 100644 --- a/src/main/java/com/leinardi/pycharm/pylint/plapi/PylintRunner.java +++ b/src/main/java/com/leinardi/pycharm/pylint/plapi/PylintRunner.java @@ -229,7 +229,8 @@ public static String detectSystemPylintPath() { } } - public static List scan(Project project, Set filesToScan) throws InterruptedIOException { + public static List scan(Project project, Set filesToScan) throws InterruptedIOException, + InterruptedException { if (!checkPylintAvailable(project, true)) { return Collections.emptyList(); } @@ -270,18 +271,34 @@ public static List scan(Project project, Set filesToScan) throws cmd.setWorkDirectory(project.getBasePath()); final Process process; + try { process = cmd.createProcess(); Moshi moshi = new Moshi.Builder().build(); Type type = Types.newParameterizedType(List.class, Issue.class); JsonAdapter> adapter = moshi.adapter(type); InputStream inputStream = process.getInputStream(); - //TODO check stderr for errors + assert (inputStream != null); + List issues; if (checkIfInputStreamIsEmpty(inputStream)) { - return new ArrayList<>(); + issues = new ArrayList<>(); } else { - return adapter.fromJson(Okio.buffer(Okio.source(inputStream))); + issues = adapter.fromJson(Okio.buffer(Okio.source(inputStream))); + } + process.waitFor(); + + // Anything equal or bigger than 32 is an abnormal exit code + // See https://docs.pylint.org/en/1.6.0/run.html#exit-codes + int exitCode = process.exitValue(); + if (exitCode >= 32) { + InputStream errStream = process.getErrorStream(); + String detail = new BufferedReader(new InputStreamReader(errStream)) + .lines().collect(Collectors.joining("\n")); + + Notifications.showPylintAbnormalExit(project, detail); + throw new PylintToolException("Pylint failed with code " + exitCode); } + return issues; } catch (InterruptedIOException e) { LOG.info("Command Line string: " + cmd.getCommandLineString()); throw e; diff --git a/src/main/java/com/leinardi/pycharm/pylint/util/Notifications.java b/src/main/java/com/leinardi/pycharm/pylint/util/Notifications.java index 7affd86..edb55c1 100644 --- a/src/main/java/com/leinardi/pycharm/pylint/util/Notifications.java +++ b/src/main/java/com/leinardi/pycharm/pylint/util/Notifications.java @@ -117,6 +117,14 @@ public static void showUnableToRunPylint(final Project project) { .notify(project); } + public static void showPylintAbnormalExit(final Project project, final String detail) { + BALLOON_GROUP + .createNotification(TITLE, detail, ERROR) + .setListener(URL_OPENING_LISTENER) + .setSubtitle(PylintBundle.message("plugin.notification.abnormal-exit.subtitle")) + .notify(project); + } + public static void showNoPythonInterpreter(Project project) { Notification notification = BALLOON_GROUP .createNotification( diff --git a/src/main/resources/com/leinardi/pycharm/pylint/PylintBundle.properties b/src/main/resources/com/leinardi/pycharm/pylint/PylintBundle.properties index ad5db80..e5329f4 100644 --- a/src/main/resources/com/leinardi/pycharm/pylint/PylintBundle.properties +++ b/src/main/resources/com/leinardi/pycharm/pylint/PylintBundle.properties @@ -53,6 +53,7 @@ plugin.notification.unable-to-run-pylint.subtitle=Unable to run Pylint plugin.notification.unable-to-run-pylint.content=Pylint is installed inside the project environment but the plugin \ is not able to run it. If you just installed it try to run File -> Synchronize or restart your IDE. \ If the problem persists you may need to manually enter the path to the Pylint executable inside the Plugin settings. +plugin.notification.abnormal-exit.subtitle=Pylint exited abnormally plugin.notification.action.plugin-settings=Plugin settings plugin.notification.install-pylint.subtitle=Pylint missing plugin.notification.install-pylint.content=The project interpreter is missing Pylint, which is needed \