/*
* Coverity Sonar Plugin
* Copyright (c) 2017 Synopsys, Inc
* support@coverity.com
*
* All rights reserved. This program and the accompanying materials are made
* available under the terms of the Eclipse Public License v1.0 which
* accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html.
*/
package org.sonar.plugins.coverity;
import com.google.common.collect.ImmutableList;
import org.sonar.api.Plugin;
import org.sonar.api.PropertyType;
import org.sonar.api.config.PropertyDefinition;
import org.sonar.api.resources.Qualifiers;
import org.sonar.plugins.coverity.base.CoverityPluginMetrics;
import org.sonar.plugins.coverity.batch.CoveritySensor;
import org.sonar.plugins.coverity.server.CoverityProfiles;
import org.sonar.plugins.coverity.server.CoverityRules;
import org.sonar.plugins.coverity.ui.CoverityWidget;
import org.sonar.plugins.coverity.server.CppLanguage;
import org.sonar.plugins.coverity.ws.CIMClientFactory;
import java.util.Arrays;
import java.util.List;
public final class CoverityPlugin implements Plugin {
public static final String COVERITY_ENABLE = "sonar.coverity.enable";
public static final String COVERITY_CONNECT_HOSTNAME = "sonar.coverity.connect.hostname";
public static final String COVERITY_CONNECT_PORT = "sonar.coverity.connect.port";
public static final String COVERITY_CONNECT_USERNAME = "sonar.coverity.connect.username";
public static final String COVERITY_CONNECT_PASSWORD = "sonar.coverity.connect.password";
public static final String COVERITY_PROJECT = "sonar.coverity.project";
public static final String COVERITY_PREFIX = "sonar.coverity.prefix";
public static final String COVERITY_SOURCE_DIRECTORY = "sonar.coverity.sources.directory";
public static final String COVERITY_CONNECT_SSL = "sonar.coverity.ssl";
public static final String COVERITY_C_CPP_SOURCE_FILE_SUFFIXES = "sonar.coverity.cov-cpp.suffixes";
public static final String REPOSITORY_KEY = "coverity";
public static List<String> COVERITY_LANGUAGES =
Arrays.asList(
"java",
"cs",
"js",
"py",
"php",
CppLanguage.KEY);
// This is where you're going to declare all your Sonar extensions
private List getExtensions() {
int i = 0;
return ImmutableList.of(
//Properties
PropertyDefinition.builder(CoverityPlugin.COVERITY_ENABLE)
.name("Enable Coverity")
.description("Enables Coverity issue import")
.defaultValue("false")
.type(PropertyType.BOOLEAN)
.onQualifiers(Qualifiers.PROJECT)
.index(++i)
.build(),
PropertyDefinition.builder(CoverityPlugin.COVERITY_CONNECT_HOSTNAME)
.name("Coverity Connect Hostname")
.description("Hostname of the Coverity Connect server from which to import issues")
.type(PropertyType.STRING)
.index(++i)
.build(),
PropertyDefinition.builder(CoverityPlugin.COVERITY_CONNECT_PORT)
.name("Coverity Connect Port")
.description("Port of the Coverity Connect server from which to import issues")
.type(PropertyType.INTEGER)
.index(++i)
.build(),
PropertyDefinition.builder(CoverityPlugin.COVERITY_CONNECT_USERNAME)
.name("Coverity Connect Username")
.description("Username to access issues in Coverity Connect")
.type(PropertyType.STRING)
.index(++i)
.build(),
PropertyDefinition.builder(CoverityPlugin.COVERITY_CONNECT_PASSWORD)
.name("Coverity Connect Password")
.description("Password to access issues in Coverity Connect")
.type(PropertyType.PASSWORD)
.index(++i)
.build(),
PropertyDefinition.builder(CoverityPlugin.COVERITY_CONNECT_SSL)
.name("Use SSL")
.description("Use SSL to interact with Coverity Connect")
.defaultValue("false")
.type(PropertyType.BOOLEAN)
.index(++i)
.build(),
PropertyDefinition.builder(CoverityPlugin.COVERITY_PROJECT)
.name("Coverity Project")
.description("The project in Coverity Connect corresponding to this Sonar project")
.type(PropertyType.STRING)
.onlyOnQualifiers(Qualifiers.PROJECT)
.index(++i)
.build(),
// language properties
PropertyDefinition.builder(COVERITY_C_CPP_SOURCE_FILE_SUFFIXES)
.name("C/C++ source files suffixes")
.description("Comma-separated list of source file suffixes to retrieve issues from Coverity Connect.")
.defaultValue(CppLanguage.DEFAULT_SUFFIXES)
.subCategory("Languages")
.type(PropertyType.STRING)
.index(1)
.build(),
/*
* Coverity analysis may not be performed on the same directory as Sonar analysis,
* so in some case we need to remove the beginning of the filename to make it
* relative to Sonar's project root.This can be done by specifying the prefix to remove from filenames
* with the 'sonar.coverity.prefix' key.
* */
PropertyDefinition.builder(CoverityPlugin.COVERITY_PREFIX)
.name("Coverity Files Prefix")
.description("Prefix to strip from filenames to match this Sonar project")
.type(PropertyType.STRING)
.onlyOnQualifiers(Qualifiers.PROJECT)
.index(++i)
.build(),
/**
* When importing defects from cim into sonar, our plugin needs to create "issuable" objects for sonarqube.
* This is accomplished my matching the path of a defect on CIM with the path of a file under the sources
* directory used by sonar. By default, this value is "sonar.sources" which is set up on a properties
* file if sonar-runner is being used as executor. However, if maven is being used as executor it will
* not use a properties file. Instead, this property will be maven's "sourceDirectory" which might
* conflict with files under maven tests folder. In other words, if a file under tests has been analyzed
* by coverity analisis, running this executor will result in that file not being indexed by sonar.
* The solution for this problem is to add a property that will tell coverity which are the sources that
* were analyzed by coverity, which my defer from the ones scanned by the sonar executor.
*/
PropertyDefinition.builder(CoverityPlugin.COVERITY_SOURCE_DIRECTORY)
.name("Coverity Sources Directory")
.description("Directory that sonar will scan for sources that match defects path on CIM")
.type(PropertyType.STRING)
.onlyOnQualifiers(Qualifiers.PROJECT)
.index(++i)
.build(),
//Batch
CoveritySensor.class,
CIMClientFactory.class,
//Server
CoverityRules.class,
CoverityProfiles.class,
CppLanguage.class,
//UI
CoverityWidget.class,
//Base
CoverityPluginMetrics.class
);
}
@Override
public void define(Context context) {
context.addExtensions(getExtensions());
}
}