aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java
diff options
context:
space:
mode:
authorJulien HENRY <julien.henry@sonarsource.com>2013-01-30 10:19:34 +0100
committerJulien HENRY <julien.henry@sonarsource.com>2013-01-30 10:19:34 +0100
commit9f2628c20da0a377f81bdeffdec77691568e23c6 (patch)
tree743a4527737deeb837fe94afd336d6c8798c6935 /src/main/java
parent6c62a2c27cc29c9a74a833f2226adbd734c132ff (diff)
downloadsonar-scanner-cli-9f2628c20da0a377f81bdeffdec77691568e23c6.tar.gz
sonar-scanner-cli-9f2628c20da0a377f81bdeffdec77691568e23c6.zip
SONAR-2291 Implemented cache on Sonar Runner side (for bootstrap JARs).
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/sonar/runner/BootstrapClassLoader.java124
-rw-r--r--src/main/java/org/sonar/runner/Bootstrapper.java186
-rw-r--r--src/main/java/org/sonar/runner/IOUtils.java200
-rw-r--r--src/main/java/org/sonar/runner/Logs.java40
-rw-r--r--src/main/java/org/sonar/runner/Main.java337
-rw-r--r--src/main/java/org/sonar/runner/Runner.java368
-rw-r--r--src/main/java/org/sonar/runner/RunnerException.java52
-rw-r--r--src/main/java/org/sonar/runner/Stats.java60
-rw-r--r--src/main/java/org/sonar/runner/Version.java52
-rw-r--r--src/main/java/org/sonar/runner/internal/batch/Launcher.java157
-rw-r--r--src/main/java/org/sonar/runner/internal/batch/SonarProjectBuilder.java546
-rw-r--r--src/main/java/org/sonar/runner/internal/batch/SonarRunnerUtils.java45
-rw-r--r--src/main/java/org/sonar/runner/internal/batch/package-info.java24
-rw-r--r--src/main/java/org/sonar/runner/package-info.java23
14 files changed, 0 insertions, 2214 deletions
diff --git a/src/main/java/org/sonar/runner/BootstrapClassLoader.java b/src/main/java/org/sonar/runner/BootstrapClassLoader.java
deleted file mode 100644
index 1a492c1..0000000
--- a/src/main/java/org/sonar/runner/BootstrapClassLoader.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Sonar Runner
- * Copyright (C) 2011 SonarSource
- * dev@sonar.codehaus.org
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
- */
-package org.sonar.runner;
-
-import java.io.IOException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.Enumeration;
-
-/**
- * Special {@link URLClassLoader} to execute Sonar, which restricts loading from parent.
- */
-class BootstrapClassLoader extends URLClassLoader {
-
- private final String[] unmaskedPackages;
-
- BootstrapClassLoader(ClassLoader parent, String... unmaskedPackages) {
- super(new URL[0], parent);
- this.unmaskedPackages = unmaskedPackages;
- }
-
- /**
- * {@inheritDoc} Visibility of a method has been relaxed to public.
- */
- @Override
- public void addURL(URL url) {
- super.addURL(url);
- }
-
- /**
- * {@inheritDoc} Visibility of a method has been relaxed to public.
- */
- @Override
- public Class<?> findClass(String name) throws ClassNotFoundException {
- return super.findClass(name);
- }
-
- /**
- * @return true, if class can be loaded from parent ClassLoader
- */
- boolean canLoadFromParent(String name) {
- if (name.startsWith("org.sonar.runner.") && !name.startsWith("org.sonar.runner.internal.batch.")) {
- return true;
- }
- for (String pkg : unmaskedPackages) {
- if (name.startsWith(pkg + ".")) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Same behavior as in {@link URLClassLoader#loadClass(String, boolean)}, except loading from parent.
- */
- @Override
- protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
- // First, check if the class has already been loaded
- Class<?> c = findLoadedClass(name);
- if (c == null) {
- try {
- // Load from parent
- if (getParent() != null && canLoadFromParent(name)) {
- c = getParent().loadClass(name);
- } else {
- // Load from system
-
- // I don't know for other vendors, but for Oracle JVM :
- // - ClassLoader.getSystemClassLoader() is sun.misc.Launcher$AppClassLoader. It contains app classpath.
- // - ClassLoader.getSystemClassLoader().getParent() is sun.misc.Launcher$ExtClassLoader. It contains core JVM
- ClassLoader systemClassLoader = getSystemClassLoader();
- if (systemClassLoader.getParent() != null) {
- systemClassLoader = systemClassLoader.getParent();
- }
- c = systemClassLoader.loadClass(name);
- }
- } catch (ClassNotFoundException e) {
- // If still not found, then invoke findClass in order
- // to find the class.
- c = findClass(name);
- }
- }
- if (resolve) {
- resolveClass(c);
- }
- return c;
- }
-
- /**
- * Unlike {@link URLClassLoader#getResource(String)} don't return resource from parent.
- * See http://jira.codehaus.org/browse/SONAR-2276
- */
- @Override
- public URL getResource(String name) {
- return findResource(name);
- }
-
- /**
- * Unlike {@link URLClassLoader#getResources(String)} don't return resources from parent.
- * See http://jira.codehaus.org/browse/SONAR-2276
- */
- @Override
- public Enumeration<URL> getResources(String name) throws IOException {
- return findResources(name);
- }
-
-}
diff --git a/src/main/java/org/sonar/runner/Bootstrapper.java b/src/main/java/org/sonar/runner/Bootstrapper.java
deleted file mode 100644
index bfe6757..0000000
--- a/src/main/java/org/sonar/runner/Bootstrapper.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Sonar Runner
- * Copyright (C) 2011 SonarSource
- * dev@sonar.codehaus.org
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
- */
-package org.sonar.runner;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.net.ConnectException;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Bootstrapper used to download everything from the server and create the correct classloader required to execute a Sonar analysis in isolation.
- */
-class Bootstrapper {
-
- static final String VERSION_PATH = "/api/server/version";
- static final String BATCH_PATH = "/batch/";
- static final int CONNECT_TIMEOUT_MILLISECONDS = 30000;
- static final int READ_TIMEOUT_MILLISECONDS = 60000;
-
- private File bootDir;
- private String serverUrl;
- private String productToken;
- private String serverVersion;
-
- /**
- * @param productToken part of User-Agent request-header field - see http://tools.ietf.org/html/rfc1945#section-10.15
- */
- Bootstrapper(String productToken, String serverUrl, File workDir) {
- this.productToken = productToken;
- bootDir = new File(workDir, "batch");
- bootDir.mkdirs();
- if (serverUrl.endsWith("/")) {
- this.serverUrl = serverUrl.substring(0, serverUrl.length() - 1);
- } else {
- this.serverUrl = serverUrl;
- }
- }
-
- /**
- * @return server url
- */
- String getServerUrl() {
- return serverUrl;
- }
-
- /**
- * @return server version
- */
- String getServerVersion() {
- if (serverVersion == null) {
- try {
- serverVersion = remoteContent(VERSION_PATH);
- } catch (ConnectException e) {
- Logs.error("Sonar server '" + serverUrl + "' can not be reached");
- throw new RunnerException("Fail to request server version", e);
- } catch (UnknownHostException e) {
- Logs.error("Sonar server '" + serverUrl + "' can not be reached");
- throw new RunnerException("Fail to request server version", e);
- } catch (IOException e) {
- throw new RunnerException("Fail to request server version", e);
- }
- }
- return serverVersion;
- }
-
- /**
- * Download batch files from server and creates {@link BootstrapClassLoader}.
- * To use this method version of Sonar should be at least 2.6.
- *
- * @param urls additional URLs for loading classes and resources
- * @param parent parent ClassLoader
- * @param unmaskedPackages only classes and resources from those packages would be available for loading from parent
- */
- BootstrapClassLoader createClassLoader(URL[] urls, ClassLoader parent, String... unmaskedPackages) {
- BootstrapClassLoader classLoader = new BootstrapClassLoader(parent, unmaskedPackages);
- List<File> files = downloadBatchFiles();
- for (URL url : urls) {
- classLoader.addURL(url);
- }
- for (File file : files) {
- try {
- classLoader.addURL(file.toURI().toURL());
- } catch (MalformedURLException e) {
- throw new IllegalStateException("Fail to create classloader", e);
- }
- }
- return classLoader;
- }
-
- private void remoteContentToFile(String path, File toFile) {
- InputStream input = null;
- FileOutputStream output = null;
- String fullUrl = serverUrl + path;
- try {
- HttpURLConnection connection = newHttpConnection(new URL(fullUrl));
- output = new FileOutputStream(toFile, false);
- input = connection.getInputStream();
- IOUtils.copyLarge(input, output);
- } catch (IOException e) {
- IOUtils.closeQuietly(output);
- IOUtils.deleteQuietly(toFile);
- throw new IllegalStateException("Fail to download the file: " + fullUrl, e);
- } finally {
- IOUtils.closeQuietly(input);
- IOUtils.closeQuietly(output);
- }
- }
-
- String remoteContent(String path) throws IOException {
- String fullUrl = serverUrl + path;
- HttpURLConnection conn = newHttpConnection(new URL(fullUrl));
- String charset = IOUtils.getCharsetFromContentType(conn.getContentType());
- if (charset == null || "".equals(charset)) {
- charset = "UTF-8";
- }
- Reader reader = new InputStreamReader((InputStream) conn.getContent(), charset);
- try {
- int statusCode = conn.getResponseCode();
- if (statusCode != HttpURLConnection.HTTP_OK) {
- throw new IOException("Status returned by url : '" + fullUrl + "' is invalid : " + statusCode);
- }
- return IOUtils.toString(reader);
- } finally {
- IOUtils.closeQuietly(reader);
- conn.disconnect();
- }
- }
-
- /**
- * By convention, the product tokens are listed in order of their significance for identifying the application.
- */
- String getUserAgent() {
- return "sonar-bootstrapper/" + Version.getVersion() + " " + productToken;
- }
-
- HttpURLConnection newHttpConnection(URL url) throws IOException {
- HttpURLConnection connection = (HttpURLConnection) url.openConnection();
- connection.setConnectTimeout(CONNECT_TIMEOUT_MILLISECONDS);
- connection.setReadTimeout(READ_TIMEOUT_MILLISECONDS);
- connection.setInstanceFollowRedirects(true);
- connection.setRequestMethod("GET");
- connection.setRequestProperty("User-Agent", getUserAgent());
- return connection;
- }
-
- private List<File> downloadBatchFiles() {
- try {
- List<File> files = new ArrayList<File>();
- String libs = remoteContent(BATCH_PATH);
- for (String lib : libs.split(",")) {
- File file = new File(bootDir, lib);
- remoteContentToFile(BATCH_PATH + lib, file);
- files.add(file);
- }
- return files;
- } catch (Exception e) {
- throw new IllegalStateException("Fail to download libraries from server", e);
- }
- }
-}
diff --git a/src/main/java/org/sonar/runner/IOUtils.java b/src/main/java/org/sonar/runner/IOUtils.java
deleted file mode 100644
index 248d18d..0000000
--- a/src/main/java/org/sonar/runner/IOUtils.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Sonar Runner
- * Copyright (C) 2011 SonarSource
- * dev@sonar.codehaus.org
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
- */
-package org.sonar.runner;
-
-import java.io.Closeable;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.Reader;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Internal class used only by the Runner as we don't want it to depend on third-party libs.
- * This class should not be used by Sonar Runner consumers.
- */
-final class IOUtils {
-
- private IOUtils() {
- // only static methods
- }
-
- /**
- * The default buffer size to use.
- */
- private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
-
- private static final Pattern CHARSET_PATTERN = Pattern.compile("(?i)\\bcharset=\\s*\"?([^\\s;\"]*)");
-
- /**
- * Unconditionally close a <code>Closeable</code>.
- */
- static void closeQuietly(Closeable closeable) {
- try {
- if (closeable != null) {
- closeable.close();
- }
- } catch (IOException ioe) {
- }
- }
-
- /**
- * Get the contents of a <code>Reader</code> as a String.
- */
- static String toString(Reader input) throws IOException {
- StringWriter sw = new StringWriter();
- copyLarge(input, sw);
- return sw.toString();
- }
-
- /**
- * Copy bytes from an <code>InputStream</code> to an <code>OutputStream</code>.
- */
- static long copyLarge(InputStream input, OutputStream output) throws IOException {
- byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
- long count = 0;
- int n = 0;
- while (-1 != (n = input.read(buffer))) {
- output.write(buffer, 0, n);
- count += n;
- }
- return count;
- }
-
- /**
- * Copy chars from a <code>Reader</code> to a <code>Writer</code>.
- */
- static long copyLarge(Reader input, Writer output) throws IOException {
- char[] buffer = new char[DEFAULT_BUFFER_SIZE];
- long count = 0;
- int n = 0;
- while (-1 != (n = input.read(buffer))) {
- output.write(buffer, 0, n);
- count += n;
- }
- return count;
- }
-
- /**
- * Duplicated from Commons IO
- */
- static boolean deleteQuietly(File file) {
- if (file == null) {
- return false;
- }
- try {
- if (file.isDirectory()) {
- cleanDirectory(file);
- }
- } catch (Exception ignored) {
- }
-
- try {
- return file.delete();
- } catch (Exception ignored) {
- return false;
- }
- }
-
- private static void cleanDirectory(File directory) throws IOException {
- if (!directory.exists()) {
- String message = directory + " does not exist";
- throw new IllegalArgumentException(message);
- }
-
- if (!directory.isDirectory()) {
- String message = directory + " is not a directory";
- throw new IllegalArgumentException(message);
- }
-
- File[] files = directory.listFiles();
- // null if security restricted
- if (files == null) {
- throw new IOException("Failed to list contents of " + directory);
- }
-
- IOException exception = null;
- for (File file : files) {
- try {
- forceDelete(file);
- } catch (IOException ioe) {
- exception = ioe;
- }
- }
-
- if (null != exception) {
- throw exception;
- }
- }
-
- private static void forceDelete(File file) throws IOException {
- if (file.isDirectory()) {
- deleteDirectory(file);
- } else {
- boolean filePresent = file.exists();
- if (!file.delete()) {
- if (!filePresent) {
- throw new FileNotFoundException("File does not exist: " + file);
- }
- String message =
- "Unable to delete file: " + file;
- throw new IOException(message);
- }
- }
- }
-
- private static void deleteDirectory(File directory) throws IOException {
- if (!directory.exists()) {
- return;
- }
-
- cleanDirectory(directory);
-
- if (!directory.delete()) {
- String message =
- "Unable to delete directory " + directory + ".";
- throw new IOException(message);
- }
- }
-
- /**
- * Parse out a charset from a content type header.
- *
- * @param contentType e.g. "text/html; charset=EUC-JP"
- * @return "EUC-JP", or null if not found. Charset is trimmed and uppercased.
- */
- static String getCharsetFromContentType(String contentType) {
- if (contentType == null) {
- return null;
- }
-
- Matcher m = CHARSET_PATTERN.matcher(contentType);
- if (m.find()) {
- return m.group(1).trim().toUpperCase();
- }
- return null;
- }
-
-}
diff --git a/src/main/java/org/sonar/runner/Logs.java b/src/main/java/org/sonar/runner/Logs.java
deleted file mode 100644
index 2bd24d6..0000000
--- a/src/main/java/org/sonar/runner/Logs.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Sonar Runner
- * Copyright (C) 2011 SonarSource
- * dev@sonar.codehaus.org
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
- */
-package org.sonar.runner;
-
-final class Logs {
- private Logs() {
- }
-
- static void info(String message) {
- System.out.println("INFO: " + message);
- }
-
- static void error(String message) {
- System.err.println("ERROR: " + message);
- }
-
- static void error(String message, Throwable t) {
- System.err.println("ERROR: " + message);
- if (t != null) {
- t.printStackTrace(System.err);
- }
- }
-}
diff --git a/src/main/java/org/sonar/runner/Main.java b/src/main/java/org/sonar/runner/Main.java
deleted file mode 100644
index add38bf..0000000
--- a/src/main/java/org/sonar/runner/Main.java
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * Sonar Runner
- * Copyright (C) 2011 SonarSource
- * dev@sonar.codehaus.org
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
- */
-package org.sonar.runner;
-
-import com.google.common.annotations.VisibleForTesting;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Locale;
-import java.util.Properties;
-
-/**
- * Arguments :
- * <ul>
- * <li>runner.home: optional path to runner home (root directory with sub-directories bin, lib and conf)</li>
- * <li>runner.settings: optional path to runner global settings, usually ${runner.home}/conf/sonar-runner.properties.
- * This property is used only if ${runner.home} is not defined</li>
- * <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>
- * <li>project.settings: optional path to project settings. Default value is ${project.home}/sonar-project.properties.</li>
- * </ul>
- *
- * @since 1.0
- */
-public final class Main {
-
- private static final String RUNNER_HOME = "runner.home";
- private static final String RUNNER_SETTINGS = "runner.settings";
- private static final String PROJECT_HOME = "project.home";
- private static final String PROJECT_SETTINGS = "project.settings";
- // TODO Remove this after everything is updated to support tasks
- private static final String TASK_COMMAND = "sonar.task";
-
- @VisibleForTesting
- boolean debugMode = false;
- @VisibleForTesting
- boolean displayVersionOnly = false;
- @VisibleForTesting
- boolean displayStackTrace = false;
- @VisibleForTesting
- String command;
- @VisibleForTesting
- Properties globalProperties;
- @VisibleForTesting
- Properties projectProperties;
-
- /**
- * Entry point of the program.
- */
- public static void main(String[] args) {
- new Main().execute(args);
- }
-
- @VisibleForTesting
- Main() {
- }
-
- private void execute(String[] args) {
- Properties argsProperties = parseArguments(args);
- System.out.println("Runner version: " + Version.getVersion());
- System.out.println("Java version: " + System.getProperty("java.version", "<unknown>")
- + ", vendor: " + System.getProperty("java.vendor", "<unknown>"));
- System.out
- .println("OS name: \"" + System.getProperty("os.name") + "\", version: \"" + System.getProperty("os.version") + "\", arch: \"" + System.getProperty("os.arch") + "\"");
- if (!displayVersionOnly) {
- int result = execute(argsProperties);
- System.exit(result);
- }
- }
-
- private int execute(Properties argsProperties) {
- if (displayStackTrace) {
- Logs.info("Error stacktraces are turned on.");
- }
- Stats stats = new Stats().start();
- try {
- loadProperties(argsProperties);
- Runner runner = Runner.create(command, globalProperties, projectProperties);
- Logs.info("Default locale: \"" + Locale.getDefault() + "\", source code encoding: \"" + runner.getSourceCodeEncoding() + "\""
- + (runner.isEncodingPlatformDependant() ? " (analysis is platform dependent)" : ""));
- if (debugMode) {
- Logs.info("Other system properties:");
- Logs.info(" - sun.arch.data.model: \"" + System.getProperty("sun.arch.data.model") + "\"");
- }
- Logs.info("Server: " + runner.getSonarServerURL());
- try {
- Logs.info("Work directory: " + runner.getWorkDir().getCanonicalPath());
- } catch (IOException e) {
- throw new RunnerException("Unable to display work directory", e);
- }
- runner.execute();
- } catch (Exception e) {
- displayExecutionResult(stats, "FAILURE");
- showError("Error during Sonar runner execution", e, displayStackTrace);
- return 1;
- }
- displayExecutionResult(stats, "SUCCESS");
- return 0;
- }
-
- private void displayExecutionResult(Stats stats, String resultMsg) {
- Logs.info("------------------------------------------------------------------------");
- Logs.info("EXECUTION " + resultMsg);
- Logs.info("------------------------------------------------------------------------");
- stats.stop();
- Logs.info("------------------------------------------------------------------------");
- }
-
- public void showError(String message, Throwable e, boolean showStackTrace) {
- if (showStackTrace) {
- Logs.error(message, e);
- if (!debugMode) {
- Logs.error("");
- suggestDebugMode();
- }
- }
- else {
- Logs.error(message);
- if (e != null) {
- Logs.error(e.getMessage());
- String previousMsg = "";
- for (Throwable cause = e.getCause(); cause != null
- && cause.getMessage() != null
- && !cause.getMessage().equals(previousMsg); cause = cause.getCause()) {
- Logs.error("Caused by: " + cause.getMessage());
- previousMsg = cause.getMessage();
- }
- }
- Logs.error("");
- Logs.error("To see the full stack trace of the errors, re-run Sonar Runner with the -e switch.");
- if (!debugMode) {
- suggestDebugMode();
- }
- }
- }
-
- private void suggestDebugMode() {
- Logs.error("Re-run Sonar Runner using the -X switch to enable full debug logging.");
- }
-
- @VisibleForTesting
- void loadProperties(Properties argsProperties) {
- globalProperties = loadGlobalProperties(argsProperties);
- projectProperties = loadProjectProperties(argsProperties);
- }
-
- @VisibleForTesting
- Properties loadGlobalProperties(Properties argsProperties) {
- Properties commandLineProps = new Properties();
- commandLineProps.putAll(System.getProperties());
- commandLineProps.putAll(argsProperties);
-
- Properties result = new Properties();
- result.putAll(loadRunnerConfiguration(commandLineProps));
- result.putAll(commandLineProps);
-
- return result;
- }
-
- @VisibleForTesting
- Properties loadProjectProperties(Properties argsProperties) {
- Properties commandLineProps = new Properties();
- commandLineProps.putAll(System.getProperties());
- commandLineProps.putAll(argsProperties);
-
- Properties result = new Properties();
- result.putAll(loadProjectConfiguration(commandLineProps));
- result.putAll(commandLineProps);
-
- if (result.containsKey(PROJECT_HOME)) {
- // the real property of the Sonar Runner is "sonar.projectDir"
- String baseDir = result.getProperty(PROJECT_HOME);
- result.remove(PROJECT_HOME);
- result.put(Runner.PROPERTY_SONAR_PROJECT_BASEDIR, baseDir);
- }
-
- return result;
- }
-
- @VisibleForTesting
- Properties loadRunnerConfiguration(Properties props) {
- File settingsFile = locatePropertiesFile(props, RUNNER_HOME, "conf/sonar-runner.properties", RUNNER_SETTINGS);
- if (settingsFile != null && settingsFile.isFile() && settingsFile.exists()) {
- Logs.info("Runner configuration file: " + settingsFile.getAbsolutePath());
- return toProperties(settingsFile);
- }
- Logs.info("Runner configuration file: NONE");
- return new Properties();
- }
-
- private Properties loadProjectConfiguration(Properties props) {
- File settingsFile = locatePropertiesFile(props, PROJECT_HOME, "sonar-project.properties", PROJECT_SETTINGS);
- if (settingsFile != null && settingsFile.isFile() && settingsFile.exists()) {
- Logs.info("Project configuration file: " + settingsFile.getAbsolutePath());
- return toProperties(settingsFile);
- }
- Logs.info("Project configuration file: NONE");
- return new Properties();
- }
-
- private File locatePropertiesFile(Properties props, String homeKey, String relativePathFromHome, String settingsKey) {
- File settingsFile = null;
- String runnerHome = props.getProperty(homeKey);
- if (runnerHome != null && !"".equals(runnerHome)) {
- settingsFile = new File(runnerHome, relativePathFromHome);
- }
-
- if (settingsFile == null || !settingsFile.exists()) {
- String settingsPath = props.getProperty(settingsKey);
- if (settingsPath != null && !"".equals(settingsPath)) {
- settingsFile = new File(settingsPath);
- }
- }
- return settingsFile;
- }
-
- private Properties toProperties(File file) {
- InputStream in = null;
- Properties properties = new Properties();
- try {
- in = new FileInputStream(file);
- properties.load(in);
- return properties;
-
- } catch (Exception e) {
- throw new IllegalStateException("Fail to load file: " + file.getAbsolutePath(), e);
-
- } finally {
- IOUtils.closeQuietly(in);
- }
- }
-
- @VisibleForTesting
- Properties parseArguments(String[] args) {
- int i = 0;
- if (args.length > 0 && !args[0].startsWith("-")) {
- command = args[0];
- i++;
- }
- else {
- command = null;
- }
- Properties props = new Properties();
- for (; i < args.length; i++) {
- String arg = args[i];
- if ("-h".equals(arg) || "--help".equals(arg)) {
- printUsage();
- }
- else if ("-v".equals(arg) || "--version".equals(arg)) {
- displayVersionOnly = true;
- }
- else if ("-e".equals(arg) || "--errors".equals(arg)) {
- displayStackTrace = true;
- }
- else if ("-X".equals(arg) || "--debug".equals(arg)) {
- props.setProperty(Runner.PROPERTY_VERBOSE, "true");
- displayStackTrace = true;
- debugMode = true;
- }
- else if ("-D".equals(arg) || "--define".equals(arg)) {
- i++;
- if (i >= args.length) {
- printError("Missing argument for option --define");
- }
- arg = args[i];
- appendPropertyTo(arg, props);
-
- }
- else if (arg.startsWith("-D")) {
- arg = arg.substring(2);
- appendPropertyTo(arg, props);
-
- }
- else {
- printError("Unrecognized option: " + arg);
- }
- }
- return props;
- }
-
- private void appendPropertyTo(String arg, Properties props) {
- final String key, value;
- int j = arg.indexOf('=');
- if (j == -1) {
- key = arg;
- value = "true";
- } else {
- key = arg.substring(0, j);
- value = arg.substring(j + 1);
- }
- if (TASK_COMMAND.equals(key)) {
- command = value;
- }
- else {
- props.setProperty(key, value);
- }
- }
-
- private void printError(String message) {
- Logs.error(message);
- printUsage();
- }
-
- private void printUsage() {
- Logs.info("");
- Logs.info("usage: sonar-runner [command] [options]");
- Logs.info("");
- Logs.info("Command:");
- Logs.info(" analyse-project Run Sonar analysis task on the current project (default)");
- Logs.info(" list-tasks Display all tasks available");
- Logs.info("Options:");
- Logs.info(" -D,--define <arg> Define property");
- Logs.info(" -e,--errors Produce execution error messages");
- Logs.info(" -h,--help Display help information");
- Logs.info(" -v,--version Display version information");
- Logs.info(" -X,--debug Produce execution debug output");
- System.exit(0);
- }
-}
diff --git a/src/main/java/org/sonar/runner/Runner.java b/src/main/java/org/sonar/runner/Runner.java
deleted file mode 100644
index 9d404da..0000000
--- a/src/main/java/org/sonar/runner/Runner.java
+++ /dev/null
@@ -1,368 +0,0 @@
-/*
- * Sonar Runner
- * Copyright (C) 2011 SonarSource
- * dev@sonar.codehaus.org
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
- */
-package org.sonar.runner;
-
-import com.google.common.annotations.VisibleForTesting;
-
-import java.io.File;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Properties;
-
-/**
- * <p>
- * Sonar Runner class that can be used to launch Sonar analyses.
- * </p>
- * <p>
- * Configuration is all done through properties:
- * </p>
- * <ul>
- * <li>"sonar.projectDir": the base directory of the project to analyse (this can also be passed via the {@link #create(Properties, File)} constructor)</li>
- * <li>"sonar.working.directory": the working directory, which is "${sonar.projectDir}/.sonar" by default.</li>
- * <li>"sonar.verbose": if set to "true", more information is displayed in the log</li>
- * <li>"sonar.environment.information.key" and "sonar.environment.information.version": can be used to overwrite environment information (can also be
- * set via {@link #setEnvironmentInformation(String, String)} method)</li>
- * <li>... plus all the other Sonar and Sonar plugins properties.</li>
- * </ul>
- *
- * @since 1.1
- */
-public final class Runner {
-
- /**
- * Old property used to activate debug level for logging.
- *
- * @deprecated Replaced by sonar.verbose since 1.2
- */
- @Deprecated
- public static final String PROPERTY_OLD_DEBUG_MODE = "runner.debug";
-
- /**
- * Property used to increase logging information.
- *
- * @since 1.2
- */
- public static final String PROPERTY_VERBOSE = "sonar.verbose";
-
- /**
- * Property used to specify the working directory for the runner. May be a relative or absolute path.
- *
- * @since 1.4
- */
- public static final String PROPERTY_WORK_DIRECTORY = "sonar.working.directory";
-
- /**
- * Default value of the working directory.
- */
- public static final String DEF_VALUE_WORK_DIRECTORY = ".sonar";
-
- /**
- * Property used to specify the base directory of the project to analyse.
- *
- * @since 1.5
- */
- public static final String PROPERTY_SONAR_PROJECT_BASEDIR = "sonar.projectBaseDir";
-
- /**
- * Property used to specify the name of the tool that will run a Sonar analysis.
- *
- * @since 1.5
- */
- public static final String PROPERTY_ENVIRONMENT_INFORMATION_KEY = "sonar.environment.information.key";
-
- /**
- * Property used to specify the version of the tool that will run a Sonar analysis.
- *
- * @since 1.5
- */
- public static final String PROPERTY_ENVIRONMENT_INFORMATION_VERSION = "sonar.environment.information.version";
-
- /**
- * Array of prefixes of versions of Sonar without support of this runner.
- */
- private static final String[] UNSUPPORTED_VERSIONS = {"1", "2.0", "2.1", "2.2", "2.3", "2.4", "2.5", "2.6", "2.7", "2.8", "2.9", "2.10"};
- private static final String[] UNSUPPORTED_VERSIONS_FOR_TASKS = {"1", "2", "3.0", "3.1", "3.2", "3.3", "3.4"};
-
- private static final String PROPERTY_SOURCE_ENCODING = "sonar.sourceEncoding";
-
- private String command;
- private File projectDir;
- private File workDir;
- private String[] unmaskedPackages;
- private List<Object> containerExtensions = new ArrayList<Object>();
- private Properties globalProperties;
- private Properties projectProperties;
- private boolean isEncodingPlatformDependant;
-
- private Runner(String command, Properties globalProperties, Properties projectProperties) {
- this.command = command;
- this.globalProperties = globalProperties;
- this.projectProperties = projectProperties;
- this.unmaskedPackages = new String[0];
- // set the default values for the Sonar Runner - they can be overriden with #setEnvironmentInformation
- this.globalProperties.put(PROPERTY_ENVIRONMENT_INFORMATION_KEY, "Runner");
- this.globalProperties.put(PROPERTY_ENVIRONMENT_INFORMATION_VERSION, Version.getVersion());
- // sets the encoding if not forced
- if (!globalProperties.containsKey(PROPERTY_SOURCE_ENCODING) && !projectProperties.containsKey(PROPERTY_SOURCE_ENCODING)) {
- isEncodingPlatformDependant = true;
- globalProperties.setProperty(PROPERTY_SOURCE_ENCODING, Charset.defaultCharset().name());
- }
- // and init the directories
- initDirs();
- }
-
- /**
- * Creates a Runner based only on the given properties.
- * @deprecated Use {@link Runner#create(String, Properties, Properties)}
- */
- @Deprecated
- public static Runner create(Properties props) {
- return create(null, new Properties(), props);
- }
-
- /**
- * Creates a Runner based only on the given properties.
- */
- public static Runner create(String command, Properties globalProperties, Properties projectProperties) {
- return new Runner(command, globalProperties, projectProperties);
- }
-
- /**
- * Creates a Runner based only on the properties and with the given base directory.
- * @deprecated Use {@link Runner#create(String, Properties, Properties, File)}
- */
- @Deprecated
- public static Runner create(Properties props, File basedir) {
- return create(null, new Properties(), props, basedir);
- }
-
- /**
- * Creates a Runner based only on the properties and with the given base directory.
- */
- public static Runner create(String command, Properties globalProperties, Properties projectProperties, File basedir) {
- projectProperties.put(PROPERTY_SONAR_PROJECT_BASEDIR, basedir.getAbsolutePath());
- return new Runner(command, globalProperties, projectProperties);
- }
-
- /**
- * Runs a Sonar analysis.
- */
- public void execute() {
- Bootstrapper bootstrapper = new Bootstrapper("SonarRunner/" + Version.getVersion(), getSonarServerURL(), getWorkDir());
- checkSonarVersion(bootstrapper);
- delegateExecution(createClassLoader(bootstrapper));
- }
-
- public String getSonarServerURL() {
- return projectProperties.getProperty("sonar.host.url", globalProperties.getProperty("sonar.host.url", "http://localhost:9000"));
- }
-
- private void initDirs() {
- String path = projectProperties.getProperty(PROPERTY_SONAR_PROJECT_BASEDIR, ".");
- projectDir = new File(path);
- if (!projectDir.isDirectory()) {
- throw new RunnerException("Project home must be an existing directory: " + path);
- }
- // project home exists: add its absolute path as "sonar.projectBaseDir" property
- projectProperties.put(PROPERTY_SONAR_PROJECT_BASEDIR, projectDir.getAbsolutePath());
- workDir = initWorkDir();
- }
-
- private File initWorkDir() {
- File newWorkDir;
- String customWorkDir = projectProperties.getProperty(PROPERTY_WORK_DIRECTORY, globalProperties.getProperty(PROPERTY_WORK_DIRECTORY));
- if (customWorkDir == null || "".equals(customWorkDir.trim())) {
- newWorkDir = new File(getProjectDir(), DEF_VALUE_WORK_DIRECTORY);
- }
- else {
- newWorkDir = defineCustomizedWorkDir(new File(customWorkDir));
- }
- IOUtils.deleteQuietly(newWorkDir);
- return newWorkDir;
- }
-
- private File defineCustomizedWorkDir(File customWorkDir) {
- if (customWorkDir.isAbsolute()) {
- return customWorkDir;
- }
- return new File(getProjectDir(), customWorkDir.getPath());
- }
-
- /**
- * @return the project base directory
- */
- public File getProjectDir() {
- return projectDir;
- }
-
- /**
- * @return work directory, default is ".sonar" in project directory
- */
- public File getWorkDir() {
- return workDir;
- }
-
- /**
- * @return the source code encoding that will be used by Sonar
- */
- public String getSourceCodeEncoding() {
- return projectProperties.getProperty(PROPERTY_SOURCE_ENCODING, globalProperties.getProperty(PROPERTY_SOURCE_ENCODING));
- }
-
- /**
- * @return true if the property "sonar.sourceEncoding" hasn't been forced
- */
- public boolean isEncodingPlatformDependant() {
- return isEncodingPlatformDependant;
- }
-
- public String getCommand() {
- return command;
- }
-
- /**
- * @return global properties, project properties and command-line properties
- */
- @VisibleForTesting
- public Properties getProperties() {
- Properties props = new Properties();
- props.putAll(globalProperties);
- props.putAll(projectProperties);
- return props;
- }
-
- protected void checkSonarVersion(Bootstrapper bootstrapper) {
- String serverVersion = bootstrapper.getServerVersion();
- if (isUnsupportedVersion(serverVersion)) {
- throw new RunnerException("Sonar " + serverVersion
- + " is not supported. Please upgrade Sonar to version 2.11 or more.");
- }
- if (command != null && isUnsupportedVersionForTasks(serverVersion)) {
- throw new RunnerException("Sonar " + serverVersion
- + " doesn't support tasks. Please upgrade Sonar to version 3.5 or more.");
- }
- }
-
- private BootstrapClassLoader createClassLoader(Bootstrapper bootstrapper) {
- URL url = getJarPath();
- return bootstrapper.createClassLoader(
- // Add JAR with Sonar Runner - it's a Jar which contains this class
- new URL[] {url},
- getClass().getClassLoader(),
- unmaskedPackages);
- }
-
- /**
- * For unknown reasons <code>getClass().getProtectionDomain().getCodeSource().getLocation()</code> doesn't work under Ant 1.7.0.
- * So this is a workaround.
- *
- * @return Jar which contains this class
- */
- public static URL getJarPath() {
- String pathToClass = "/" + Runner.class.getName().replace('.', '/') + ".class";
- URL url = Runner.class.getResource(pathToClass);
- if (url != null) {
- String path = url.toString();
- String uri = null;
- if (path.startsWith("jar:file:")) {
- int bang = path.indexOf('!');
- uri = path.substring(4, bang);
- } else if (path.startsWith("file:")) {
- int tail = path.indexOf(pathToClass);
- uri = path.substring(0, tail);
- }
- if (uri != null) {
- try {
- return new URL(uri);
- } catch (MalformedURLException e) {
- }
- }
- }
- return null;
- }
-
- static boolean isUnsupportedVersion(String version) {
- for (String unsupportedVersion : UNSUPPORTED_VERSIONS) {
- if (isVersion(version, unsupportedVersion)) {
- return true;
- }
- }
- return false;
- }
-
- static boolean isUnsupportedVersionForTasks(String version) {
- for (String unsupportedVersion : UNSUPPORTED_VERSIONS_FOR_TASKS) {
- if (isVersion(version, unsupportedVersion)) {
- return true;
- }
- }
- return false;
- }
-
- static boolean isVersion(String version, String prefix) {
- return version.startsWith(prefix + ".") || version.equals(prefix);
- }
-
- private void delegateExecution(BootstrapClassLoader sonarClassLoader) {
- ClassLoader oldContextClassLoader = Thread.currentThread().getContextClassLoader();
- try {
- Thread.currentThread().setContextClassLoader(sonarClassLoader);
- Class<?> launcherClass = sonarClassLoader.findClass("org.sonar.runner.internal.batch.Launcher");
- Constructor<?> constructor = launcherClass.getConstructor(String.class, Properties.class, Properties.class, List.class);
- Object launcher = constructor.newInstance(getCommand(), globalProperties, projectProperties, containerExtensions);
- Method method = launcherClass.getMethod("execute");
- method.invoke(launcher);
- } catch (InvocationTargetException e) {
- // Unwrap original exception
- throw new RunnerException("Unable to execute Sonar", e.getTargetException());
- } catch (Exception e) {
- // Catch all other exceptions, which relates to reflection
- throw new RunnerException("Unable to execute Sonar", e);
- } finally {
- Thread.currentThread().setContextClassLoader(oldContextClassLoader);
- }
- }
-
- /**
- * Allows to overwrite the environment information when Sonar Runner is embedded in a specific tool (for instance, with the Sonar Ant Task).
- *
- * @param key the key of the tool that embeds Sonar Runner
- * @param version the version of this tool
- */
- public void setEnvironmentInformation(String key, String version) {
- this.globalProperties.put(PROPERTY_ENVIRONMENT_INFORMATION_KEY, key);
- this.globalProperties.put(PROPERTY_ENVIRONMENT_INFORMATION_VERSION, version);
- }
-
- public void setUnmaskedPackages(String... unmaskedPackages) {
- this.unmaskedPackages = unmaskedPackages;
- }
-
- public void addContainerExtension(Object extension) {
- containerExtensions.add(extension);
- }
-
-}
diff --git a/src/main/java/org/sonar/runner/RunnerException.java b/src/main/java/org/sonar/runner/RunnerException.java
deleted file mode 100644
index 27ffffb..0000000
--- a/src/main/java/org/sonar/runner/RunnerException.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Sonar Runner
- * Copyright (C) 2011 SonarSource
- * dev@sonar.codehaus.org
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
- */
-package org.sonar.runner;
-
-/**
- * Exception thrown by the Sonar Runner when something bad happens.
- *
- * @since 1.2
- */
-public class RunnerException extends RuntimeException {
-
- private static final long serialVersionUID = 4810407777585753030L;
-
- /**
- * See {@link RuntimeException}
- */
- public RunnerException(String message) {
- super(message);
- }
-
- /**
- * See {@link RuntimeException}
- */
- public RunnerException(Throwable cause) {
- super(cause);
- }
-
- /**
- * See {@link RuntimeException}
- */
- public RunnerException(String message, Throwable cause) {
- super(message, cause);
- }
-
-}
diff --git a/src/main/java/org/sonar/runner/Stats.java b/src/main/java/org/sonar/runner/Stats.java
deleted file mode 100644
index fdec553..0000000
--- a/src/main/java/org/sonar/runner/Stats.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Sonar Runner
- * Copyright (C) 2011 SonarSource
- * dev@sonar.codehaus.org
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
- */
-package org.sonar.runner;
-
-class Stats {
- private long startTime;
-
- Stats() {
- }
-
- Stats start() {
- startTime = System.currentTimeMillis();
- return this;
- }
-
- Stats stop() {
- long stopTime = System.currentTimeMillis() - startTime;
- Logs.info("Total time: " + formatTime(stopTime));
-
- System.gc();
- Runtime r = Runtime.getRuntime();
- long mb = 1024L * 1024;
- Logs.info("Final Memory: " + (r.totalMemory() - r.freeMemory()) / mb + "M/" + r.totalMemory() / mb + "M");
-
- return this;
- }
-
- static String formatTime(long time) {
- long h = time / (60 * 60 * 1000);
- long m = (time - h * 60 * 60 * 1000) / (60 * 1000);
- long s = (time - h * 60 * 60 * 1000 - m * 60 * 1000) / 1000;
- long ms = time % 1000;
- final String format;
- if (h > 0) {
- format = "%1$d:%2$02d:%3$02d.%4$03ds";
- } else if (m > 0) {
- format = "%2$d:%3$02d.%4$03ds";
- } else {
- format = "%3$d.%4$03ds";
- }
- return String.format(format, h, m, s, ms);
- }
-}
diff --git a/src/main/java/org/sonar/runner/Version.java b/src/main/java/org/sonar/runner/Version.java
deleted file mode 100644
index 313d727..0000000
--- a/src/main/java/org/sonar/runner/Version.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Sonar Runner
- * Copyright (C) 2011 SonarSource
- * dev@sonar.codehaus.org
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
- */
-package org.sonar.runner;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Properties;
-
-public enum Version {
-
- INSTANCE;
-
- private static final String PROPERTIES_PATH = "/org/sonar/runner/version.txt";
- private String version;
-
- public static String getVersion() {
- return INSTANCE.version;
- }
-
- private Version() {
- InputStream input = getClass().getResourceAsStream(PROPERTIES_PATH);
- try {
- Properties properties = new Properties();
- properties.load(input);
- this.version = properties.getProperty("version");
-
- } catch (IOException e) {
- // Can not load the version
- this.version = "";
-
- } finally {
- IOUtils.closeQuietly(input);
- }
- }
-}
diff --git a/src/main/java/org/sonar/runner/internal/batch/Launcher.java b/src/main/java/org/sonar/runner/internal/batch/Launcher.java
deleted file mode 100644
index 1aebbd9..0000000
--- a/src/main/java/org/sonar/runner/internal/batch/Launcher.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Sonar Runner
- * Copyright (C) 2011 SonarSource
- * dev@sonar.codehaus.org
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
- */
-package org.sonar.runner.internal.batch;
-
-import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.joran.JoranConfigurator;
-import ch.qos.logback.core.joran.spi.JoranException;
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.Maps;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang.StringUtils;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.batch.bootstrap.ProjectDefinition;
-import org.sonar.api.batch.bootstrap.ProjectReactor;
-import org.sonar.api.utils.SonarException;
-import org.sonar.batch.bootstrapper.Batch;
-import org.sonar.batch.bootstrapper.EnvironmentInformation;
-import org.sonar.runner.Runner;
-
-import java.io.InputStream;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-
-/**
- * Contrary to {@link org.sonar.runner.Runner}, this class is executed within the classloader
- * provided by the server. It contains the installed plugins and the same version of sonar-batch as the server.
- */
-public class Launcher {
-
- private String command;
- private Properties globalProperties;
- private Properties projectProperties;
- private List<Object> containerExtensions;
-
- /**
- * @deprecated Use {@link Launcher#Launcher(String, Properties, Properties, List)} instead
- */
- @Deprecated
- public Launcher(Properties properties, List<Object> containerExtensions) {
- this("project-analysis", new Properties(), properties, containerExtensions);
- }
-
- public Launcher(String command, Properties globalProperties, Properties projectProperties, List<Object> containerExtensions) {
- this.command = command;
- this.globalProperties = globalProperties;
- this.projectProperties = projectProperties;
- this.containerExtensions = containerExtensions;
- }
-
- /**
- * Main entry point.
- */
- public void execute() {
- Properties globalConfiguration = getInitialConfiguration();
- globalConfiguration.putAll(globalProperties);
- initLogging(globalConfiguration);
-
- Properties projectConfiguration = new Properties();
- projectConfiguration.putAll(globalConfiguration);
- projectConfiguration.putAll(projectProperties);
- ProjectDefinition project = SonarProjectBuilder.create(command, projectConfiguration).generateProjectDefinition();
-
- executeBatch(globalConfiguration, project);
- }
-
- private void executeBatch(Properties globalConfiguration, ProjectDefinition project) {
- String envKey = globalProperties.getProperty(Runner.PROPERTY_ENVIRONMENT_INFORMATION_KEY);
- String envVersion = globalProperties.getProperty(Runner.PROPERTY_ENVIRONMENT_INFORMATION_VERSION);
- Batch.Builder builder = Batch.builder()
- .setEnvironment(new EnvironmentInformation(envKey, envVersion));
- for (Object extension : containerExtensions) {
- builder.addComponent(extension);
- }
- if (project != null) {
- builder.setProjectReactor(new ProjectReactor(project));
- }
- if (StringUtils.isNotBlank(command)) {
- // This code can only works on Sonar 3.5+
- builder
- .setGlobalProperties(toMap(globalConfiguration))
- .setTaskCommand(command);
- }
- Batch batch = builder.build();
- batch.execute();
- }
-
- private Map<String, String> toMap(Properties props) {
- Map<String, String> result = Maps.newHashMap();
- for (Map.Entry<Object, Object> entry : props.entrySet()) {
- result.put(entry.getKey().toString(), entry.getValue().toString());
- }
- return result;
- }
-
- private void initLogging(Properties props) {
- LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
- JoranConfigurator jc = new JoranConfigurator();
- jc.setContext(context);
- context.reset();
- InputStream input = Batch.class.getResourceAsStream("/org/sonar/batch/logback.xml");
- System.setProperty("ROOT_LOGGER_LEVEL", isDebug() ? "DEBUG" : "INFO");
- context.putProperty("SQL_LOGGER_LEVEL", getSqlLevel(props));
- context.putProperty("SQL_RESULTS_LOGGER_LEVEL", getSqlResultsLevel(props));
- try {
- jc.doConfigure(input);
-
- } catch (JoranException e) {
- throw new SonarException("can not initialize logging", e);
-
- } finally {
- IOUtils.closeQuietly(input);
- }
- }
-
- @VisibleForTesting
- protected boolean isDebug() {
- return Boolean.parseBoolean(projectProperties.getProperty(Runner.PROPERTY_VERBOSE, projectProperties.getProperty(Runner.PROPERTY_OLD_DEBUG_MODE, "false")));
- }
-
- @VisibleForTesting
- protected static String getSqlLevel(Properties props) {
- boolean showSql = "true".equals(props.get("sonar.showSql"));
- return showSql ? "DEBUG" : "WARN";
- }
-
- @VisibleForTesting
- protected static String getSqlResultsLevel(Properties props) {
- boolean showSql = "true".equals(props.get("sonar.showSqlResults"));
- return showSql ? "DEBUG" : "WARN";
- }
-
- private Properties getInitialConfiguration() {
- Properties props = new Properties();
- props.putAll(System.getProperties());
- props.putAll(System.getenv());
- return props;
- }
-
-}
diff --git a/src/main/java/org/sonar/runner/internal/batch/SonarProjectBuilder.java b/src/main/java/org/sonar/runner/internal/batch/SonarProjectBuilder.java
deleted file mode 100644
index 84b8788..0000000
--- a/src/main/java/org/sonar/runner/internal/batch/SonarProjectBuilder.java
+++ /dev/null
@@ -1,546 +0,0 @@
-/*
- * Sonar Runner
- * Copyright (C) 2011 SonarSource
- * dev@sonar.codehaus.org
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
- */
-package org.sonar.runner.internal.batch;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.Lists;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.io.filefilter.AndFileFilter;
-import org.apache.commons.io.filefilter.FileFileFilter;
-import org.apache.commons.io.filefilter.WildcardFileFilter;
-import org.apache.commons.lang.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.batch.bootstrap.ProjectDefinition;
-import org.sonar.runner.RunnerException;
-
-import java.io.File;
-import java.io.FileFilter;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Properties;
-
-/**
- * Class that creates a Sonar project definition based on a set of properties.
- *
- * @since 1.5
- */
-public final class SonarProjectBuilder {
-
- private static final Logger LOG = LoggerFactory.getLogger(SonarProjectBuilder.class);
-
- private static final String PROPERTY_PROJECT_BASEDIR = "sonar.projectBaseDir";
- private static final String PROPERTY_PROJECT_CONFIG_FILE = "sonar.projectConfigFile";
- private static final String PROPERTY_PROJECT_KEY = "sonar.projectKey";
- private static final String PROPERTY_PROJECT_NAME = "sonar.projectName";
- private static final String PROPERTY_PROJECT_DESCRIPTION = "sonar.projectDescription";
- private static final String PROPERTY_PROJECT_VERSION = "sonar.projectVersion";
- private static final String PROPERTY_MODULES = "sonar.modules";
-
- /**
- * New properties, to be consistent with Sonar naming conventions
- * @since 1.5
- */
- private static final String PROPERTY_SOURCES = "sonar.sources";
- private static final String PROPERTY_TESTS = "sonar.tests";
- private static final String PROPERTY_BINARIES = "sonar.binaries";
- private static final String PROPERTY_LIBRARIES = "sonar.libraries";
-
- /**
- * Old deprecated properties, replaced by the same ones preceded by "sonar."
- */
- private static final String PROPERTY_OLD_SOURCES = "sources";
- private static final String PROPERTY_OLD_TESTS = "tests";
- private static final String PROPERTY_OLD_BINARIES = "binaries";
- private static final String PROPERTY_OLD_LIBRARIES = "libraries";
- private static final Map<String, String> DEPRECATED_PROPS_TO_NEW_PROPS = new HashMap<String, String>() {
- {
- put(PROPERTY_OLD_SOURCES, PROPERTY_SOURCES);
- put(PROPERTY_OLD_TESTS, PROPERTY_TESTS);
- put(PROPERTY_OLD_BINARIES, PROPERTY_BINARIES);
- put(PROPERTY_OLD_LIBRARIES, PROPERTY_LIBRARIES);
- }
- };
-
- /**
- * @since 1.4
- */
- private static final String PROPERTY_WORK_DIRECTORY = "sonar.working.directory";
- private static final String DEF_VALUE_WORK_DIRECTORY = ".sonar";
-
- /**
- * Array of all mandatory properties required for a project without child.
- */
- private static final String[] MANDATORY_PROPERTIES_FOR_SIMPLE_PROJECT = {PROPERTY_PROJECT_BASEDIR, PROPERTY_PROJECT_KEY, PROPERTY_PROJECT_NAME, PROPERTY_PROJECT_VERSION,
- PROPERTY_SOURCES};
-
- /**
- * Array of all mandatory properties required for a project with children.
- */
- private static final String[] MANDATORY_PROPERTIES_FOR_MULTIMODULE_PROJECT = {PROPERTY_PROJECT_BASEDIR, PROPERTY_PROJECT_KEY, PROPERTY_PROJECT_NAME, PROPERTY_PROJECT_VERSION};
-
- /**
- * Array of all mandatory properties required for a child project before its properties get merged with its parent ones.
- */
- private static final String[] MANDATORY_PROPERTIES_FOR_CHILD = {PROPERTY_PROJECT_KEY, PROPERTY_PROJECT_NAME};
-
- /**
- * Properties that must not be passed from the parent project to its children.
- */
- private static final List<String> NON_HERITED_PROPERTIES_FOR_CHILD = Lists.newArrayList(PROPERTY_PROJECT_BASEDIR, PROPERTY_MODULES, PROPERTY_PROJECT_DESCRIPTION);
-
- private String command;
- private Properties properties;
- private File rootProjectWorkDir;
-
- private SonarProjectBuilder(String command, Properties properties) {
- this.command = command;
- this.properties = properties;
- }
-
- public static SonarProjectBuilder create(Properties properties) {
- return create(null, properties);
- }
-
- public static SonarProjectBuilder create(String command, Properties properties) {
- return new SonarProjectBuilder(command, properties);
- }
-
- public ProjectDefinition generateProjectDefinition() {
- if (StringUtils.isBlank(command) || "inspect".equals(command)) {
- ProjectDefinition rootProject = defineProject(properties, null);
- rootProjectWorkDir = rootProject.getWorkDir();
- defineChildren(rootProject);
- cleanAndCheckProjectDefinitions(rootProject);
- return rootProject;
- }
- else if (properties.containsKey(PROPERTY_PROJECT_KEY)) {
- return defineTaskContext();
- }
- else {
- return null;
- }
- }
-
- private ProjectDefinition defineTaskContext() {
- File baseDir = new File(System.getProperty("user.home"));
- File workDir = initRootProjectWorkDir(baseDir);
-
- ProjectDefinition definition = ProjectDefinition.create().setProperties(properties)
- .setBaseDir(baseDir)
- .setWorkDir(workDir);
- return definition;
- }
-
- private ProjectDefinition defineProject(Properties properties, ProjectDefinition parent) {
- if (properties.containsKey(PROPERTY_MODULES)) {
- checkMandatoryProperties(properties, MANDATORY_PROPERTIES_FOR_MULTIMODULE_PROJECT);
- }
- else {
- checkMandatoryProperties(properties, MANDATORY_PROPERTIES_FOR_SIMPLE_PROJECT);
- }
- File baseDir = new File(properties.getProperty(PROPERTY_PROJECT_BASEDIR));
- File workDir = null;
- if (parent == null) {
- workDir = initRootProjectWorkDir(baseDir);
- } else {
- workDir = initModuleWorkDir(properties);
- }
-
- ProjectDefinition definition = ProjectDefinition.create().setProperties(properties)
- .setBaseDir(baseDir)
- .setWorkDir(workDir);
- return definition;
- }
-
- @VisibleForTesting
- protected File initRootProjectWorkDir(File baseDir) {
- String workDir = properties.getProperty(PROPERTY_WORK_DIRECTORY);
- if (StringUtils.isBlank(workDir)) {
- return new File(baseDir, DEF_VALUE_WORK_DIRECTORY);
- }
-
- File customWorkDir = new File(workDir);
- if (customWorkDir.isAbsolute()) {
- return customWorkDir;
- }
- return new File(baseDir, customWorkDir.getPath());
- }
-
- @VisibleForTesting
- protected File initModuleWorkDir(Properties properties) {
- String cleanKey = StringUtils.deleteWhitespace(properties.getProperty(PROPERTY_PROJECT_KEY));
- cleanKey = StringUtils.replace(cleanKey, ":", "_");
- return new File(rootProjectWorkDir, cleanKey);
- }
-
- private void defineChildren(ProjectDefinition parentProject) {
- Properties parentProps = parentProject.getProperties();
- if (parentProps.containsKey(PROPERTY_MODULES)) {
- for (String module : SonarRunnerUtils.getListFromProperty(parentProps, PROPERTY_MODULES)) {
- Properties moduleProps = extractModuleProperties(module, parentProps);
- ProjectDefinition childProject = loadChildProject(parentProject, moduleProps, module);
- // check the uniqueness of the child key
- checkUniquenessOfChildKey(childProject, parentProject);
- // the child project may have children as well
- defineChildren(childProject);
- // and finally add this child project to its parent
- parentProject.addSubProject(childProject);
- }
- }
- }
-
- private ProjectDefinition loadChildProject(ProjectDefinition parentProject, Properties moduleProps, String moduleId) {
- setProjectKeyAndNameIfNotDefined(moduleProps, moduleId);
-
- final File baseDir;
- if (moduleProps.containsKey(PROPERTY_PROJECT_BASEDIR)) {
- baseDir = getFileFromPath(moduleProps.getProperty(PROPERTY_PROJECT_BASEDIR), parentProject.getBaseDir());
- setProjectBaseDir(baseDir, moduleProps, moduleId);
- try {
- if (!parentProject.getBaseDir().getCanonicalFile().equals(baseDir.getCanonicalFile())) {
- tryToFindAndLoadPropsFile(baseDir, moduleProps, moduleId);
- }
- } catch (IOException e) {
- throw new RunnerException("Error when resolving baseDir", e);
- }
- } else if (moduleProps.containsKey(PROPERTY_PROJECT_CONFIG_FILE)) {
- baseDir = loadPropsFile(parentProject, moduleProps, moduleId);
- } else {
- baseDir = new File(parentProject.getBaseDir(), moduleId);
- setProjectBaseDir(baseDir, moduleProps, moduleId);
- tryToFindAndLoadPropsFile(baseDir, moduleProps, moduleId);
- }
-
- // and finish
- checkMandatoryProperties(moduleProps, MANDATORY_PROPERTIES_FOR_CHILD);
- if (!moduleProps.containsKey(PROPERTY_MODULES)) {
- // SONARPLUGINS-2285 Not an aggreator project so we can validate that paths are correct if defined
-
- // We need to resolve patterns that may have been used in "sonar.libraries"
- for (String pattern : SonarRunnerUtils.getListFromProperty(moduleProps, PROPERTY_LIBRARIES)) {
- File[] files = getLibraries(baseDir, pattern);
- if (files == null || files.length == 0) {
- LOG.error("Invalid value of " + PROPERTY_LIBRARIES + " for module " + moduleId);
- throw new RunnerException("No files matching pattern \"" + pattern + "\" in directory \"" + baseDir + "\"");
- }
- }
-
- // Check sonar.tests
- String[] testDirs = SonarRunnerUtils.getListFromProperty(moduleProps, PROPERTY_TESTS);
- checkExistenceOfDirectories(moduleId, baseDir, testDirs, PROPERTY_TESTS);
-
- // Check sonar.binaries
- String[] binDirs = SonarRunnerUtils.getListFromProperty(moduleProps, PROPERTY_BINARIES);
- checkExistenceOfDirectories(moduleId, baseDir, binDirs, PROPERTY_BINARIES);
- }
- mergeParentProperties(moduleProps, parentProject.getProperties());
-
- prefixProjectKeyWithParentKey(moduleProps, parentProject.getKey());
-
- return defineProject(moduleProps, parentProject);
- }
-
- /**
- * @return baseDir
- */
- protected File loadPropsFile(ProjectDefinition parentProject, Properties moduleProps, String moduleId) {
- File propertyFile = getFileFromPath(moduleProps.getProperty(PROPERTY_PROJECT_CONFIG_FILE), parentProject.getBaseDir());
- if (propertyFile.isFile()) {
- Properties propsFromFile = toProperties(propertyFile);
- for (Entry<Object, Object> entry : propsFromFile.entrySet()) {
- moduleProps.put(entry.getKey(), entry.getValue());
- }
- File baseDir = null;
- if (moduleProps.containsKey(PROPERTY_PROJECT_BASEDIR)) {
- baseDir = getFileFromPath(moduleProps.getProperty(PROPERTY_PROJECT_BASEDIR), propertyFile.getParentFile());
- } else {
- baseDir = propertyFile.getParentFile();
- }
- setProjectBaseDir(baseDir, moduleProps, moduleId);
- return baseDir;
- } else {
- throw new RunnerException("The properties file of the module '" + moduleId + "' does not exist: " + propertyFile.getAbsolutePath());
- }
- }
-
- private void tryToFindAndLoadPropsFile(File baseDir, Properties moduleProps, String moduleId) {
- File propertyFile = new File(baseDir, "sonar-project.properties");
- if (propertyFile.isFile()) {
- Properties propsFromFile = toProperties(propertyFile);
- for (Entry<Object, Object> entry : propsFromFile.entrySet()) {
- moduleProps.put(entry.getKey(), entry.getValue());
- }
- if (moduleProps.containsKey(PROPERTY_PROJECT_BASEDIR)) {
- File overwrittenBaseDir = getFileFromPath(moduleProps.getProperty(PROPERTY_PROJECT_BASEDIR), propertyFile.getParentFile());
- setProjectBaseDir(overwrittenBaseDir, moduleProps, moduleId);
- }
- }
- }
-
- @VisibleForTesting
- protected static Properties toProperties(File propertyFile) {
- Properties propsFromFile = new Properties();
- FileInputStream fileInputStream = null;
- try {
- fileInputStream = new FileInputStream(propertyFile);
- propsFromFile.load(fileInputStream);
- } catch (IOException e) {
- throw new RunnerException("Impossible to read the property file: " + propertyFile.getAbsolutePath(), e);
- } finally {
- IOUtils.closeQuietly(fileInputStream);
- }
- return propsFromFile;
- }
-
- @VisibleForTesting
- protected static void setProjectKeyAndNameIfNotDefined(Properties childProps, String moduleId) {
- if (!childProps.containsKey(PROPERTY_PROJECT_KEY)) {
- childProps.put(PROPERTY_PROJECT_KEY, moduleId);
- }
- if (!childProps.containsKey(PROPERTY_PROJECT_NAME)) {
- childProps.put(PROPERTY_PROJECT_NAME, moduleId);
- }
- }
-
- @VisibleForTesting
- protected static void checkUniquenessOfChildKey(ProjectDefinition childProject, ProjectDefinition parentProject) {
- for (ProjectDefinition definition : parentProject.getSubProjects()) {
- if (definition.getKey().equals(childProject.getKey())) {
- throw new RunnerException("Project '" + parentProject.getKey() + "' can't have 2 modules with the following key: " + childProject.getKey());
- }
- }
- }
-
- @VisibleForTesting
- protected static void prefixProjectKeyWithParentKey(Properties childProps, String parentKey) {
- String childKey = childProps.getProperty(PROPERTY_PROJECT_KEY);
- childProps.put(PROPERTY_PROJECT_KEY, parentKey + ":" + childKey);
- }
-
- private static void setProjectBaseDir(File baseDir, Properties childProps, String moduleId) {
- if (!baseDir.isDirectory()) {
- throw new RunnerException("The base directory of the module '" + moduleId + "' does not exist: " + baseDir.getAbsolutePath());
- }
- childProps.put(PROPERTY_PROJECT_BASEDIR, baseDir.getAbsolutePath());
- }
-
- @VisibleForTesting
- protected static void checkMandatoryProperties(Properties props, String[] mandatoryProps) {
- replaceDeprecatedProperties(props);
- StringBuilder missing = new StringBuilder();
- for (String mandatoryProperty : mandatoryProps) {
- if (!props.containsKey(mandatoryProperty)) {
- if (missing.length() > 0) {
- missing.append(", ");
- }
- missing.append(mandatoryProperty);
- }
- }
- if (missing.length() != 0) {
- String projectKey = props.getProperty(PROPERTY_PROJECT_KEY);
- throw new RunnerException("You must define the following mandatory properties for '" + (projectKey == null ? "Unknown" : projectKey) + "': " + missing);
- }
- }
-
- @VisibleForTesting
- protected static void cleanAndCheckProjectDefinitions(ProjectDefinition project) {
- if (project.getSubProjects().isEmpty()) {
- cleanAndCheckModuleProperties(project);
- } else {
- cleanAndCheckAggregatorProjectProperties(project);
-
- // clean modules properties as well
- for (ProjectDefinition module : project.getSubProjects()) {
- cleanAndCheckProjectDefinitions(module);
- }
- }
- }
-
- @VisibleForTesting
- protected static void cleanAndCheckModuleProperties(ProjectDefinition project) {
- Properties properties = project.getProperties();
-
- // We need to check the existence of source directories
- String[] sourceDirs = SonarRunnerUtils.getListFromProperty(properties, PROPERTY_SOURCES);
- checkExistenceOfDirectories(project.getKey(), project.getBaseDir(), sourceDirs, PROPERTY_SOURCES);
-
- // And we need to resolve patterns that may have been used in "sonar.libraries"
- List<String> libPaths = Lists.newArrayList();
- for (String pattern : SonarRunnerUtils.getListFromProperty(properties, PROPERTY_LIBRARIES)) {
- for (File file : getLibraries(project.getBaseDir(), pattern)) {
- libPaths.add(file.getAbsolutePath());
- }
- }
- properties.remove(PROPERTY_LIBRARIES);
- properties.put(PROPERTY_LIBRARIES, StringUtils.join(libPaths, ","));
- }
-
- @VisibleForTesting
- protected static void cleanAndCheckAggregatorProjectProperties(ProjectDefinition project) {
- Properties properties = project.getProperties();
-
- // SONARPLUGINS-2295
- String[] sourceDirs = SonarRunnerUtils.getListFromProperty(properties, PROPERTY_SOURCES);
- for (String path : sourceDirs) {
- File sourceFolder = getFileFromPath(path, project.getBaseDir());
- if (sourceFolder.isDirectory()) {
- LOG.warn("/!\\ A multi-module project can't have source folders, so '{}' won't be used for the analysis. " +
- "If you want to analyse files of this folder, you should create another sub-module and move them inside it.",
- sourceFolder.toString());
- }
- }
-
- // "aggregator" project must not have the following properties:
- properties.remove(PROPERTY_SOURCES);
- properties.remove(PROPERTY_TESTS);
- properties.remove(PROPERTY_BINARIES);
- properties.remove(PROPERTY_LIBRARIES);
-
- // and they don't need properties related to their modules either
- Properties clone = (Properties) properties.clone();
- List<String> moduleIds = Lists.newArrayList(SonarRunnerUtils.getListFromProperty(properties, PROPERTY_MODULES));
- for (Entry<Object, Object> entry : clone.entrySet()) {
- String key = (String) entry.getKey();
- if (isKeyPrefixedByModuleId(key, moduleIds)) {
- properties.remove(key);
- }
- }
- }
-
- /**
- * Replaces the deprecated properties by the new ones, and logs a message to warn the users.
- */
- @VisibleForTesting
- protected static void replaceDeprecatedProperties(Properties props) {
- for (Entry<String, String> entry : DEPRECATED_PROPS_TO_NEW_PROPS.entrySet()) {
- String key = entry.getKey();
- if (props.containsKey(key)) {
- String newKey = entry.getValue();
- LOG.warn("/!\\ The '{}' property is deprecated and is replaced by '{}'. Don't forget to update your files.", key, newKey);
- String value = props.getProperty(key);
- props.remove(key);
- props.put(newKey, value);
- }
- }
-
- }
-
- @VisibleForTesting
- protected static void mergeParentProperties(Properties childProps, Properties parentProps) {
- List<String> moduleIds = Lists.newArrayList(SonarRunnerUtils.getListFromProperty(parentProps, PROPERTY_MODULES));
- for (Map.Entry<Object, Object> entry : parentProps.entrySet()) {
- String key = (String) entry.getKey();
- if (!childProps.containsKey(key)
- && !NON_HERITED_PROPERTIES_FOR_CHILD.contains(key)
- && !isKeyPrefixedByModuleId(key, moduleIds)) {
- childProps.put(entry.getKey(), entry.getValue());
- }
- }
- }
-
- private static boolean isKeyPrefixedByModuleId(String key, List<String> moduleIds) {
- for (String moduleId : moduleIds) {
- if (key.startsWith(moduleId + ".")) {
- return true;
- }
- }
- return false;
- }
-
- @VisibleForTesting
- protected static Properties extractModuleProperties(String module, Properties properties) {
- Properties moduleProps = new Properties();
- String propertyPrefix = module + ".";
- int prefixLength = propertyPrefix.length();
- for (Map.Entry<Object, Object> entry : properties.entrySet()) {
- String key = (String) entry.getKey();
- if (key.startsWith(propertyPrefix)) {
- moduleProps.put(key.substring(prefixLength), entry.getValue());
- }
- }
- return moduleProps;
- }
-
- @VisibleForTesting
- protected static void checkExistenceOfDirectories(String moduleRef, File baseDir, String[] sourceDirs, String propName) {
- for (String path : sourceDirs) {
- File sourceFolder = getFileFromPath(path, baseDir);
- if (!sourceFolder.isDirectory()) {
- LOG.error("Invalid value of " + propName + " for " + moduleRef);
- throw new RunnerException("The folder '" + path + "' does not exist for '" + moduleRef +
- "' (base directory = " + baseDir.getAbsolutePath() + ")");
- }
- }
-
- }
-
- /**
- * Returns files matching specified pattern.
- */
- @VisibleForTesting
- protected static File[] getLibraries(File baseDir, String pattern) {
- final int i = Math.max(pattern.lastIndexOf('/'), pattern.lastIndexOf('\\'));
- final String dirPath, filePattern;
- if (i == -1) {
- dirPath = ".";
- filePattern = pattern;
- } else {
- dirPath = pattern.substring(0, i);
- filePattern = pattern.substring(i + 1);
- }
- FileFilter fileFilter = new AndFileFilter(FileFileFilter.FILE, new WildcardFileFilter(filePattern));
- File dir = resolvePath(baseDir, dirPath);
- File[] files = dir.listFiles(fileFilter);
- if (files == null) {
- files = new File[0];
- }
- return files;
- }
-
- private static File resolvePath(File baseDir, String path) {
- File file = new File(path);
- if (!file.isAbsolute()) {
- try {
- file = new File(baseDir, path).getCanonicalFile();
- } catch (IOException e) {
- throw new RunnerException("Unable to resolve path \"" + path + "\"", e);
- }
- }
- return file;
- }
-
- /**
- * Returns the file denoted by the given path, may this path be relative to "baseDir" or absolute.
- */
- @VisibleForTesting
- protected static File getFileFromPath(String path, File baseDir) {
- File propertyFile = new File(path.trim());
- if (!propertyFile.isAbsolute()) {
- propertyFile = new File(baseDir, propertyFile.getPath());
- }
- return propertyFile;
- }
-
-}
diff --git a/src/main/java/org/sonar/runner/internal/batch/SonarRunnerUtils.java b/src/main/java/org/sonar/runner/internal/batch/SonarRunnerUtils.java
deleted file mode 100644
index 64cd3b3..0000000
--- a/src/main/java/org/sonar/runner/internal/batch/SonarRunnerUtils.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Sonar Runner
- * Copyright (C) 2011 SonarSource
- * dev@sonar.codehaus.org
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
- */
-package org.sonar.runner.internal.batch;
-
-import org.apache.commons.lang.StringUtils;
-
-import java.util.Properties;
-
-/**
- * Public utility that can be used by consumers of the Sonar Runner.
- */
-public final class SonarRunnerUtils {
-
- private SonarRunnerUtils() {
- // only static methods
- }
-
- /**
- * Transforms a comma-separated list String property in to a array of trimmed strings.
- *
- * This works even if they are separated by whitespace characters (space char, EOL, ...)
- *
- */
- public static String[] getListFromProperty(Properties properties, String key) {
- return StringUtils.stripAll(StringUtils.split(properties.getProperty(key, ""), ','));
- }
-
-}
diff --git a/src/main/java/org/sonar/runner/internal/batch/package-info.java b/src/main/java/org/sonar/runner/internal/batch/package-info.java
deleted file mode 100644
index b06feba..0000000
--- a/src/main/java/org/sonar/runner/internal/batch/package-info.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Sonar Runner
- * Copyright (C) 2011 SonarSource
- * dev@sonar.codehaus.org
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
- */
-/**
- * Internal package that creates the project definition and launches the analyses based on it.
- * Should not be used by consumers.
- */
-package org.sonar.runner.internal.batch; \ No newline at end of file
diff --git a/src/main/java/org/sonar/runner/package-info.java b/src/main/java/org/sonar/runner/package-info.java
deleted file mode 100644
index 62e80e2..0000000
--- a/src/main/java/org/sonar/runner/package-info.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Sonar Runner
- * Copyright (C) 2011 SonarSource
- * dev@sonar.codehaus.org
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
- */
-/**
- * API package of the Sonar Runner.
- */
-package org.sonar.runner; \ No newline at end of file