您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

Main.java 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /*
  2. * SonarQube Runner - CLI - Distribution
  3. * Copyright (C) 2011 SonarSource
  4. * sonarqube@googlegroups.com
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
  19. */
  20. package org.sonar.runner.cli;
  21. import java.io.BufferedReader;
  22. import java.io.IOException;
  23. import java.io.InputStreamReader;
  24. import java.nio.charset.StandardCharsets;
  25. import java.util.Properties;
  26. import org.sonar.runner.api.EmbeddedRunner;
  27. /**
  28. * Arguments :
  29. * <ul>
  30. * <li>runner.home: optional path to runner home (root directory with sub-directories bin, lib and conf)</li>
  31. * <li>runner.settings: optional path to runner global settings, usually ${runner.home}/conf/sonar-runner.properties.
  32. * This property is used only if ${runner.home} is not defined</li>
  33. * <li>project.home: path to project root directory. If not set, then it's supposed to be the directory where the runner is executed</li>
  34. * <li>project.settings: optional path to project settings. Default value is ${project.home}/sonar-project.properties.</li>
  35. * </ul>
  36. *
  37. * @since 1.0
  38. */
  39. public class Main {
  40. private final Shutdown shutdown;
  41. private final Cli cli;
  42. private final Conf conf;
  43. private EmbeddedRunner runner;
  44. private BufferedReader inputReader;
  45. private RunnerFactory runnerFactory;
  46. private Logs logger;
  47. Main(Shutdown shutdown, Cli cli, Conf conf, RunnerFactory runnerFactory, Logs logger) {
  48. this.shutdown = shutdown;
  49. this.cli = cli;
  50. this.conf = conf;
  51. this.runnerFactory = runnerFactory;
  52. this.logger = logger;
  53. }
  54. public static void main(String[] args) {
  55. Exit exit = new Exit();
  56. Shutdown shutdown = new Shutdown(exit);
  57. Logs logs = new Logs();
  58. Cli cli = new Cli(exit, logs).parse(args);
  59. cli.verify();
  60. Main main = new Main(shutdown, cli, new Conf(cli, logs), new RunnerFactory(logs), logs);
  61. main.execute();
  62. }
  63. void execute() {
  64. Stats stats = new Stats(logger).start();
  65. try {
  66. Properties p = conf.properties();
  67. init(p);
  68. runner.start();
  69. if (cli.isInteractive()) {
  70. interactiveLoop(p);
  71. } else {
  72. runAnalysis(stats, p);
  73. }
  74. } catch (Exception e) {
  75. displayExecutionResult(stats, "FAILURE");
  76. showError("Error during Sonar runner execution", e, cli.isDisplayStackTrace());
  77. shutdown.exit(Exit.ERROR);
  78. }
  79. runner.stop();
  80. shutdown.exit(Exit.SUCCESS);
  81. }
  82. private void interactiveLoop(Properties p) throws IOException {
  83. do {
  84. Stats stats = new Stats(logger).start();
  85. try {
  86. runAnalysis(stats, p);
  87. } catch (Exception e) {
  88. displayExecutionResult(stats, "FAILURE");
  89. showError("Error during Sonar runner execution", e, cli.isDisplayStackTrace());
  90. }
  91. } while (waitForUser());
  92. }
  93. private void init(Properties p) throws IOException {
  94. SystemInfo.print(logger);
  95. if (cli.isDisplayVersionOnly()) {
  96. shutdown.exit(Exit.SUCCESS);
  97. }
  98. if (cli.isDisplayStackTrace()) {
  99. logger.info("Error stacktraces are turned on.");
  100. }
  101. runner = runnerFactory.create(p);
  102. }
  103. private void runAnalysis(Stats stats, Properties p) {
  104. runner.runAnalysis(p);
  105. displayExecutionResult(stats, "SUCCESS");
  106. }
  107. private boolean waitForUser() throws IOException {
  108. if (inputReader == null) {
  109. inputReader = new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8));
  110. }
  111. shutdown.signalReady(true);
  112. if (shutdown.shouldExit()) {
  113. // exit before displaying message
  114. return false;
  115. }
  116. System.out.println("");
  117. System.out.println("<Press enter to restart analysis or Ctrl+C to exit the interactive mode>");
  118. String line = inputReader.readLine();
  119. shutdown.signalReady(false);
  120. return line != null;
  121. }
  122. // Visible for testing
  123. void setInputReader(BufferedReader inputReader) {
  124. this.inputReader = inputReader;
  125. }
  126. private void displayExecutionResult(Stats stats, String resultMsg) {
  127. logger.info("------------------------------------------------------------------------");
  128. logger.info("EXECUTION " + resultMsg);
  129. logger.info("------------------------------------------------------------------------");
  130. stats.stop();
  131. logger.info("------------------------------------------------------------------------");
  132. }
  133. private void showError(String message, Throwable e, boolean showStackTrace) {
  134. if (showStackTrace) {
  135. logger.error(message, e);
  136. if (!cli.isDebugMode()) {
  137. logger.error("");
  138. suggestDebugMode();
  139. }
  140. } else {
  141. logger.error(message);
  142. if (e != null) {
  143. logger.error(e.getMessage());
  144. String previousMsg = "";
  145. for (Throwable cause = e.getCause(); cause != null
  146. && cause.getMessage() != null
  147. && !cause.getMessage().equals(previousMsg); cause = cause.getCause()) {
  148. logger.error("Caused by: " + cause.getMessage());
  149. previousMsg = cause.getMessage();
  150. }
  151. }
  152. logger.error("");
  153. logger.error("To see the full stack trace of the errors, re-run SonarQube Runner with the -e switch.");
  154. if (!cli.isDebugMode()) {
  155. suggestDebugMode();
  156. }
  157. }
  158. }
  159. private void suggestDebugMode() {
  160. logger.error("Re-run SonarQube Runner using the -X switch to enable full debug logging.");
  161. }
  162. }