diff --git a/README.md b/README.md index a709edb..bfeb504 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ Here is the compatibility matrix of the plugin: | 3.1.1 | 4.1.2 | 7.9 -> 9.9 | Fortran | | 3.1.2 | 5.1.0 | 7.9 -> 9.9 | Fortran | | 5.1.0 | 5.1.0 | 7.9 -> 9.9 | Fortran | +| 5.2.0 | 5.1.0 | 25.1.0 -> 25.9.0 | Fortran | *Notice: Since 5.X this plugins will follow I-Code versionning. There is no breaking changes between 3.X and 5.X* @@ -50,8 +51,8 @@ If embedded version of i-Code does not match your need, you can set the executio - `sonar.icode.path`: Define i-Code CNES executable path to auto-launch it on analysis. Default: `${HOME}/icode-cnes/icode.exe`. #### Other plugin's properties -- `sonar.icode.f77.file.suffixes`: List of suffixes for F77 files to analyze. Default: `.f,.f77,.for,.fpp,.ftn,.F,.F77,.FOR,.FPP,.FTN`. -- `sonar.icode.f90.file.suffixes`: List of suffixes for F90 files to analyze. Default: `.f90,.F90`. +- `sonar.f77.file.suffixes`: List of suffixes for F77 files to analyze. Default: `.f,.f77,.for,.fpp,.ftn,.F,.F77,.FOR,.FPP,.FTN`. +- `sonar.f90.file.suffixes`: List of suffixes for F90 files to analyze. Default: `.f90,.F90`. - `sonar.icode.reports.path`: Path to the i-Code reports. Multiple path can be provided. Default: `result.res`. ### Features diff --git a/it/Dockerfile-auditor b/it/Dockerfile-auditor index e2ef879..61b054c 100644 --- a/it/Dockerfile-auditor +++ b/it/Dockerfile-auditor @@ -22,7 +22,7 @@ COPY --from=builder /opt/sonar-scanner /opt/sonar-scanner RUN apk update --no-cache && \ - apk add --update --no-cache -q curl gcc jq libffi-dev musl-dev openssl-dev python3 py3-requests shellcheck + apk add --update --no-cache -q curl gcc jq libffi-dev musl-dev openssl-dev python3 py3-requests RUN set -eux && \ addgroup --gid 1000 scanner-cli && \ diff --git a/pom.xml b/pom.xml index 24a24a5..e8c8f40 100644 --- a/pom.xml +++ b/pom.xml @@ -57,13 +57,13 @@ UTF-8 - 17 + 11 23 17 3.5.3 - 9.14.0.375 - 9.9.0.65466 + 11.0.0.2664 + 25.1.0.102122 icode fr.cnes.sonar.plugins.icode.ICodePlugin https://github.com/cnescatlab/sonar-icode-cnes-plugin @@ -75,15 +75,11 @@ - jitpack.io - https://jitpack.io - - - github - https://maven.pkg.github.com/cnescatlab/i-CodeCNES - - true - + github + https://maven.pkg.github.com/cnescatlab/i-CodeCNES + + false + @@ -104,13 +100,6 @@ commons-lang3 3.17.0 - - org.sonarsource.sonarqube sonar-plugin-api-impl @@ -257,4 +246,4 @@ - + \ No newline at end of file diff --git a/src/main/java/fr/cnes/sonar/plugins/icode/check/ICodeSensor.java b/src/main/java/fr/cnes/sonar/plugins/icode/check/ICodeSensor.java index 42fb7a1..62e6026 100644 --- a/src/main/java/fr/cnes/sonar/plugins/icode/check/ICodeSensor.java +++ b/src/main/java/fr/cnes/sonar/plugins/icode/check/ICodeSensor.java @@ -16,6 +16,34 @@ */ package fr.cnes.sonar.plugins.icode.check; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.api.batch.fs.FilePredicate; +import org.sonar.api.batch.fs.FilePredicates; +import org.sonar.api.batch.fs.FileSystem; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.TextRange; +import org.sonar.api.batch.rule.ActiveRules; +import org.sonar.api.batch.sensor.Sensor; +import org.sonar.api.batch.sensor.SensorContext; +import org.sonar.api.batch.sensor.SensorDescriptor; +import org.sonar.api.batch.sensor.issue.NewIssue; +import org.sonar.api.batch.sensor.issue.NewIssueLocation; +import org.sonar.api.config.Configuration; +import org.sonar.api.rule.RuleKey; + import fr.cnes.icode.Analyzer; import fr.cnes.icode.data.CheckResult; import fr.cnes.icode.services.languages.LanguageService; @@ -29,43 +57,27 @@ import fr.cnes.sonar.plugins.icode.model.XmlHandler; import fr.cnes.sonar.plugins.icode.rules.ICodeRulesDefinition; import fr.cnes.sonar.plugins.icode.settings.ICodePluginProperties; -import org.sonar.api.batch.fs.*; -import org.sonar.api.batch.rule.ActiveRules; -import org.sonar.api.batch.sensor.Sensor; -import org.sonar.api.batch.sensor.SensorContext; -import org.sonar.api.batch.sensor.SensorDescriptor; -import org.sonar.api.batch.sensor.issue.NewIssue; -import org.sonar.api.batch.sensor.issue.NewIssueLocation; -import org.sonar.api.config.Configuration; -import org.sonar.api.rule.RuleKey; -import org.sonar.api.utils.log.Logger; -import org.sonar.api.utils.log.Loggers; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.nio.file.Paths; -import java.util.*; /** * Executed during sonar-scanner call. * This Sensor is able to: - * - Run i-Code checks. - * - Import i-Code reports into SonarQube. - * - Run a specified external version of i-Code. + * - Run i-Code checks. + * - Import i-Code reports into SonarQube. + * - Run a specified external version of i-Code. */ public class ICodeSensor implements Sensor { + private static final String SENSOR_NAME = "Sonar i-Code"; + /** * Logger for this class. */ - private static final Logger LOGGER = Loggers.get(ICodeSensor.class); + private static final Logger LOGGER = LoggerFactory.getLogger(ICodeSensor.class); - /** + /** * Languages used by I-Code */ - private final String[] languages = {Fortran77Language.KEY, Fortran90Language.KEY}; + private final String[] languages = { Fortran77Language.KEY, Fortran90Language.KEY }; /** * Give information about this sensor. @@ -78,7 +90,7 @@ public void describe(final SensorDescriptor sensorDescriptor) { sensorDescriptor.onlyOnLanguages(languages); // Defines sensor name - sensorDescriptor.name("Sonar i-Code"); + sensorDescriptor.name(ICodeSensor.SENSOR_NAME); // Only main files are concerned, not tests. sensorDescriptor.onlyOnFileType(InputFile.Type.MAIN); @@ -86,9 +98,9 @@ public void describe(final SensorDescriptor sensorDescriptor) { // This sensor is activated only if a rule from the following repo is activated. for (String Lang : languages) { sensorDescriptor.createIssuesForRuleRepositories( - ICodeRulesDefinition.getRepositoryKeyForLanguage(Lang)); + ICodeRulesDefinition.getRepositoryKeyForLanguage(Lang)); } - + } /** @@ -98,18 +110,17 @@ public void describe(final SensorDescriptor sensorDescriptor) { */ @Override public void execute(final SensorContext sensorContext) { - // Represent the configuration used for the analysis. final Configuration config = sensorContext.config(); // Run external version of i-Code CNES on during analysis. - if(config.getBoolean(ICodePluginProperties.AUTOLAUNCH_PROP_KEY) + if (config.getBoolean(ICodePluginProperties.AUTOLAUNCH_PROP_KEY) .orElse(Boolean.getBoolean(ICodePluginProperties.AUTOLAUNCH_PROP_DEFAULT))) { executeExternalICode(sensorContext); } // Run embedded version of i-Code CNES on during analysis. - if(config.getBoolean(ICodePluginProperties.USE_EMBEDDED_PROP_KEY) + if (config.getBoolean(ICodePluginProperties.USE_EMBEDDED_PROP_KEY) .orElse(Boolean.getBoolean(ICodePluginProperties.USE_EMBEDDED_PROP_DEFAULT))) { executeEmbeddedICode(sensorContext); } @@ -137,17 +148,18 @@ protected void executeExternalResultsImport(final SensorContext sensorContext) { final List reportFiles = getReportFiles(config, fileSystem); // If exists, unmarshal each xml result file. - for(final File reportFile : reportFiles) { + for (final File reportFile : reportFiles) { try { // Unmarshal the xml. final FileInputStream file = new FileInputStream(reportFile); - final AnalysisProject analysisProject = (AnalysisProject) XmlHandler.unmarshal(file, AnalysisProject.class); + final AnalysisProject analysisProject = (AnalysisProject) XmlHandler.unmarshal(file, + AnalysisProject.class); // Retrieve file in a SonarQube format. final Map scannedFiles = getScannedFiles(fileSystem, analysisProject); // Handles issues. for (final AnalysisRule rule : analysisProject.getAnalysisRules()) { - if(isRuleActive(activeRules, rule.getAnalysisRuleId())) { // manage active rules + if (isRuleActive(activeRules, rule.getAnalysisRuleId())) { // manage active rules saveIssue(sensorContext, scannedFiles, rule); } else if (ICodeMetricsProcessor.isMetric(rule.getAnalysisRuleId())) { // manage trivial measures ICodeMetricsProcessor.saveMeasure(sensorContext, scannedFiles, rule); @@ -180,20 +192,21 @@ private void executeEmbeddedICode(final SensorContext sensorContext) { final ActiveRules activeRules = sensorContext.activeRules(); final Iterable inputFiles = fileSystem.inputFiles(predicates.hasType(InputFile.Type.MAIN)); final HashSet files = new HashSet<>(); - final HashMap filesMap = new HashMap<>(); + final HashMap filesMap = new HashMap<>(); // Gather all files in a Set. - for(final InputFile inputFile : inputFiles) { + for (final InputFile inputFile : inputFiles) { files.add(new File(inputFile.uri())); filesMap.put(inputFile.uri().getPath(), inputFile); } + // Run all checkers on all files. final List results = analyzer.stableCheck(files, LanguageService.getLanguagesIds(), null); // Add each issue to SonarQube. - for(final CheckResult result : results) { - if(isRuleActive(activeRules, result.getName())) { // manage active rules + for (final CheckResult result : results) { + if (isRuleActive(activeRules, result.getName())) { // manage active rules saveIssue(sensorContext, result); } else if (ICodeMetricsProcessor.isMetric(result.getName())) { // manage trivial measures ICodeMetricsProcessor.saveMeasure(sensorContext, result); @@ -221,17 +234,20 @@ private void executeExternalICode(final SensorContext sensorContext) { final Iterable inputFiles = fileSystem.inputFiles(predicates.hasType(InputFile.Type.MAIN)); final StringBuilder files = new StringBuilder(); inputFiles.forEach(file -> files.append(file.uri().getPath()).append(" ")); - final String executable = config.get(ICodePluginProperties.ICODE_PATH_KEY).orElse(ICodePluginProperties.ICODE_PATH_DEFAULT); - final String outputFile = config.get(ICodePluginProperties.REPORT_PATH_KEY).orElse(ICodePluginProperties.REPORT_PATH_DEFAULT); - final String outputPath = Paths.get(sensorContext.fileSystem().baseDir().toString(),outputFile).toString(); + final String executable = config.get(ICodePluginProperties.ICODE_PATH_KEY) + .orElse(ICodePluginProperties.ICODE_PATH_DEFAULT); + final String outputFile = config.get(ICodePluginProperties.REPORT_PATH_KEY) + .orElse(ICodePluginProperties.REPORT_PATH_DEFAULT); + final String outputPath = Paths.get(sensorContext.fileSystem().baseDir().toString(), outputFile).toString(); final String outputOption = "-o"; final String command = String.join(" ", executable, files.toString(), outputOption, outputPath); - LOGGER.info("Running i-Code CNES and generating results to "+ outputPath); + LOGGER.info("Running i-Code CNES and generating results to " + outputPath); try { int success = runICode(command); - if(0!=success){ - final String message = String.format("i-Code CNES auto-launch analysis failed with exit code %d.", success); + if (0 != success) { + final String message = String.format("i-Code CNES auto-launch analysis failed with exit code %d.", + success); throw new ICodeException(message); } LOGGER.info("Auto-launch successfully executed i-Code CNES."); @@ -245,11 +261,11 @@ private void executeExternalICode(final SensorContext sensorContext) { * * @param command The i-Code Command to execute. * @return 0 if all was fine. - * @throws IOException On possible unknown file. + * @throws IOException On possible unknown file. * @throws InterruptedException On possible process problem. */ protected int runICode(final String command) throws IOException, InterruptedException { - final Process icode = Runtime.getRuntime().exec(command); + final Process icode = Runtime.getRuntime().exec(command); return icode.waitFor(); } @@ -257,20 +273,21 @@ protected int runICode(final String command) throws IOException, InterruptedExce * This method save an issue into the SonarQube service. * * @param sensorContext A SensorContext to reach SonarQube services. - * @param result A CheckResult with the convenient format for i-Code. + * @param result A CheckResult with the convenient format for i-Code. */ static void saveIssue(final SensorContext sensorContext, final CheckResult result) { final FileSystem fileSystem = sensorContext.fileSystem(); final FilePredicates predicates = fileSystem.predicates(); final NewIssue issue = sensorContext.newIssue(); final String fileToFind = result.getFile().getPath(); - final FilePredicate predicate = predicates.or(predicates.hasPath(fileToFind), predicates.hasRelativePath(fileToFind)); + final FilePredicate predicate = predicates.or(predicates.hasPath(fileToFind), + predicates.hasRelativePath(fileToFind)); final InputFile file = fileSystem.inputFile(predicate); - if(Objects.nonNull(file)) { + if (Objects.nonNull(file)) { final String repositoryKey = ICodeRulesDefinition.getRepositoryKeyForLanguage(file.language()); final RuleKey ruleKey = RuleKey.of(repositoryKey, result.getName()); final NewIssueLocation location = issue.newLocation(); - final TextRange textRange = file.selectLine(result.getLine()>0?result.getLine():1); + final TextRange textRange = file.selectLine(result.getLine() > 0 ? result.getLine() : 1); location.on(file); location.at(textRange); location.message(result.getMessage()); @@ -285,24 +302,26 @@ static void saveIssue(final SensorContext sensorContext, final CheckResult resul * This method save an issue into the SonarQube service. * * @param context A SensorContext to reach SonarQube services. - * @param files Map containing files in SQ format. - * @param issue A AnalysisRule with the convenient format for i-Code. + * @param files Map containing files in SQ format. + * @param issue A AnalysisRule with the convenient format for i-Code. */ static void saveIssue(final SensorContext context, final Map files, final AnalysisRule issue) { // Retrieve the file containing the issue. final InputFile inputFile = files.getOrDefault(issue.getResult().getFileName(), null); - if(inputFile!=null) { + if (inputFile != null) { // Retrieve the ruleKey if it exists. - final RuleKey ruleKey = RuleKey.of(ICodeRulesDefinition.getRepositoryKeyForLanguage(inputFile.language()), issue.getAnalysisRuleId()); + final RuleKey ruleKey = RuleKey.of(ICodeRulesDefinition.getRepositoryKeyForLanguage(inputFile.language()), + issue.getAnalysisRuleId()); // Create a new issue for SonarQube, but it must be saved using NewIssue.save(). final NewIssue newIssue = context.newIssue(); // Create a new location for this issue. final NewIssueLocation newIssueLocation = newIssue.newLocation(); - // Calculate the line number of the issue (must be between 1 and max, otherwise 1). + // Calculate the line number of the issue (must be between 1 and max, otherwise + // 1). int issueLine = Integer.parseInt(issue.getResult().getResultLine()); issueLine = issueLine > 0 && issueLine <= inputFile.lines() ? issueLine : 1; @@ -316,8 +335,7 @@ static void saveIssue(final SensorContext context, final Map } else { LOGGER.error(String.format( "Issue '%s' on file '%s' has not been saved because source file was not found.", - issue.getAnalysisRuleId(), issue.getResult().getFileName() - )); + issue.getAnalysisRuleId(), issue.getResult().getFileName())); } } @@ -325,22 +343,24 @@ static void saveIssue(final SensorContext context, final Map /** * Construct a map with all found source files. * - * @param fileSystem The file system on which the analysis is running. + * @param fileSystem The file system on which the analysis is running. * @param analysisProject The i-Code report content. * @return A possibly empty Map of InputFile. */ - protected Map getScannedFiles(final FileSystem fileSystem, final AnalysisProject analysisProject) { + protected Map getScannedFiles(final FileSystem fileSystem, + final AnalysisProject analysisProject) { // Contains the result to be returned. final Map result = new HashMap<>(); final List files = analysisProject.getAnalysisFiles(); // Looks for each file in file system, print an error if not found. - for(final AnalysisFile file : files) { - // Checks if the file system contains a file with corresponding path (relative or absolute). + for (final AnalysisFile file : files) { + // Checks if the file system contains a file with corresponding path (relative + // or absolute). final String fileToFind = new File(fileSystem.baseDir(), file.getFileName()).getPath(); final FilePredicate predicate = fileSystem.predicates().hasPath(fileToFind); final InputFile inputFile = fileSystem.inputFile(predicate); - if(inputFile!=null) { + if (inputFile != null) { result.put(file.getFileName(), inputFile); } else { LOGGER.error(String.format("The source file '%s' was not found.", file.getFileName())); @@ -353,7 +373,7 @@ protected Map getScannedFiles(final FileSystem fileSystem, fi /** * Returns a list of processable result files. * - * @param config Configuration of the analysis where properties are put. + * @param config Configuration of the analysis where properties are put. * @param fileSystem The current file system. * @return Return a list of path 'findable' in the file system. */ @@ -364,11 +384,12 @@ protected List getReportFiles(final Configuration config, final FileSystem // Retrieves the non-verified path list from the SonarQube property. final String[] pathArray = config.getStringArray(ICodePluginProperties.REPORT_PATH_KEY); - // Check if each path is known by the file system and add it to the processable path list, + // Check if each path is known by the file system and add it to the processable + // path list, // otherwise print a warning and ignore this result file. - for(final String path : pathArray) { + for (final String path : pathArray) { final File file = new File(fileSystem.baseDir(), path); - if(file.exists() && file.isFile()) { + if (file.exists() && file.isFile()) { result.add(file); LOGGER.info(String.format("Results file %s has been found and will be processed.", path)); } else { @@ -383,18 +404,16 @@ protected List getReportFiles(final Configuration config, final FileSystem * Check if a rule is activated in current analysis. * * @param activeRules Set of active rules during an analysis. - * @param rule Key (i-Code) of the rule to check. + * @param rule Key (i-Code) of the rule to check. * @return True if the rule is active and false if not or not exists. */ protected boolean isRuleActive(final ActiveRules activeRules, final String rule) { boolean isActive = false; for (String Lang : languages) { RuleKey ruleKey = RuleKey.of(ICodeRulesDefinition.getRepositoryKeyForLanguage(Lang), rule); - isActive = activeRules.find(ruleKey)!=null || isActive; + isActive = activeRules.find(ruleKey) != null || isActive; } return isActive; } } - - diff --git a/src/main/java/fr/cnes/sonar/plugins/icode/languages/ICodeLanguage.java b/src/main/java/fr/cnes/sonar/plugins/icode/languages/ICodeLanguage.java index 91f6b4f..619f8e8 100644 --- a/src/main/java/fr/cnes/sonar/plugins/icode/languages/ICodeLanguage.java +++ b/src/main/java/fr/cnes/sonar/plugins/icode/languages/ICodeLanguage.java @@ -16,13 +16,13 @@ */ package fr.cnes.sonar.plugins.icode.languages; -import org.apache.commons.lang.StringUtils; -import org.sonar.api.config.Configuration; -import org.sonar.api.resources.AbstractLanguage; - import java.util.ArrayList; import java.util.List; +import org.apache.commons.lang3.StringUtils; +import org.sonar.api.config.Configuration; +import org.sonar.api.resources.AbstractLanguage; + /** * Declared language i-Code as the parent language for Fortran 77, Fortran 90. */ @@ -37,8 +37,8 @@ public abstract class ICodeLanguage extends AbstractLanguage { * i-Code extension for i-Code specific properties, Metrics and Rules. * * @param configuration Inject SonarQube configuration into this extension. - * @param key Key of the language to set. - * @param name Name of the language to set. + * @param key Key of the language to set. + * @param name Name of the language to set. */ public ICodeLanguage(final Configuration configuration, final String key, final String name) { super(key, name); @@ -75,20 +75,20 @@ public String[] getFileSuffixes() { /** * Delete all empty string values into a input String array. - * + * * @param stringArray Input String array. * * @return Output String array without empty string values. */ - public static String[] filterEmptyStrings(final String[] stringArray) { - List nonEmptyStrings = new ArrayList<>(); - for (final String string : stringArray) { - if (StringUtils.isNotBlank(string.trim())) { - nonEmptyStrings.add(string.trim()); - } - } - return nonEmptyStrings.toArray(new String[nonEmptyStrings.size()]); - } + public static String[] filterEmptyStrings(final String[] stringArray) { + List nonEmptyStrings = new ArrayList<>(); + for (final String string : stringArray) { + if (StringUtils.isNotBlank(string.trim())) { + nonEmptyStrings.add(string.trim()); + } + } + return nonEmptyStrings.toArray(new String[nonEmptyStrings.size()]); + } /** * Assert obj is the same object as this. @@ -98,7 +98,7 @@ public static String[] filterEmptyStrings(final String[] stringArray) { */ @Override public boolean equals(final Object obj) { - return obj==this; + return super.equals(obj); } /** diff --git a/src/main/java/fr/cnes/sonar/plugins/icode/languages/ICodeQualityProfiles.java b/src/main/java/fr/cnes/sonar/plugins/icode/languages/ICodeQualityProfiles.java index bb68283..a24e9f8 100644 --- a/src/main/java/fr/cnes/sonar/plugins/icode/languages/ICodeQualityProfiles.java +++ b/src/main/java/fr/cnes/sonar/plugins/icode/languages/ICodeQualityProfiles.java @@ -16,15 +16,15 @@ */ package fr.cnes.sonar.plugins.icode.languages; -import fr.cnes.sonar.plugins.icode.rules.ICodeRulesDefinition; -import fr.cnes.sonar.plugins.icode.rules.RulesRepository; +import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition; -import org.sonar.api.utils.log.Logger; -import org.sonar.api.utils.log.Loggers; import org.sonar.api.server.rule.RulesDefinition.NewRule; -import java.util.List; +import fr.cnes.sonar.plugins.icode.rules.ICodeRulesDefinition; +import fr.cnes.sonar.plugins.icode.rules.RulesRepository; /** * Built-in quality profile format since SonarQube 9.9 @@ -32,7 +32,7 @@ public final class ICodeQualityProfiles implements BuiltInQualityProfilesDefinition { /** Logger for this class. **/ - private static final Logger LOGGER = Loggers.get(ICodeQualityProfiles.class); + private static final Logger LOGGER = LoggerFactory.getLogger(ICodeQualityProfiles.class); /** Display name for the built-in quality profile. **/ private static final String I_CODE_RULES_PROFILE_NAME = "Sonar way"; @@ -54,12 +54,13 @@ public void define(final Context context) { /** * Create a built in quality profile for a specific language. * - * @param context SonarQube context in which create the profile. + * @param context SonarQube context in which create the profile. * @param repository Rules' repository. - * @param language Language key of the associated profile. - * @param rules Rules to activate. + * @param language Language key of the associated profile. + * @param rules Rules to activate. */ - private void createBuiltInProfile(final Context context, final String repository, final String languageKey, final List rules) { + private void createBuiltInProfile(final Context context, final String repository, final String languageKey, + final List rules) { // Create a builder for the rules' repository. NewBuiltInQualityProfile profile = context.createBuiltInQualityProfile(I_CODE_RULES_PROFILE_NAME, languageKey); @@ -70,6 +71,7 @@ private void createBuiltInProfile(final Context context, final String repository } profile.setDefault(true); profile.done(); - LOGGER.info(String.format("%s rules are activated for the repository %s.", profile.activeRules().size(), repository)); + LOGGER.info(String.format("%s rules are activated for the repository %s.", profile.activeRules().size(), + repository)); } } \ No newline at end of file diff --git a/src/main/java/fr/cnes/sonar/plugins/icode/measures/ICodeMetricsProcessor.java b/src/main/java/fr/cnes/sonar/plugins/icode/measures/ICodeMetricsProcessor.java index 6a48c17..67c36e8 100644 --- a/src/main/java/fr/cnes/sonar/plugins/icode/measures/ICodeMetricsProcessor.java +++ b/src/main/java/fr/cnes/sonar/plugins/icode/measures/ICodeMetricsProcessor.java @@ -16,9 +16,14 @@ */ package fr.cnes.sonar.plugins.icode.measures; -import fr.cnes.icode.data.CheckResult; -import fr.cnes.sonar.plugins.icode.model.AnalysisProject; -import fr.cnes.sonar.plugins.icode.model.AnalysisRule; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.sonar.api.batch.fs.FilePredicates; import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.batch.fs.InputComponent; @@ -27,10 +32,10 @@ import org.sonar.api.batch.sensor.measure.NewMeasure; import org.sonar.api.measures.CoreMetrics; import org.sonar.api.measures.Metric; -import org.sonar.api.utils.log.Logger; -import org.sonar.api.utils.log.Loggers; -import java.util.*; +import fr.cnes.icode.data.CheckResult; +import fr.cnes.sonar.plugins.icode.model.AnalysisProject; +import fr.cnes.sonar.plugins.icode.model.AnalysisRule; /** * Executed during sonar-scanner call. @@ -39,7 +44,7 @@ public class ICodeMetricsProcessor { /** Logger for this class. **/ - private static final Logger LOGGER = Loggers.get(ICodeMetricsProcessor.class); + private static final Logger LOGGER = LoggerFactory.getLogger(ICodeMetricsProcessor.class); /** Shared part between all i-Code metrics key. **/ private static final String COMMON_METRICS_KEY_PART = ".MET."; @@ -50,7 +55,8 @@ public class ICodeMetricsProcessor { /** * Private constructor because this class contains only static methods. */ - private ICodeMetricsProcessor(){} + private ICodeMetricsProcessor() { + } /** * Determine if an i-Code rule is a metric. @@ -65,17 +71,17 @@ public static boolean isMetric(final String ruleId) { /** * Save a measure in SonarQube from i-Code report format. * - * @param context Context of the analysis containing services. - * @param files Map containing files in SQ format. + * @param context Context of the analysis containing services. + * @param files Map containing files in SQ format. * @param icodeMeasure Measure considered like a rule in i-Code. */ public static void saveMeasure(final SensorContext context, final Map files, - final AnalysisRule icodeMeasure) { + final AnalysisRule icodeMeasure) { // Determine if a measure is relative to a file or a method. final String metricScope = icodeMeasure.getResult().getResultTypePlace(); - if(metricScope.equals(CLASS)) { + if (metricScope.equals(CLASS)) { // Get i-Code rule id to test if issue must be saved here. final String metricKey = icodeMeasure.getAnalysisRuleId(); // Take F77 / F90 ncloc and number of comment lines into account @@ -93,13 +99,13 @@ else if (metricKey.contains("MET.LineOfComment")) { /** * Save an issue or log a warning if the component is not found. * - * @param context SonarQube context in which measure must be saved. - * @param files All files visible by SonarQube. - * @param sonarMetric The SonarQube metric in which the measure must be saved. + * @param context SonarQube context in which measure must be saved. + * @param files All files visible by SonarQube. + * @param sonarMetric The SonarQube metric in which the measure must be saved. * @param icodeMeasure The value of the i-Code measure. */ protected static void saveSonarQubeNewMeasure(final SensorContext context, final Map files, - final Metric sonarMetric, final AnalysisRule icodeMeasure) { + final Metric sonarMetric, final AnalysisRule icodeMeasure) { // Component concerned by the measure. final String metricComponent = icodeMeasure.getResult().getFileName(); @@ -126,21 +132,21 @@ protected static void saveSonarQubeNewMeasure(final SensorContext context, final /** * Save extra measures from report analysis. * - * @param context Context of the analysis containing services. + * @param context Context of the analysis containing services. * @param scannedFiles Available files. - * @param project Complete i-Code report. + * @param project Complete i-Code report. */ public static void saveExtraMeasures(final SensorContext context, final Map scannedFiles, - final AnalysisProject project) { + final AnalysisProject project) { // Contains all measures final Map> measures = new HashMap<>(); // Collect all measures on methods into specific list - for(final AnalysisRule rule : project.getAnalysisRules()) { + for (final AnalysisRule rule : project.getAnalysisRules()) { final String type = rule.getResult().getResultTypePlace(); final String id = rule.getAnalysisRuleId(); - if(id.contains(COMMON_METRICS_KEY_PART) && type.equals(METHOD)) { + if (id.contains(COMMON_METRICS_KEY_PART) && type.equals(METHOD)) { final List sub = measures.getOrDefault(id, new ArrayList<>()); sub.add(rule); measures.put(id, sub); @@ -159,22 +165,22 @@ public static void saveExtraMeasures(final SensorContext context, final Map scannedFiles, - final List results) { + final List results) { // Contains all measures final Map> measures = new HashMap<>(); // Collect all measures on methods into specific list - for(final CheckResult result : results) { - final String type = Objects.isNull(result.getLocation()) || result.getLocation().isEmpty() ? - CLASS : result.getLocation(); + for (final CheckResult result : results) { + final String type = Objects.isNull(result.getLocation()) || result.getLocation().isEmpty() ? CLASS + : result.getLocation(); final String id = result.getName(); - if(id.contains(COMMON_METRICS_KEY_PART) && type.equals(METHOD)) { + if (id.contains(COMMON_METRICS_KEY_PART) && type.equals(METHOD)) { final List sub = measures.getOrDefault(id, new ArrayList<>()); final AnalysisRule rule = new AnalysisRule(result); sub.add(rule); @@ -194,25 +200,25 @@ public static void saveExtraMeasures(final SensorContext context, final Map scannedFiles, - final Map> measures) { + final Map> measures) { final Map functions = new HashMap<>(); final List rawMeasures = new ArrayList<>(); // Collect all ncloc measures in one list. - measures.forEach((x,y) -> { - if(x.contains(".MET.Line")) { + measures.forEach((x, y) -> { + if (x.contains(".MET.Line")) { rawMeasures.addAll(y); } }); // Compute number of functions by file. - for(final AnalysisRule measure : rawMeasures) { + for (final AnalysisRule measure : rawMeasures) { final String file = measure.getResult().getFileName(); Integer sum = functions.getOrDefault(file, 0) + 1; functions.put(file, sum); @@ -225,25 +231,25 @@ private static void computeFunctions(final SensorContext context, final Map scannedFiles, - final Map> measures) { + final Map> measures) { final Map complexity = new HashMap<>(); final List rawMeasures = new ArrayList<>(); // Collect all fortran complexity measures in one list. - measures.forEach((x,y) -> { - if(x.contains("F77.MET.ComplexitySimplified")||x.contains("F90.MET.ComplexitySimplified")) { + measures.forEach((x, y) -> { + if (x.contains("F77.MET.ComplexitySimplified") || x.contains("F90.MET.ComplexitySimplified")) { rawMeasures.addAll(y); } }); // Compute complexity sum value by file. - for(final AnalysisRule measure : rawMeasures) { + for (final AnalysisRule measure : rawMeasures) { final String file = measure.getResult().getFileName(); final Integer value = Double.valueOf((measure.getResult().getResultValue())).intValue(); Integer sum = complexity.getOrDefault(file, 0); @@ -259,28 +265,28 @@ private static void computeComplexity(final SensorContext context, final Map scannedFiles, - final Map> measures) { + final Map> measures) { final Map nesting = new HashMap<>(); final List rawMeasures = new ArrayList<>(); // collect all nesting measures in one list - measures.forEach((x,y) -> { - if(x.contains(".MET.Nesting")) { + measures.forEach((x, y) -> { + if (x.contains(".MET.Nesting")) { rawMeasures.addAll(y); } }); // compute max nesting value by file - for(final AnalysisRule measure : rawMeasures) { + for (final AnalysisRule measure : rawMeasures) { final String file = measure.getResult().getFileName(); final Integer value = Double.valueOf((measure.getResult().getResultValue())).intValue(); Integer max = nesting.getOrDefault(file, 0); - max = Math.max(max,value); + max = Math.max(max, value); nesting.put(file, max); } @@ -292,18 +298,18 @@ private static void computeNesting(final SensorContext context, final Map scannedFiles, - final String filename, final Integer value, final Metric metric) { + final String filename, final Integer value, final Metric metric) { // Retrieve the file. final InputFile file = scannedFiles.getOrDefault(filename, null); // Create a new measure from the scan context if the file exists. - if(file!=null) { + if (file != null) { final NewMeasure newMeasure = context.newMeasure(); newMeasure.forMetric(metric); newMeasure.withValue(value); @@ -313,8 +319,7 @@ private static void saveMeasure(final SensorContext context, final Map rules = new ArrayList<>(); try { InputStream inputFile = this.getClass().getResourceAsStream(pathToRulesXml); - + if (inputFile == null) { repository.done(); if (language.equals(FORTRAN77_LANGUAGE)) { @@ -97,7 +97,7 @@ protected void createFortranRepository(final Context context, final String langu } else { RulesRepository.getInstance().setF90Rules(rules); } - + } DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); @@ -118,21 +118,24 @@ protected void createFortranRepository(final Context context, final String langu String internalKey = element.getElementsByTagName("internalKey").item(0).getTextContent(); String description = element.getElementsByTagName("description").item(0).getTextContent(); String severity = element.getElementsByTagName("severity").item(0).getTextContent(); - RuleStatus status = RuleStatus.valueOf(element.getElementsByTagName("status").item(0).getTextContent()); + RuleStatus status = RuleStatus + .valueOf(element.getElementsByTagName("status").item(0).getTextContent()); RuleType type = RuleType.valueOf(element.getElementsByTagName("type").item(0).getTextContent()); - String remediationFunctionBaseEffort = element.getElementsByTagName("remediationFunctionBaseEffort").item(0).getTextContent(); + String remediationFunctionBaseEffort = element.getElementsByTagName("remediationFunctionBaseEffort") + .item(0).getTextContent(); RuleKey ruleKey = RuleKey.of(repositoryName, key); NewRule rule = repository.createRule(ruleKey.rule()) - .setName(name) - .setInternalKey(internalKey) - .setHtmlDescription(description) - .setSeverity(severity) - .setStatus(status) - .setType(type); - - rule.setDebtRemediationFunction(rule.debtRemediationFunctions().constantPerIssue(remediationFunctionBaseEffort)); + .setName(name) + .setInternalKey(internalKey) + .setHtmlDescription(description) + .setSeverity(severity) + .setStatus(status) + .setType(type); + + rule.setDebtRemediationFunction( + rule.debtRemediationFunctions().constantPerIssue(remediationFunctionBaseEffort)); rules.add(rule); LOGGER.info(String.format("Rule %s created.", rule.toString())); } @@ -145,16 +148,16 @@ protected void createFortranRepository(final Context context, final String langu RulesRepository.getInstance().setF77Rules(rules); } else { RulesRepository.getInstance().setF90Rules(rules); - } + } } /** - * Getter for repository key. + * Getter for repository key. * * @param language Key of the related language. - * @return A string "language-key". - */ - public static String getRepositoryKeyForLanguage(final String language) { - return language + REPO_KEY_SUFFIX; - } + * @return A string "language-key". + */ + public static String getRepositoryKeyForLanguage(final String language) { + return language + REPO_KEY_SUFFIX; + } } \ No newline at end of file diff --git a/src/main/java/fr/cnes/sonar/plugins/icode/settings/ICodePluginProperties.java b/src/main/java/fr/cnes/sonar/plugins/icode/settings/ICodePluginProperties.java index b0de1ae..7c04ca4 100644 --- a/src/main/java/fr/cnes/sonar/plugins/icode/settings/ICodePluginProperties.java +++ b/src/main/java/fr/cnes/sonar/plugins/icode/settings/ICodePluginProperties.java @@ -16,186 +16,179 @@ */ package fr.cnes.sonar.plugins.icode.settings; -import org.sonar.api.PropertyType; -import org.sonar.api.config.PropertyDefinition; -import org.sonar.api.resources.Qualifiers; - import java.util.Arrays; import java.util.List; +import org.sonar.api.PropertyType; +import org.sonar.api.config.PropertyDefinition; + /** * Define all SonarQube properties provided by this plugin. */ public class ICodePluginProperties { - /** - * i-Code CNES default location's path value. - */ - public static final String ICODE_PATH_DEFAULT = "icode"; + /** + * i-Code CNES default location's path value. + */ + public static final String ICODE_PATH_DEFAULT = "icode"; - /** - * Prefix used by all properties of this plugin. - **/ - private static final String PROPERTIES_PREFIX = "sonar.icode."; + /** + * Prefix used by all properties of this plugin. + **/ + private static final String PROPERTIES_PREFIX = "sonar.icode."; - /** - * i-Code name. - **/ - public static final String ICODE_NAME = "i-Code CNES"; - + /** + * i-Code name. + **/ + public static final String ICODE_NAME = "i-Code CNES"; - // project code file patterns - /** - * Key for the F77 suffix property - **/ - public static final String F77_SUFFIX_KEY = PROPERTIES_PREFIX + "f77.file.suffixes"; - /** - * Default value for the code suffix property - **/ - public static final String F77_SUFFIX_DEFAULT = ".f,.f77,.for,.fpp,.ftn,.F,.F77,.FOR,.FPP,.FTN"; - /** - * Name for the code suffix property - **/ - public static final String F77_SUFFIX_NAME = "Fortran 77 File Suffixes"; - /** - * Description for the code suffix property - **/ - public static final String F77_SUFFIX_DESC = "List of suffixes for Fortran 77 files to analyze."; + // project code file patterns + /** + * Key for the F77 suffix property + **/ + public static final String F77_SUFFIX_KEY = "sonar.f77.file.suffixes"; + /** + * Default value for the code suffix property + **/ + public static final String F77_SUFFIX_DEFAULT = ".f,.f77,.for,.fpp,.ftn,.F,.F77,.FOR,.FPP,.FTN"; + /** + * Name for the code suffix property + **/ + public static final String F77_SUFFIX_NAME = "Fortran 77 File Suffixes"; + /** + * Description for the code suffix property + **/ + public static final String F77_SUFFIX_DESC = "List of suffixes for Fortran 77 files to analyze."; - // project code file patterns - /** - * Key for the F90 suffix property - **/ - public static final String F90_SUFFIX_KEY = PROPERTIES_PREFIX + "f90.file.suffixes"; - /** - * Default value for the code suffix property - **/ - public static final String F90_SUFFIX_DEFAULT = ".f90,.F90"; - /** - * Name for the code suffix property - **/ - public static final String F90_SUFFIX_NAME = "Fortran 90 File Suffixes"; - /** - * Description for the code suffix property - **/ - public static final String F90_SUFFIX_DESC = "List of suffixes for Fortran 90 files to analyze."; + // project code file patterns + /** + * Key for the F90 suffix property + **/ + public static final String F90_SUFFIX_KEY = "sonar.f90.file.suffixes"; + /** + * Default value for the code suffix property + **/ + public static final String F90_SUFFIX_DEFAULT = ".f90,.F90"; + /** + * Name for the code suffix property + **/ + public static final String F90_SUFFIX_NAME = "Fortran 90 File Suffixes"; + /** + * Description for the code suffix property + **/ + public static final String F90_SUFFIX_DESC = "List of suffixes for Fortran 90 files to analyze."; - // Reports path - /** - * Key for the report path property - **/ - public static final String REPORT_PATH_KEY = PROPERTIES_PREFIX + "reports.path"; - /** - * Name for the report path property - **/ - public static final String REPORT_PATH_NAME = "Report files"; - /** - * Description for the report path property - **/ - public static final String REPORT_PATH_DESC = "Path to the i-Code reports. Multiple path can be provided."; - /** - * Default value for the report path property - **/ - public static final String REPORT_PATH_DEFAULT = ""; - /** - * i-Code CNES launching mode key - */ - public static final String AUTOLAUNCH_PROP_KEY = PROPERTIES_PREFIX + "launch"; - /** - * i-Code CNES launching mode default value - */ - public static final String AUTOLAUNCH_PROP_DEFAULT = "false"; - /** - * Launching mode name - */ - public static final String AUTOLAUNCH_PROP_NAME = "i-Code CNES auto-launch"; - /** - * Launching mode description - */ - public static final String AUTOLAUNCH_PROP_DESC = "Auto-launch i-Code CNES on analysis using indicated location."; - /** - * Embedded i-Code CNES execution activation - */ - public static final String USE_EMBEDDED_PROP_KEY = PROPERTIES_PREFIX + "embedded"; - /** - * Embedded i-Code CNES execution activation default value - */ - public static final String USE_EMBEDDED_PROP_DEFAULT = "true"; - /** - * Embedded i-Code CNES execution activation name - */ - public static final String USE_EMBEDDED_PROP_NAME = "Run embedded i-Code CNES"; - /** - * Embedded i-Code CNES execution activation description - */ - public static final String USE_EMBEDDED_PROP_DESC = "Run i-Code CNES version provided with this plugin during the analysis."; - /** - * i-Code CNES location's path key - */ - public static final String ICODE_PATH_KEY = PROPERTIES_PREFIX + "path"; - /** - * i-Code CNES location's path key - */ - public static final String ICODE_PATH_NAME = "i-Code CNES location"; - /** - * i-Code CNES location's path key - */ - public static final String ICODE_PATH_DESC = "Define i-Code CNES executable path to auto-launch it on analysis."; + // Reports path + /** + * Key for the report path property + **/ + public static final String REPORT_PATH_KEY = PROPERTIES_PREFIX + "reports.path"; + /** + * Name for the report path property + **/ + public static final String REPORT_PATH_NAME = "Report files"; + /** + * Description for the report path property + **/ + public static final String REPORT_PATH_DESC = "Path to the i-Code reports. Multiple path can be provided."; + /** + * Default value for the report path property + **/ + public static final String REPORT_PATH_DEFAULT = ""; + /** + * i-Code CNES launching mode key + */ + public static final String AUTOLAUNCH_PROP_KEY = PROPERTIES_PREFIX + "launch"; + /** + * i-Code CNES launching mode default value + */ + public static final String AUTOLAUNCH_PROP_DEFAULT = "false"; + /** + * Launching mode name + */ + public static final String AUTOLAUNCH_PROP_NAME = "i-Code CNES auto-launch"; + /** + * Launching mode description + */ + public static final String AUTOLAUNCH_PROP_DESC = "Auto-launch i-Code CNES on analysis using indicated location."; + /** + * Embedded i-Code CNES execution activation + */ + public static final String USE_EMBEDDED_PROP_KEY = PROPERTIES_PREFIX + "embedded"; + /** + * Embedded i-Code CNES execution activation default value + */ + public static final String USE_EMBEDDED_PROP_DEFAULT = "true"; + /** + * Embedded i-Code CNES execution activation name + */ + public static final String USE_EMBEDDED_PROP_NAME = "Run embedded i-Code CNES"; + /** + * Embedded i-Code CNES execution activation description + */ + public static final String USE_EMBEDDED_PROP_DESC = "Run i-Code CNES version provided with this plugin during the analysis."; + /** + * i-Code CNES location's path key + */ + public static final String ICODE_PATH_KEY = PROPERTIES_PREFIX + "path"; + /** + * i-Code CNES location's path key + */ + public static final String ICODE_PATH_NAME = "i-Code CNES location"; + /** + * i-Code CNES location's path key + */ + public static final String ICODE_PATH_DESC = "Define i-Code CNES executable path to auto-launch it on analysis."; - private ICodePluginProperties() { - super(); - } + private ICodePluginProperties() { + super(); + } - /** - * Plugin properties extensions. - * - * @return The list of built properties. - */ - public static List getProperties() { - return Arrays.asList( - PropertyDefinition.builder(USE_EMBEDDED_PROP_KEY) - .defaultValue(USE_EMBEDDED_PROP_DEFAULT) - .category(ICODE_NAME) - .name(USE_EMBEDDED_PROP_NAME) - .description(USE_EMBEDDED_PROP_DESC) - .type(PropertyType.BOOLEAN) - .onQualifiers(Qualifiers.PROJECT) - .build() - , - PropertyDefinition.builder(AUTOLAUNCH_PROP_KEY) - .defaultValue(AUTOLAUNCH_PROP_DEFAULT) - .category(ICODE_NAME) - .name(AUTOLAUNCH_PROP_NAME) - .description(AUTOLAUNCH_PROP_DESC) - .type(PropertyType.BOOLEAN) - .onQualifiers(Qualifiers.PROJECT) - .build() - , - PropertyDefinition.builder(ICODE_PATH_KEY) - .defaultValue(ICODE_PATH_DEFAULT) - .category(ICODE_NAME) - .name(ICODE_PATH_NAME) - .description(ICODE_PATH_DESC) - .onQualifiers(Qualifiers.PROJECT) - .build() - , - PropertyDefinition.builder(F77_SUFFIX_KEY).multiValues(true) - .defaultValue(F77_SUFFIX_DEFAULT).category(ICODE_NAME) - .name(F77_SUFFIX_NAME).description(F77_SUFFIX_DESC) - .onQualifiers(Qualifiers.PROJECT) - .build() - , - PropertyDefinition.builder(F90_SUFFIX_KEY).multiValues(true) - .defaultValue(F90_SUFFIX_DEFAULT).category(ICODE_NAME) - .name(F90_SUFFIX_NAME).description(F90_SUFFIX_DESC) - .onQualifiers(Qualifiers.PROJECT) - .build() - , - PropertyDefinition.builder(REPORT_PATH_KEY).multiValues(true) - .defaultValue(REPORT_PATH_DEFAULT).category(ICODE_NAME) - .name(REPORT_PATH_NAME).description(REPORT_PATH_DESC) - .onQualifiers(Qualifiers.PROJECT) - .build()); - } + /** + * Plugin properties extensions. + * + * @return The list of built properties. + */ + public static List getProperties() { + return Arrays.asList( + PropertyDefinition.builder(USE_EMBEDDED_PROP_KEY) + .defaultValue(USE_EMBEDDED_PROP_DEFAULT) + .category(ICODE_NAME) + .name(USE_EMBEDDED_PROP_NAME) + .description(USE_EMBEDDED_PROP_DESC) + .type(PropertyType.BOOLEAN) + .onConfigScopes(PropertyDefinition.ConfigScope.PROJECT) + .build(), + PropertyDefinition.builder(AUTOLAUNCH_PROP_KEY) + .defaultValue(AUTOLAUNCH_PROP_DEFAULT) + .category(ICODE_NAME) + .name(AUTOLAUNCH_PROP_NAME) + .description(AUTOLAUNCH_PROP_DESC) + .type(PropertyType.BOOLEAN) + .onConfigScopes(PropertyDefinition.ConfigScope.PROJECT) + .build(), + PropertyDefinition.builder(ICODE_PATH_KEY) + .defaultValue(ICODE_PATH_DEFAULT) + .category(ICODE_NAME) + .name(ICODE_PATH_NAME) + .description(ICODE_PATH_DESC) + .onConfigScopes(PropertyDefinition.ConfigScope.PROJECT) + .build(), + PropertyDefinition.builder(F77_SUFFIX_KEY).multiValues(true) + .defaultValue(F77_SUFFIX_DEFAULT).category(ICODE_NAME) + .name(F77_SUFFIX_NAME).description(F77_SUFFIX_DESC) + .onConfigScopes(PropertyDefinition.ConfigScope.PROJECT) + .build(), + PropertyDefinition.builder(F90_SUFFIX_KEY).multiValues(true) + .defaultValue(F90_SUFFIX_DEFAULT).category(ICODE_NAME) + .name(F90_SUFFIX_NAME).description(F90_SUFFIX_DESC) + .onConfigScopes(PropertyDefinition.ConfigScope.PROJECT) + .build(), + PropertyDefinition.builder(REPORT_PATH_KEY).multiValues(true) + .defaultValue(REPORT_PATH_DEFAULT).category(ICODE_NAME) + .name(REPORT_PATH_NAME).description(REPORT_PATH_DESC) + .onConfigScopes(PropertyDefinition.ConfigScope.PROJECT) + .build()); + } } diff --git a/src/test/java/fr/cnes/sonar/plugins/icode/check/ICodeSensorTest.java b/src/test/java/fr/cnes/sonar/plugins/icode/check/ICodeSensorTest.java index 8bb0357..3beaafb 100644 --- a/src/test/java/fr/cnes/sonar/plugins/icode/check/ICodeSensorTest.java +++ b/src/test/java/fr/cnes/sonar/plugins/icode/check/ICodeSensorTest.java @@ -16,12 +16,15 @@ */ package fr.cnes.sonar.plugins.icode.check; -import fr.cnes.sonar.plugins.icode.languages.Fortran77Language; -import fr.cnes.sonar.plugins.icode.model.AnalysisFile; -import fr.cnes.sonar.plugins.icode.model.AnalysisProject; -import fr.cnes.sonar.plugins.icode.model.AnalysisRule; -import fr.cnes.sonar.plugins.icode.model.Result; -import fr.cnes.sonar.plugins.icode.settings.ICodePluginProperties; +import static org.mockito.Mockito.verify; + +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; + import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -29,21 +32,17 @@ import org.mockito.Mockito; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.internal.DefaultFileSystem; -import org.sonar.api.batch.fs.FileSystem; import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.batch.sensor.SensorDescriptor; import org.sonar.api.batch.sensor.internal.SensorContextTester; import org.sonar.api.config.internal.MapSettings; -import java.io.File; -import java.io.IOException; -import java.net.URISyntaxException; -import java.nio.charset.StandardCharsets; -import java.util.HashMap; -import java.util.Map; - -import static org.mockito.Mockito.verify; +import fr.cnes.sonar.plugins.icode.model.AnalysisFile; +import fr.cnes.sonar.plugins.icode.model.AnalysisProject; +import fr.cnes.sonar.plugins.icode.model.AnalysisRule; +import fr.cnes.sonar.plugins.icode.model.Result; +import fr.cnes.sonar.plugins.icode.settings.ICodePluginProperties; public class ICodeSensorTest { @@ -59,31 +58,31 @@ public class ICodeSensorTest { public void prepare() throws URISyntaxException { fs = new DefaultFileSystem(new File(getClass().getResource("/project").toURI())); fs.setEncoding(StandardCharsets.UTF_8); - - clanhb_f = TestInputFileBuilder.create("ProjectKey", fs.baseDir(), new File(getClass().getResource("/project/clanhb.f").toURI())) + + clanhb_f = TestInputFileBuilder + .create("ProjectKey", fs.baseDir(), new File(getClass().getResource("/project/clanhb.f").toURI())) .setLanguage("icode") .setType(InputFile.Type.MAIN) .setLines(10) - .setOriginalLineStartOffsets(new int[]{0,0,0,0,0,0,0,0,0,0}) + .setOriginalLineStartOffsets(new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }) .setLastValidOffset(100) .build(); fs.add(clanhb_f); - clanhb_f90 = TestInputFileBuilder.create("ProjectKey", fs.baseDir(), new File(getClass().getResource("/project/clanhb.f90").toURI())) + clanhb_f90 = TestInputFileBuilder + .create("ProjectKey", fs.baseDir(), new File(getClass().getResource("/project/clanhb.f90").toURI())) .setLanguage("icode") .setType(InputFile.Type.MAIN) .setLines(10) - .setOriginalLineStartOffsets(new int[]{0,0,0,0,0,0,0,0,0,0}) + .setOriginalLineStartOffsets(new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }) .setLastValidOffset(100) .build(); fs.add(clanhb_f90); - context = SensorContextTester.create(fs.baseDir()); files = new HashMap<>(); rule = new AnalysisRule(); - files.put("clanhb.f", clanhb_f); files.put("clanhb.f90", clanhb_f90); @@ -115,7 +114,7 @@ public void test_run_internal_icode_in_nominal_situation() { try { sensor.execute(context); Assertions.assertTrue(true); - } catch(final Exception e) { + } catch (final Exception e) { Assertions.fail(); } } @@ -142,7 +141,7 @@ public void test_normal_work_with_icode_launch_failed() { try { sensor.execute(context); Assertions.assertTrue(true); - } catch(final Exception e) { + } catch (final Exception e) { Assertions.fail(); } } @@ -226,7 +225,7 @@ public void test_run_a_command() throws IOException, InterruptedException { final ICodeSensor sensor = new ICodeSensor(); final int value = sensor.runICode("java -version"); - + Assert.assertEquals(0, value); } @@ -239,7 +238,7 @@ public void test_get_scanned_files() { file.setFileName("clanhb.f"); file.setLanguage("f77"); - project.setAnalysisFile(new AnalysisFile[]{file}); + project.setAnalysisFile(new AnalysisFile[] { file }); Assert.assertNotNull(sensor); @@ -248,7 +247,6 @@ public void test_get_scanned_files() { Assert.assertEquals(1, relevantFile.size()); } - @Test public void test_get_scanned_files_f90() { final ICodeSensor sensor = new ICodeSensor(); @@ -258,7 +256,7 @@ public void test_get_scanned_files_f90() { file.setFileName("clanhb.f90"); file.setLanguage("f90"); - project.setAnalysisFile(new AnalysisFile[]{file}); + project.setAnalysisFile(new AnalysisFile[] { file }); Assert.assertNotNull(sensor); @@ -267,7 +265,6 @@ public void test_get_scanned_files_f90() { Assert.assertEquals(1, relevantFile.size()); } - @Test public void test_save_issue_with_unknown_file() { rule.setResult(new Result()); diff --git a/src/test/java/fr/cnes/sonar/plugins/icode/languages/ICodeLanguagesTest.java b/src/test/java/fr/cnes/sonar/plugins/icode/languages/ICodeLanguagesTest.java index 4af8fac..edf3b3b 100644 --- a/src/test/java/fr/cnes/sonar/plugins/icode/languages/ICodeLanguagesTest.java +++ b/src/test/java/fr/cnes/sonar/plugins/icode/languages/ICodeLanguagesTest.java @@ -16,14 +16,12 @@ */ package fr.cnes.sonar.plugins.icode.languages; -import fr.cnes.sonar.plugins.icode.settings.ICodePluginProperties; -import org.junit.Assert; +import static org.junit.Assert.assertArrayEquals; + import org.junit.Test; import org.sonar.api.config.Configuration; import org.sonar.api.config.internal.MapSettings; -import static org.junit.Assert.assertArrayEquals; - public class ICodeLanguagesTest { @Test @@ -31,9 +29,9 @@ public void test_given_settings_when_getFileSuffixes_then_settings() { Configuration settings = new MapSettings().asConfig(); Fortran77Language fortran77Language = new Fortran77Language(settings); Fortran90Language fortran90Language = new Fortran90Language(settings); - String[] expected = new String[]{".f",".f77",".for",".fpp",".ftn",".F",".F77",".FOR",".FPP",".FTN"}; + String[] expected = new String[] { ".f", ".f77", ".for", ".fpp", ".ftn", ".F", ".F77", ".FOR", ".FPP", ".FTN" }; assertArrayEquals(expected, fortran77Language.getFileSuffixes()); - expected = new String[]{".f90",".F90"}; + expected = new String[] { ".f90", ".F90" }; assertArrayEquals(expected, fortran90Language.getFileSuffixes()); } @@ -53,15 +51,16 @@ public String getDefaultSuffixes() { return ".notstrange,,strange,., "; } }; - String[] expected = new String[]{".notstrange","strange","."}; + String[] expected = new String[] { ".notstrange", "strange", "." }; String[] actual = strangeLanguage.getFileSuffixes(); assertArrayEquals(expected, actual); } @Test public void test_all_possibilities_with_filter_empty_strings() { - String[] expected = new String[]{".notstrange","strange","."}; - String[] actual = ICodeLanguage.filterEmptyStrings(new String[]{".notstrange","","strange","."," "}); + String[] expected = new String[] { ".notstrange", "strange", "." }; + String[] actual = ICodeLanguage + .filterEmptyStrings(new String[] { ".notstrange", "", "strange", ".", " " }); assertArrayEquals(expected, actual); } } diff --git a/src/test/java/fr/cnes/sonar/plugins/icode/measures/ICodeMetricsProcessorTest.java b/src/test/java/fr/cnes/sonar/plugins/icode/measures/ICodeMetricsProcessorTest.java index 91aef77..ff155af 100644 --- a/src/test/java/fr/cnes/sonar/plugins/icode/measures/ICodeMetricsProcessorTest.java +++ b/src/test/java/fr/cnes/sonar/plugins/icode/measures/ICodeMetricsProcessorTest.java @@ -16,32 +16,31 @@ */ package fr.cnes.sonar.plugins.icode.measures; -import fr.cnes.icode.data.CheckResult; -import fr.cnes.sonar.plugins.icode.model.AnalysisProject; -import fr.cnes.sonar.plugins.icode.model.AnalysisRule; -import fr.cnes.sonar.plugins.icode.model.Result; +import java.io.File; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.charset.Charset; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; + import org.junit.Assert; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.Arguments; - -import java.util.stream.Stream; +import org.junit.jupiter.params.provider.MethodSource; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.internal.DefaultFileSystem; import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.batch.sensor.internal.SensorContextTester; -import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure; -import java.io.File; -import java.net.URI; -import java.net.URISyntaxException; -import java.nio.charset.Charset; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import fr.cnes.icode.data.CheckResult; +import fr.cnes.sonar.plugins.icode.model.AnalysisProject; +import fr.cnes.sonar.plugins.icode.model.AnalysisRule; +import fr.cnes.sonar.plugins.icode.model.Result; class ICodeMetricsProcessorTest { @@ -67,12 +66,12 @@ public void prepare() throws URISyntaxException { .build(); fs.add(clanhb_f); - clanhb_f90 = TestInputFileBuilder.create("ProjectKey", fs.baseDir(), new File(getClass().getResource("/project/clanhb.f90").toURI())) + clanhb_f90 = TestInputFileBuilder + .create("ProjectKey", fs.baseDir(), new File(getClass().getResource("/project/clanhb.f90").toURI())) .setLanguage("icode") .setType(InputFile.Type.MAIN) .build(); fs.add(clanhb_f90); - context = SensorContextTester.create(fs.baseDir()); files = new HashMap<>(); @@ -86,8 +85,7 @@ private static Stream testData() { return Stream.of( Arguments.of(new AnalysisRuleTestData("F77.MET.ComplexitySimplified", "clanhb.f", "3")), Arguments.of(new AnalysisRuleTestData("F77.MET.Nesting", "clanhb.f", "3")), - Arguments.of(new AnalysisRuleTestData("F77.MET.Line", "clanhb.f", "3")) - ); + Arguments.of(new AnalysisRuleTestData("F77.MET.Line", "clanhb.f", "3"))); } @ParameterizedTest @@ -104,7 +102,7 @@ void test_compute_metrics(AnalysisRuleTestData testData) { rule.getResult().setResultTypePlace("method"); rule.getResult().setResultMessage("Small file"); - project.setAnalysisRule(new AnalysisRule[]{rule}); + project.setAnalysisRule(new AnalysisRule[] { rule }); ICodeMetricsProcessor.saveExtraMeasures(context, files, project); @@ -124,11 +122,10 @@ void test_is_metric_false() { @Test void test_save_extra_measure_with_null_location() { // If we upgrade to Junit5, we may check @ParametrizedTest annotation - String[] locations = {null, "", "method"}; - int[] expectedResults = {0, 0, 1}; - + String[] locations = { null, "", "method" }; + int[] expectedResults = { 0, 0, 1 }; - for(int i=0;i