diff options
author | Julien HENRY <julien.henry@sonarsource.com> | 2013-01-15 10:52:10 +0100 |
---|---|---|
committer | Julien HENRY <julien.henry@sonarsource.com> | 2013-01-15 10:52:10 +0100 |
commit | 89efe41a15713e2368ab3b3fe4dabc9505cf83ee (patch) | |
tree | a8cefed9de3304db34fca342790c9e0131525c20 /src/main | |
parent | 5aeb92cac38f2f71e810b2405b08c1c2c8b62e4c (diff) | |
download | sonar-scanner-cli-89efe41a15713e2368ab3b3fe4dabc9505cf83ee.tar.gz sonar-scanner-cli-89efe41a15713e2368ab3b3fe4dabc9505cf83ee.zip |
SONARPLUGINS-2540 Update Sonar Runner CLI to be able to run tasks.
Diffstat (limited to 'src/main')
4 files changed, 157 insertions, 48 deletions
diff --git a/src/main/java/org/sonar/runner/Main.java b/src/main/java/org/sonar/runner/Main.java index 482f827..5321345 100644 --- a/src/main/java/org/sonar/runner/Main.java +++ b/src/main/java/org/sonar/runner/Main.java @@ -49,6 +49,11 @@ public final class Main { private boolean debugMode = false; private boolean displayVersionOnly = false; + private String command; + @VisibleForTesting + Properties globalProperties; + @VisibleForTesting + Properties projectProperties; /** * Entry point of the program. @@ -64,8 +69,8 @@ public final class Main { private void execute(String[] args) { Stats stats = new Stats().start(); try { - Properties props = loadProperties(args); - Runner runner = Runner.create(props); + loadProperties(args); + Runner runner = Runner.create(command, globalProperties, projectProperties); Logs.info("Runner version: " + Version.getVersion()); Logs.info("Java version: " + System.getProperty("java.version", "<unknown>") + ", vendor: " + System.getProperty("java.vendor", "<unknown>")); @@ -92,14 +97,33 @@ public final class Main { } @VisibleForTesting - Properties loadProperties(String[] args) { + void loadProperties(String[] args) { + Properties argsProperties = parseArguments(args); + globalProperties = loadGlobalProperties(argsProperties); + projectProperties = loadProjectProperties(argsProperties); + } + + @VisibleForTesting + Properties loadGlobalProperties(Properties argsProperties) { Properties commandLineProps = new Properties(); commandLineProps.putAll(System.getProperties()); - commandLineProps.putAll(parseArguments(args)); + commandLineProps.putAll(argsProperties); Properties result = new Properties(); - result.putAll(loadRunnerProperties(commandLineProps)); - result.putAll(loadProjectProperties(commandLineProps)); + 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)) { @@ -113,7 +137,7 @@ public final class Main { } @VisibleForTesting - Properties loadRunnerProperties(Properties props) { + 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()); @@ -123,7 +147,7 @@ public final class Main { return new Properties(); } - private Properties loadProjectProperties(Properties props) { + 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()); @@ -167,8 +191,16 @@ public final class Main { @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 (int i = 0; i < args.length; i++) { + for (; i < args.length; i++) { String arg = args[i]; if ("-h".equals(arg) || "--help".equals(arg)) { printUsage(); @@ -222,8 +254,11 @@ public final class Main { private void printUsage() { Logs.info(""); - Logs.info("usage: sonar-runner [options]"); + 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(" -h,--help Display help information"); Logs.info(" -v,--version Display version information"); diff --git a/src/main/java/org/sonar/runner/Runner.java b/src/main/java/org/sonar/runner/Runner.java index 2b26856..ecddd0c 100644 --- a/src/main/java/org/sonar/runner/Runner.java +++ b/src/main/java/org/sonar/runner/Runner.java @@ -105,23 +105,27 @@ public final class Runner { 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 properties; + private Properties globalProperties; + private Properties projectProperties; private boolean isEncodingPlatformDependant; - private Runner(Properties props) { - this.properties = props; + 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.properties.put(PROPERTY_ENVIRONMENT_INFORMATION_KEY, "Runner"); - this.properties.put(PROPERTY_ENVIRONMENT_INFORMATION_VERSION, Version.getVersion()); + this.globalProperties.put(PROPERTY_ENVIRONMENT_INFORMATION_KEY, "Runner"); + this.globalProperties.put(PROPERTY_ENVIRONMENT_INFORMATION_VERSION, Version.getVersion()); // sets the encoding if not forced - if (!properties.containsKey(PROPERTY_SOURCE_ENCODING)) { + if (!globalProperties.containsKey(PROPERTY_SOURCE_ENCODING) && !projectProperties.containsKey(PROPERTY_SOURCE_ENCODING)) { isEncodingPlatformDependant = true; - properties.setProperty(PROPERTY_SOURCE_ENCODING, Charset.defaultCharset().name()); + globalProperties.setProperty(PROPERTY_SOURCE_ENCODING, Charset.defaultCharset().name()); } // and init the directories initDirs(); @@ -131,15 +135,29 @@ public final class Runner { * Creates a Runner based only on the given properties. */ public static Runner create(Properties props) { - return new Runner(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. */ public static Runner create(Properties props, File basedir) { - props.put(PROPERTY_SONAR_PROJECT_BASEDIR, basedir.getAbsolutePath()); - return new Runner(props); + 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); } /** @@ -152,23 +170,23 @@ public final class Runner { } public String getSonarServerURL() { - return properties.getProperty("sonar.host.url", "http://localhost:9000"); + return projectProperties.getProperty("sonar.host.url", globalProperties.getProperty("sonar.host.url", "http://localhost:9000")); } private void initDirs() { - String path = properties.getProperty(PROPERTY_SONAR_PROJECT_BASEDIR, "."); + 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.runner.projectDir" property - properties.put(PROPERTY_SONAR_PROJECT_BASEDIR, projectDir.getAbsolutePath()); + projectProperties.put(PROPERTY_SONAR_PROJECT_BASEDIR, projectDir.getAbsolutePath()); workDir = initWorkDir(); } private File initWorkDir() { File newWorkDir; - String customWorkDir = properties.getProperty(PROPERTY_WORK_DIRECTORY); + 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); } @@ -204,7 +222,7 @@ public final class Runner { * @return the source code encoding that will be used by Sonar */ public String getSourceCodeEncoding() { - return properties.getProperty(PROPERTY_SOURCE_ENCODING); + return projectProperties.getProperty(PROPERTY_SOURCE_ENCODING, globalProperties.getProperty(PROPERTY_SOURCE_ENCODING)); } /** @@ -214,11 +232,18 @@ public final class Runner { return isEncodingPlatformDependant; } + public String getCommand() { + return command; + } + /** * @return global properties, project properties and command-line properties */ protected Properties getProperties() { - return properties; + Properties props = new Properties(); + props.putAll(globalProperties); + props.putAll(projectProperties); + return props; } protected void checkSonarVersion(Bootstrapper bootstrapper) { @@ -284,8 +309,8 @@ public final class Runner { try { Thread.currentThread().setContextClassLoader(sonarClassLoader); Class<?> launcherClass = sonarClassLoader.findClass("org.sonar.runner.internal.batch.Launcher"); - Constructor<?> constructor = launcherClass.getConstructor(Properties.class, List.class); - Object launcher = constructor.newInstance(getProperties(), containerExtensions); + 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) { @@ -306,8 +331,8 @@ public final class Runner { * @param version the version of this tool */ public void setEnvironmentInformation(String key, String version) { - this.properties.put(PROPERTY_ENVIRONMENT_INFORMATION_KEY, key); - this.properties.put(PROPERTY_ENVIRONMENT_INFORMATION_VERSION, version); + this.globalProperties.put(PROPERTY_ENVIRONMENT_INFORMATION_KEY, key); + this.globalProperties.put(PROPERTY_ENVIRONMENT_INFORMATION_VERSION, version); } public void setUnmaskedPackages(String... unmaskedPackages) { diff --git a/src/main/java/org/sonar/runner/internal/batch/Launcher.java b/src/main/java/org/sonar/runner/internal/batch/Launcher.java index dbee102..5fa68ad 100644 --- a/src/main/java/org/sonar/runner/internal/batch/Launcher.java +++ b/src/main/java/org/sonar/runner/internal/batch/Launcher.java @@ -23,6 +23,7 @@ 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.slf4j.LoggerFactory; import org.sonar.api.batch.bootstrap.ProjectDefinition; @@ -34,6 +35,7 @@ import org.sonar.runner.Runner; import java.io.InputStream; import java.util.List; +import java.util.Map; import java.util.Properties; /** @@ -42,11 +44,20 @@ import java.util.Properties; */ public class Launcher { - private Properties propertiesFromRunner; + private String command; + private Properties globalProperties; + private Properties projectProperties; private List<Object> containerExtensions; + @Deprecated public Launcher(Properties properties, List<Object> containerExtensions) { - this.propertiesFromRunner = properties; + 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; } @@ -54,24 +65,37 @@ public class Launcher { * Main entry point. */ public void execute() { - Properties configuration = getInitialConfiguration(); - configuration.putAll(propertiesFromRunner); - ProjectDefinition project = SonarProjectBuilder.create(configuration).generateProjectDefinition(); - initLogging(configuration); - executeBatch(project); + Properties globalConfiguration = getInitialConfiguration(); + globalConfiguration.putAll(globalProperties); + Properties projectConfiguration = new Properties(); + projectConfiguration.putAll(globalConfiguration); + projectConfiguration.putAll(projectProperties); + ProjectDefinition project = SonarProjectBuilder.create(command, projectConfiguration).generateProjectDefinition(); + initLogging(globalConfiguration); + executeBatch(globalConfiguration, project); } - private void executeBatch(ProjectDefinition project) { + private void executeBatch(Properties globalConfiguration, ProjectDefinition project) { setContainerExtensionsOnProject(project); - String envKey = propertiesFromRunner.getProperty(Runner.PROPERTY_ENVIRONMENT_INFORMATION_KEY); - String envVersion = propertiesFromRunner.getProperty(Runner.PROPERTY_ENVIRONMENT_INFORMATION_VERSION); + String envKey = projectProperties.getProperty(Runner.PROPERTY_ENVIRONMENT_INFORMATION_KEY); + String envVersion = projectProperties.getProperty(Runner.PROPERTY_ENVIRONMENT_INFORMATION_VERSION); Batch batch = Batch.builder() + .setGlobalProperties(toMap(globalConfiguration)) + .setTaskCommand(command) .setProjectReactor(new ProjectReactor(project)) .setEnvironment(new EnvironmentInformation(envKey, envVersion)) .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 setContainerExtensionsOnProject(ProjectDefinition projectDefinition) { for (Object extension : containerExtensions) { projectDefinition.addContainerExtension(extension); @@ -103,7 +127,7 @@ public class Launcher { @VisibleForTesting protected boolean isDebug() { - return Boolean.parseBoolean(propertiesFromRunner.getProperty(Runner.PROPERTY_VERBOSE, propertiesFromRunner.getProperty(Runner.PROPERTY_OLD_DEBUG_MODE, "false"))); + return Boolean.parseBoolean(projectProperties.getProperty(Runner.PROPERTY_VERBOSE, projectProperties.getProperty(Runner.PROPERTY_OLD_DEBUG_MODE, "false"))); } @VisibleForTesting diff --git a/src/main/java/org/sonar/runner/internal/batch/SonarProjectBuilder.java b/src/main/java/org/sonar/runner/internal/batch/SonarProjectBuilder.java index 440b4c6..d9857f4 100644 --- a/src/main/java/org/sonar/runner/internal/batch/SonarProjectBuilder.java +++ b/src/main/java/org/sonar/runner/internal/batch/SonarProjectBuilder.java @@ -29,6 +29,7 @@ import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.batch.bootstrap.ProjectDefinition; +import org.sonar.batch.tasks.AnalyseProjectTaskDefinition; import org.sonar.runner.RunnerException; import java.io.File; @@ -110,23 +111,47 @@ public final class SonarProjectBuilder { */ 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(Properties properties) { + private SonarProjectBuilder(String command, Properties properties) { + this.command = command; this.properties = properties; } public static SonarProjectBuilder create(Properties properties) { - return new SonarProjectBuilder(properties); + return create(null, properties); + } + + public static SonarProjectBuilder create(String command, Properties properties) { + if (StringUtils.isBlank(command)) { + command = AnalyseProjectTaskDefinition.COMMAND; + } + return new SonarProjectBuilder(command, properties); } public ProjectDefinition generateProjectDefinition() { - ProjectDefinition rootProject = defineProject(properties, null); - rootProjectWorkDir = rootProject.getWorkDir(); - defineChildren(rootProject); - cleanAndCheckProjectDefinitions(rootProject); - return rootProject; + if (AnalyseProjectTaskDefinition.COMMAND.equals(command)) { + ProjectDefinition rootProject = defineProject(properties, null); + rootProjectWorkDir = rootProject.getWorkDir(); + defineChildren(rootProject); + cleanAndCheckProjectDefinitions(rootProject); + return rootProject; + } + else { + return defineTaskContext(); + } + } + + 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) { |