diff options
author | Evgeny Mandrikov <mandrikov@gmail.com> | 2011-02-03 04:08:26 +0000 |
---|---|---|
committer | Evgeny Mandrikov <mandrikov@gmail.com> | 2011-02-03 04:08:26 +0000 |
commit | a0c622bc8666ccb0983fce374dfd01f03ca37703 (patch) | |
tree | a6c7e249db0dfe7fc871789daca65783b45a46e9 /src/main | |
parent | 3a838115d1275778b303029fbf6632976b5db58f (diff) | |
download | sonar-scanner-cli-a0c622bc8666ccb0983fce374dfd01f03ca37703.tar.gz sonar-scanner-cli-a0c622bc8666ccb0983fce374dfd01f03ca37703.zip |
SONAR-RUNNER
Diffstat (limited to 'src/main')
-rwxr-xr-x | src/main/assembly/bin/sonar-runner.sh | 27 | ||||
-rw-r--r-- | src/main/assembly/conf/sonar-runner.properties | 17 | ||||
-rw-r--r-- | src/main/java/org/sonar/cli/BootstrapLauncher.java | 99 | ||||
-rw-r--r-- | src/main/java/org/sonar/cli/ChildFirstClassLoader.java | 75 | ||||
-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.java | 182 | ||||
-rw-r--r-- | src/main/resources/org/sonar/runner/version.txt | 1 |
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&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} |