int (List<String> commands) { try { final AtomicInteger exitCode = new AtomicInteger(); final @NlsSafe StringBuilder errorOutput = new StringBuilder(); final List<@NlsSafe String> delayedInfoOutput = new ArrayList<>(); final Process process = new ProcessBuilder(CommandLineUtil.toCommandLine(commands)).start(); BaseOSProcessHandler handler = new BaseOSProcessHandler(process, commands.toString(), null); handler.addProcessListener(new ProcessAdapter() { @Override public void startNotified(@NotNull ProcessEvent event) { if (myProperties.verbose) { LOG.info("Started " + commands); } } @Override public void processTerminated(@NotNull ProcessEvent event) { if (myProperties.verbose) { LOG.info("Terminated " + commands + ", exit code: " + event.getExitCode()); } exitCode.set(event.getExitCode()); } @Override public void onTextAvailable(@NotNull ProcessEvent event, @NotNull Key outputType) { String message = StringUtil.trimTrailing(event.getText()); if (outputType == ProcessOutputTypes.STDERR) { LOG.error(message, (Throwable)null); errorOutput.append(event.getText()); } else { LOG.info(message); if (myProperties.verbose) { info(message); } else { delayedInfoOutput.add(message); } } } }); handler.startNotify(); handler.waitFor(); int result = exitCode.get(); if (result != 0) { final String message = errorOutput.toString(); if (!StringUtil.isEmptyOrSpaces(message)) { error(message); } for (@NlsSafe String info : delayedInfoOutput) { error(info); } } return result; } catch (Exception e) { error(e.getMessage()); LOG.warn(e); return -1; } }