From 3a838115d1275778b303029fbf6632976b5db58f Mon Sep 17 00:00:00 2001 From: Evgeny Mandrikov Date: Thu, 3 Feb 2011 00:40:38 +0000 Subject: [PATCH 1/1] SONAR-RUNNER: Rename directory --- pom.xml | 102 ++++++++++++++++ src/assembly/bin/sonar-runner.sh | 21 ++++ src/assembly/conf/sonar-runner.properties | 17 +++ src/it/example/analyze.sh | 4 + src/it/example/project.properties | 12 ++ .../src/org/sonar/cli/example/HelloWorld.java | 7 ++ .../java/org/sonar/cli/BootstrapLauncher.java | 99 ++++++++++++++++ .../org/sonar/cli/ChildFirstClassLoader.java | 75 ++++++++++++ src/main/java/org/sonar/cli/Launcher.java | 109 ++++++++++++++++++ 9 files changed, 446 insertions(+) create mode 100644 pom.xml create mode 100755 src/assembly/bin/sonar-runner.sh create mode 100644 src/assembly/conf/sonar-runner.properties create mode 100755 src/it/example/analyze.sh create mode 100644 src/it/example/project.properties create mode 100644 src/it/example/src/org/sonar/cli/example/HelloWorld.java create mode 100644 src/main/java/org/sonar/cli/BootstrapLauncher.java create mode 100644 src/main/java/org/sonar/cli/ChildFirstClassLoader.java create mode 100644 src/main/java/org/sonar/cli/Launcher.java diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..58f10c7 --- /dev/null +++ b/pom.xml @@ -0,0 +1,102 @@ + + 4.0.0 + + org.codehaus.sonar-plugins + parent + 8 + ../parent + + + sonar-runner + 0.1-SNAPSHOT + + Sonar Standalone Runner + + http://docs.codehaus.org/display/SONAR/Sonar+Standalone+Runner + 2011 + + SonarSource + http://www.sonarsource.com + + + + GNU LGPL 3 + http://www.gnu.org/licenses/lgpl.txt + repo + + + + + + godin + Evgeny Mandrikov + +3 + + + simon.brandhof + Simon Brandhof + +1 + + + + + scm:svn:http://svn.codehaus.org/sonar-plugins/trunk/sonar-cli + scm:svn:https://svn.codehaus.org/sonar-plugins/trunk/sonar-cli + http://svn.sonar-plugins.codehaus.org + + + + + + + + 2.6-SNAPSHOT + + + + + + org.codehaus.sonar + sonar-batch-bootstrapper + ${sonar.version} + + + + ch.qos.logback + logback-classic + 0.9.15 + provided + + + org.codehaus.sonar + sonar-batch + ${sonar.version} + provided + + + + + + + org.apache.maven.plugins + maven-shade-plugin + + + package + + shade + + + + + org.sonar.cli.BootstrapLauncher + + + + + + + + + diff --git a/src/assembly/bin/sonar-runner.sh b/src/assembly/bin/sonar-runner.sh new file mode 100755 index 0000000..98a3882 --- /dev/null +++ b/src/assembly/bin/sonar-runner.sh @@ -0,0 +1,21 @@ +#!/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 + +echo "Info: Using sonar-runner at $SONAR_RUNNER_HOME" + +JAVACMD="`which java`" + +exec "$JAVACMD" + -classpath "${SONAR_RUNNER_HOME}"/lib/sonar-runner-*.jar \ + "$@" diff --git a/src/assembly/conf/sonar-runner.properties b/src/assembly/conf/sonar-runner.properties new file mode 100644 index 0000000..58e14fd --- /dev/null +++ b/src/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/it/example/analyze.sh b/src/it/example/analyze.sh new file mode 100755 index 0000000..f3e2f6a --- /dev/null +++ b/src/it/example/analyze.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +# TODO remove hard-coded version +java -jar ../../../target/sonar-cli-0.1-SNAPSHOT.jar project.properties diff --git a/src/it/example/project.properties b/src/it/example/project.properties new file mode 100644 index 0000000..a5708b9 --- /dev/null +++ b/src/it/example/project.properties @@ -0,0 +1,12 @@ +project.key=my:project +project.name=My project +project.version=1.0 + +project.build.directory=output + +#project.sources=src/main/java +#project.sources=src/main/resources +#project.binaries=output/classes +#project.language=java +#sonar.dynamicAnalysis=reuseReports +#sonar.surefire.reports=output/junit/ diff --git a/src/it/example/src/org/sonar/cli/example/HelloWorld.java b/src/it/example/src/org/sonar/cli/example/HelloWorld.java new file mode 100644 index 0000000..beed553 --- /dev/null +++ b/src/it/example/src/org/sonar/cli/example/HelloWorld.java @@ -0,0 +1,7 @@ +package org.sonar.cli.example; + +class HelloWorld { + public void sayHello() { + System.out.println("Hello world"); + } +} diff --git a/src/main/java/org/sonar/cli/BootstrapLauncher.java b/src/main/java/org/sonar/cli/BootstrapLauncher.java new file mode 100644 index 0000000..dabadcc --- /dev/null +++ b/src/main/java/org/sonar/cli/BootstrapLauncher.java @@ -0,0 +1,99 @@ +/* + * 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 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 new file mode 100644 index 0000000..c6ab493 --- /dev/null +++ b/src/main/java/org/sonar/cli/ChildFirstClassLoader.java @@ -0,0 +1,75 @@ +/* + * 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/cli/Launcher.java new file mode 100644 index 0000000..ef502b7 --- /dev/null +++ b/src/main/java/org/sonar/cli/Launcher.java @@ -0,0 +1,109 @@ +/* + * 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 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.io.IOUtils; +import org.slf4j.LoggerFactory; +import org.sonar.api.platform.Environment; +import org.sonar.api.utils.SonarException; +import org.sonar.batch.Batch; +import org.sonar.batch.bootstrapper.ProjectDefinition; +import org.sonar.batch.bootstrapper.Reactor; + +import java.io.*; +import java.util.Properties; + +public class Launcher { + + private String[] args; + + public static void main(String[] args) throws Exception { + new Launcher(args).execute(); + } + + public Launcher(String[] args) { + this.args = args; + } + + public void execute() throws Exception { + initLogging(); + ProjectDefinition project = defineProject(new File(args[0])); + Reactor reactor = new Reactor(project); + Batch batch = new Batch(getInitialConfiguration(), Environment.ANT, reactor); // TODO environment + batch.execute(); + } + + private void initLogging() { + 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", getLog().isDebugEnabled() ? "DEBUG" : "INFO"); + System.setProperty("ROOT_LOGGER_LEVEL", "INFO"); + try { + jc.doConfigure(input); + + } catch (JoranException e) { + throw new SonarException("can not initialize logging", e); + + } finally { + IOUtils.closeQuietly(input); + } + } + + 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); + // 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(); + } + +} -- 2.39.5