aboutsummaryrefslogtreecommitdiffstats
path: root/src/main
diff options
context:
space:
mode:
authorEvgeny Mandrikov <mandrikov@gmail.com>2011-02-03 04:08:26 +0000
committerEvgeny Mandrikov <mandrikov@gmail.com>2011-02-03 04:08:26 +0000
commita0c622bc8666ccb0983fce374dfd01f03ca37703 (patch)
treea6c7e249db0dfe7fc871789daca65783b45a46e9 /src/main
parent3a838115d1275778b303029fbf6632976b5db58f (diff)
downloadsonar-scanner-cli-a0c622bc8666ccb0983fce374dfd01f03ca37703.tar.gz
sonar-scanner-cli-a0c622bc8666ccb0983fce374dfd01f03ca37703.zip
SONAR-RUNNER
Diffstat (limited to 'src/main')
-rwxr-xr-xsrc/main/assembly/bin/sonar-runner.sh27
-rw-r--r--src/main/assembly/conf/sonar-runner.properties17
-rw-r--r--src/main/java/org/sonar/cli/BootstrapLauncher.java99
-rw-r--r--src/main/java/org/sonar/cli/ChildFirstClassLoader.java75
-rw-r--r--src/main/java/org/sonar/runner/Launcher.java (renamed from src/main/java/org/sonar/cli/Launcher.java)64
-rw-r--r--src/main/java/org/sonar/runner/Main.java182
-rw-r--r--src/main/resources/org/sonar/runner/version.txt1
7 files changed, 255 insertions, 210 deletions
diff --git a/src/main/assembly/bin/sonar-runner.sh b/src/main/assembly/bin/sonar-runner.sh
new file mode 100755
index 0000000..abad57b
--- /dev/null
+++ b/src/main/assembly/bin/sonar-runner.sh
@@ -0,0 +1,27 @@
+#!/bin/sh
+#
+# Sonar Runner Startup Script for Unix
+#
+
+if [ -z "$SONAR_RUNNER_HOME" ] ; then
+ PRG="$0"
+
+ SONAR_RUNNER_HOME=`dirname "$PRG"`/..
+
+ # make it fully qualified
+ SONAR_RUNNER_HOME=`cd "$SONAR_RUNNER_HOME" && pwd`
+fi
+
+JAVACMD="`which java`"
+
+JAVACLASSPATH="${SONAR_RUNNER_HOME}"/lib/sonar-runner.jar
+JAVACLASSPATH=$JAVACLASSPATH:"${SONAR_RUNNER_HOME}"/lib/sonar-batch-bootstrapper.jar
+
+echo "Info: Using sonar-runner at $SONAR_RUNNER_HOME"
+echo "Info: Using java at $JAVACMD"
+echo "Info: Using classpath $JAVACLASSPATH"
+
+exec "$JAVACMD" \
+ -classpath $JAVACLASSPATH \
+ "-Drunner.home=${SONAR_RUNNER_HOME}" \
+ org.sonar.runner.Main "$@"
diff --git a/src/main/assembly/conf/sonar-runner.properties b/src/main/assembly/conf/sonar-runner.properties
new file mode 100644
index 0000000..58e14fd
--- /dev/null
+++ b/src/main/assembly/conf/sonar-runner.properties
@@ -0,0 +1,17 @@
+#sonar.host.url=http://localhost:9000
+
+#----- PostgreSQL
+#sonar.jdbc.url=jdbc:postgresql://localhost/sonar
+#sonar.jdbc.driver=org.postgresql.Driver
+
+#----- MySQL
+#sonar.jdbc.url=jdbc:mysql://localhost:3306/sonar?useUnicode=true&amp;characterEncoding=utf8
+#sonar.jdbc.driver=com.mysql.jdbc.Driver
+
+#----- Oracle
+#sonar.jdbc.url=jdbc:oracle:thin:@localhost/XE
+#sonar.jdbc.driver=oracle.jdbc.driver.OracleDriver
+
+#----- Global database settings
+#sonar.jdbc.username=sonar
+#sonar.jdbc.password=sonar
diff --git a/src/main/java/org/sonar/cli/BootstrapLauncher.java b/src/main/java/org/sonar/cli/BootstrapLauncher.java
deleted file mode 100644
index dabadcc..0000000
--- a/src/main/java/org/sonar/cli/BootstrapLauncher.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Sonar CLI
- * Copyright (C) 2009 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.cli;
-
-import org.sonar.batch.bootstrapper.BatchDownloader;
-
-import java.io.File;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.List;
-
-public class BootstrapLauncher {
-
- private static final String LAUNCHER_CLASS_NAME = "org.sonar.cli.Launcher";
-
- private String[] args;
-
- public static void main(String[] args) throws Exception {
- new BootstrapLauncher(args).bootstrap();
- }
-
- public BootstrapLauncher(String[] args) {
- this.args = args;
- }
-
- public void bootstrap() throws Exception {
- ClassLoader cl = getInitialClassLoader();
-
- Class launcherClass = cl.loadClass(LAUNCHER_CLASS_NAME);
-
- Method[] methods = launcherClass.getMethods();
- Method mainMethod = null;
-
- for (int i = 0; i < methods.length; ++i) {
- if (!("main".equals(methods[i].getName()))) {
- continue;
- }
-
- int modifiers = methods[i].getModifiers();
-
- if (!(Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
- continue;
- }
-
- if (methods[i].getReturnType() != Void.TYPE) {
- continue;
- }
-
- Class[] paramTypes = methods[i].getParameterTypes();
- if (paramTypes.length != 1) {
- continue;
- }
- if (paramTypes[0] != String[].class) {
- continue;
- }
- mainMethod = methods[i];
- break;
- }
-
- if (mainMethod == null) {
- throw new NoSuchMethodException(LAUNCHER_CLASS_NAME + ":main(String[] args)");
- }
-
- Thread.currentThread().setContextClassLoader(cl);
-
- mainMethod.invoke(launcherClass, new Object[] { this.args });
- }
-
- private static ClassLoader getInitialClassLoader() throws Exception {
- BatchDownloader downloader = new BatchDownloader("http://localhost:9000"); // TODO hard-coded value
- List<File> files = downloader.downloadBatchFiles(new File("/tmp/sonar-boot"));
- ChildFirstClassLoader classLoader = new ChildFirstClassLoader();
- for (File file : files) {
- System.out.println(file);
- classLoader.addFile(file);
- }
- // Add JAR with Sonar CLI - it's a Jar which contains this class
- classLoader.addURL(BootstrapLauncher.class.getProtectionDomain().getCodeSource().getLocation());
- return classLoader;
- }
-}
diff --git a/src/main/java/org/sonar/cli/ChildFirstClassLoader.java b/src/main/java/org/sonar/cli/ChildFirstClassLoader.java
deleted file mode 100644
index c6ab493..0000000
--- a/src/main/java/org/sonar/cli/ChildFirstClassLoader.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Sonar CLI
- * Copyright (C) 2009 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.cli;
-
-import java.io.File;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLClassLoader;
-
-public class ChildFirstClassLoader extends URLClassLoader {
- public ChildFirstClassLoader() {
- super(new URL[0]);
- }
-
- @Override
- public void addURL(URL url) {
- super.addURL(url);
- }
-
- public void addFile(File file) {
- try {
- addURL(file.toURI().toURL());
- } catch (MalformedURLException e) {
- throw new RuntimeException(e);
- }
- }
-
- /**
- * Searches for classes using child-first strategy.
- */
- @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 not loaded, search the local (child) resources
- if (c == null) {
- try {
- c = findClass(name);
- } catch (ClassNotFoundException e) {
- // ignore
- }
- }
- // If we could not find it, delegate to parent
- // Note that we don't attempt to catch any ClassNotFoundException
- if (c == null) {
- if (getParent() != null) {
- c = getParent().loadClass(name);
- } else {
- c = getSystemClassLoader().loadClass(name);
- }
- }
- if (resolve) {
- resolveClass(c);
- }
- return c;
- }
-}
diff --git a/src/main/java/org/sonar/cli/Launcher.java b/src/main/java/org/sonar/runner/Launcher.java
index ef502b7..04deaab 100644
--- a/src/main/java/org/sonar/cli/Launcher.java
+++ b/src/main/java/org/sonar/runner/Launcher.java
@@ -1,6 +1,6 @@
/*
- * Sonar CLI
- * Copyright (C) 2009 SonarSource
+ * Sonar Standalone Runner
+ * Copyright (C) 2011 SonarSource
* dev@sonar.codehaus.org
*
* This program is free software; you can redistribute it and/or
@@ -18,13 +18,12 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02
*/
-package org.sonar.cli;
+package org.sonar.runner;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.core.joran.spi.JoranException;
-import org.apache.commons.configuration.Configuration;
-import org.apache.commons.configuration.SystemConfiguration;
+import org.apache.commons.configuration.*;
import org.apache.commons.io.IOUtils;
import org.slf4j.LoggerFactory;
import org.sonar.api.platform.Environment;
@@ -33,26 +32,30 @@ import org.sonar.batch.Batch;
import org.sonar.batch.bootstrapper.ProjectDefinition;
import org.sonar.batch.bootstrapper.Reactor;
-import java.io.*;
+import java.io.File;
+import java.io.InputStream;
import java.util.Properties;
public class Launcher {
- private String[] args;
+ private Main task;
- public static void main(String[] args) throws Exception {
- new Launcher(args).execute();
+ public Launcher(Main launcher) {
+ this.task = launcher;
}
- public Launcher(String[] args) {
- this.args = args;
+ /**
+ * This method invoked from {@link Main}.
+ */
+ public void execute() {
+ initLogging();
+ executeBatch();
}
- public void execute() throws Exception {
- initLogging();
- ProjectDefinition project = defineProject(new File(args[0]));
+ private void executeBatch() {
+ ProjectDefinition project = defineProject();
Reactor reactor = new Reactor(project);
- Batch batch = new Batch(getInitialConfiguration(), Environment.ANT, reactor); // TODO environment
+ Batch batch = new Batch(getInitialConfiguration(project), Environment.ANT, reactor); // TODO environment
batch.execute();
}
@@ -75,35 +78,24 @@ public class Launcher {
}
}
- private ProjectDefinition defineProject(File file) {
- File baseDir = file.getParentFile();
- File workDir = new File(baseDir, ".sonar");
- Properties properties = new Properties();
- try {
- properties.load(new FileInputStream(file));
- } catch (FileNotFoundException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
-
- ProjectDefinition definition = new ProjectDefinition(baseDir, workDir, properties);
+ private ProjectDefinition defineProject() {
+ File baseDir = task.getProjectDir();
+ Properties properties = task.getProperties();
+ ProjectDefinition definition = new ProjectDefinition(baseDir, task.getWorkDir(), properties);
// TODO for some reason it can't be relative
definition.addSourceDir(new File(baseDir, "src").getAbsolutePath()); // TODO hard-coded value
// TODO definition.addTestDir(path);
// TODO definition.addBinaryDir(path);
// TODO definition.addLibrary(path);
-
- System.out.println(baseDir);
-
return definition;
}
- private Configuration getInitialConfiguration() {
- // TODO
- return new SystemConfiguration();
+ private Configuration getInitialConfiguration(ProjectDefinition project) {
+ CompositeConfiguration configuration = new CompositeConfiguration();
+ configuration.addConfiguration(new SystemConfiguration());
+ configuration.addConfiguration(new EnvironmentConfiguration());
+ configuration.addConfiguration(new MapConfiguration(project.getProperties()));
+ return configuration;
}
}
diff --git a/src/main/java/org/sonar/runner/Main.java b/src/main/java/org/sonar/runner/Main.java
new file mode 100644
index 0000000..eb38033
--- /dev/null
+++ b/src/main/java/org/sonar/runner/Main.java
@@ -0,0 +1,182 @@
+/*
+ * Sonar Standalone 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 org.sonar.batch.bootstrapper.BootstrapClassLoader;
+import org.sonar.batch.bootstrapper.BootstrapException;
+import org.sonar.batch.bootstrapper.Bootstrapper;
+import org.sonar.batch.bootstrapper.BootstrapperIOUtils;
+
+import java.io.*;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.util.Properties;
+
+public class Main {
+
+ private String[] args;
+
+ private File workDir;
+
+ private Properties properties;
+
+ private Bootstrapper bootstrapper;
+
+ public static void main(String[] args) throws Exception {
+ new Main(args).execute();
+ }
+
+ public Main(String[] args) {
+ this.args = args;
+ String home = System.getProperty("runner.home");
+ properties = new Properties();
+ loadProperties(new File(home + "/conf/sonar-runner.properties"));
+ loadProperties(new File(getProjectDir(), "sonar-project.properties"));
+ // TODO load properties from command-line
+ }
+
+ /**
+ * @return project directory (current directory)
+ */
+ public File getProjectDir() {
+ return new File(".").getAbsoluteFile();
+ }
+
+ /**
+ * @return work directory, default is ".sonar" in project directory
+ */
+ public File getWorkDir() {
+ if (workDir == null) {
+ workDir = new File(getProjectDir(), ".sonar");
+ }
+ return workDir;
+ }
+
+ /**
+ * @return global properties, project properties and command-line properties
+ */
+ public Properties getProperties() {
+ return properties;
+ }
+
+ /**
+ * Loads {@link Launcher} from specified {@link BootstrapClassLoader} and passes control to it.
+ *
+ * @see Launcher#execute()
+ */
+ private void delegateExecution(BootstrapClassLoader sonarClassLoader) throws Exception {
+ ClassLoader oldContextClassLoader = Thread.currentThread().getContextClassLoader();
+ try {
+ Thread.currentThread().setContextClassLoader(sonarClassLoader);
+ Class<?> launcherClass = sonarClassLoader.findClass("org.sonar.runner.Launcher");
+ Constructor<?> constructor = launcherClass.getConstructor(Main.class);
+ Object launcher = constructor.newInstance(this);
+ Method method = launcherClass.getMethod("execute");
+ method.invoke(launcher);
+ } catch (InvocationTargetException e) {
+ // Unwrap original exception
+ throw new BootstrapException(e.getTargetException());
+ } catch (Exception e) {
+ // Catch all other exceptions, which relates to reflection
+ throw new BootstrapException(e);
+ } finally {
+ Thread.currentThread().setContextClassLoader(oldContextClassLoader);
+ }
+ }
+
+ /**
+ * Loads properties from specified file.
+ */
+ private void loadProperties(File file) {
+ InputStream in = null;
+ try {
+ in = new FileInputStream(file);
+ properties.load(in);
+ } catch (FileNotFoundException e) {
+ throw new BootstrapException(e);
+ } catch (IOException e) {
+ throw new BootstrapException(e);
+ } finally {
+ BootstrapperIOUtils.closeQuietly(in);
+ }
+ }
+
+ public void execute() throws Exception {
+ String serverUrl = properties.getProperty("sonar.host.url", "http://localhost:9000");
+ log("Sonar Standalone Runner version: " + getRunnerVersion());
+ log("Sonar server: " + serverUrl);
+ log("Sonar work directory: " + getWorkDir().getAbsolutePath());
+ bootstrapper = new Bootstrapper(serverUrl, getWorkDir());
+ checkSonarVersion();
+ delegateExecution(createClassLoader());
+ }
+
+ private void checkSonarVersion() {
+ String serverVersion = bootstrapper.getServerVersion();
+ log("Sonar version: " + serverVersion);
+ if (isVersionPriorTo2Dot6(serverVersion)) {
+ throw new BootstrapException("Sonar " + serverVersion
+ + " does not support Standalone Runner. Please upgrade Sonar to version 2.6 or more.");
+ }
+ }
+
+ private BootstrapClassLoader createClassLoader() {
+ URL url = Main.class.getProtectionDomain().getCodeSource().getLocation();
+ return bootstrapper.createClassLoader(
+ new URL[] { url }, // Add JAR with Sonar Runner - it's a Jar which contains this class
+ getClass().getClassLoader(),
+ "org.apache.tools.ant", "org.sonar.ant");
+ }
+
+ static boolean isVersionPriorTo2Dot6(String version) {
+ return isVersion(version, "1")
+ || isVersion(version, "2.0")
+ || isVersion(version, "2.1")
+ || isVersion(version, "2.2")
+ || isVersion(version, "2.3")
+ || isVersion(version, "2.4")
+ || isVersion(version, "2.5");
+ }
+
+ private static boolean isVersion(String version, String prefix) {
+ return version.startsWith(prefix + ".") || version.equals(prefix);
+ }
+
+ public static String getRunnerVersion() {
+ InputStream in = null;
+ try {
+ in = Main.class.getResourceAsStream("/org/sonar/runner/version.txt");
+ Properties props = new Properties();
+ props.load(in);
+ return props.getProperty("version");
+ } catch (IOException e) {
+ throw new BootstrapException("Could not load the version information for Sonar Standalone Runner", e);
+ } finally {
+ BootstrapperIOUtils.closeQuietly(in);
+ }
+ }
+
+ private void log(String message) {
+ System.out.println(message);
+ }
+}
diff --git a/src/main/resources/org/sonar/runner/version.txt b/src/main/resources/org/sonar/runner/version.txt
new file mode 100644
index 0000000..defbd48
--- /dev/null
+++ b/src/main/resources/org/sonar/runner/version.txt
@@ -0,0 +1 @@
+version=${project.version}