示例#1
0
        internal /* for testing */ static bool ShouldMergeAnalysisSettings(string language, AnalysisConfig config, Common.ILogger logger)
        {
            Debug.Assert(!string.IsNullOrEmpty(language));
            Debug.Assert(config != null);

            // See https://github.com/SonarSource/sonar-scanner-msbuild/issues/561
            // Legacy behaviour is to overwrite.
            // The new (SQ 7.4+) behaviour is to merge only if sonar.[LANGUAGE].roslyn.ignoreIssues is false.
            var serverVersion = config?.FindServerVersion();

            if (serverVersion == null || serverVersion < new Version("7.4"))
            {
                logger.LogInfo(Resources.AnalyzerSettings_ExternalIssueNotSupported, SonarProduct.GetSonarProductToLog(config?.SonarQubeHostUrl));
                return(false);
            }

            var settingName   = $"sonar.{language}.roslyn.ignoreIssues";
            var settingInFile = config.GetSettingOrDefault(settingName, includeServerSettings: true, defaultValue: "false");

            if (bool.TryParse(settingInFile, out var ignoreExternalRoslynIssues))
            {
                logger.LogDebug(Resources.AnalyzerSettings_ImportAllSettingValue, settingName, ignoreExternalRoslynIssues.ToString().ToLowerInvariant());
                return(!ignoreExternalRoslynIssues);
            }
            else
            {
                logger.LogWarning(Resources.AnalyzerSettings_InvalidValueForImportAll, settingName, settingInFile);
                return(false);
            }
        }
示例#2
0
        public bool TryWriteProperties(PropertiesWriter writer, out IEnumerable <ProjectData> allProjects)
        {
            var projects = ProjectLoader.LoadFrom(analysisConfig.SonarOutputDir);

            if (!projects.Any())
            {
                logger.LogError(Resources.ERR_NoProjectInfoFilesFound, SonarProduct.GetSonarProductToLog(analysisConfig.SonarQubeHostUrl));
                allProjects = Enumerable.Empty <ProjectData>();
                return(false);
            }

            var projectsWithoutGuid = projects.Where(p => p.ProjectGuid == Guid.Empty).ToList();

            if (projectsWithoutGuid.Count > 0)
            {
                logger.LogWarning(Resources.WARN_EmptyProjectGuids, string.Join(", ", projectsWithoutGuid.Select(p => p.FullPath)));
            }

            var projectDirectories = projects.Select(p => p.GetDirectory()).ToList();
            var analysisProperties = analysisConfig.ToAnalysisProperties(logger);

            FixSarifAndEncoding(projects, analysisProperties);

            allProjects = projects.GroupBy(p => p.ProjectGuid).Select(ToProjectData).ToList();
            var validProjects = allProjects.Where(p => p.Status == ProjectInfoValidity.Valid).ToList();

            if (validProjects.Count == 0)
            {
                logger.LogError(Resources.ERR_NoValidProjectInfoFiles, SonarProduct.GetSonarProductToLog(analysisConfig.SonarQubeHostUrl));
                return(false);
            }

            var rootProjectBaseDir = ComputeRootProjectBaseDir(projectDirectories);

            if (rootProjectBaseDir == null ||
                !rootProjectBaseDir.Exists)
            {
                logger.LogError(Resources.ERR_ProjectBaseDirDoesNotExist);
                return(false);
            }

            var rootModuleFiles = PutFilesToRightModuleOrRoot(validProjects, rootProjectBaseDir);

            PostProcessProjectStatus(validProjects);

            if (rootModuleFiles.Count == 0 &&
                validProjects.All(p => p.Status == ProjectInfoValidity.NoFilesToAnalyze))
            {
                logger.LogError(Resources.ERR_NoValidProjectInfoFiles, SonarProduct.GetSonarProductToLog(analysisConfig.SonarQubeHostUrl));
                return(false);
            }

            writer.WriteSonarProjectInfo(rootProjectBaseDir);
            writer.WriteSharedFiles(rootModuleFiles);
            validProjects.ForEach(writer.WriteSettingsForProject);
            // Handle global settings
            writer.WriteGlobalSettings(analysisProperties);
            return(true);
        }
示例#3
0
        public override bool Execute()
        {
            var logger = new MSBuildLoggerAdapter(Log);
            var config = TaskUtilities.TryGetConfig(AnalysisConfigDir, logger);

            var languageSettings = GetLanguageSpecificSettings(config);

            if (languageSettings == null)
            {
                // Early-out: we don't have any settings for the current language.
                // Preserve the default existing behaviour of only preserving the original list of additional files but clearing the analyzers.
                RuleSetFilePath     = null;
                AdditionalFilePaths = OriginalAdditionalFiles;
                return(!Log.HasLoggedErrors);
            }

            TaskOutputs outputs;

            // We analyze test projects since MMF-2297 / SQ 8.9. C#/VB.NET plugin <= 8.20 bundled with SQ <= 8.8 would ignore results on test projects anyway.
            if (IsTestProject && (ExcludeTestProjects() || !IsTestAnalysisSupported()))
            {
                // Special case: to provide colorization etc for code in test projects, we need to run only the SonarC#/VB analyzers, with all of the non-utility rules turned off
                // See [MMF-486]: https://jira.sonarsource.com/browse/MMF-486
                Log.LogMessage(MessageImportance.Low, Resources.AnalyzerSettings_ConfiguringTestProjectAnalysis);
                outputs = CreateDeactivatedProjectSettings(languageSettings);
            }
            else
            {
                if (ShouldMergeAnalysisSettings(Language, config, logger))
                {
                    Log.LogMessage(MessageImportance.Low, Resources.AnalyzerSettings_MergingSettings);
                    outputs = CreateMergedAnalyzerSettings(languageSettings);
                }
                else
                {
                    Log.LogMessage(MessageImportance.Low, Resources.AnalyzerSettings_OverwritingSettings);
                    outputs = CreateLegacyProductProjectSettings(languageSettings);
                }
            }

            ApplyTaskOutput(outputs);

            return(!Log.HasLoggedErrors);

            bool ExcludeTestProjects() =>
            config.GetAnalysisSettings(false).TryGetValue(ExcludeTestProjectsSettingId, out var excludeTestProjects) &&
            excludeTestProjects.Equals("true", StringComparison.OrdinalIgnoreCase);

            bool IsTestAnalysisSupported()
            {
                var version = config.FindServerVersion();

                return(SonarProduct.IsSonarCloud(config.SonarQubeHostUrl, version) || version >= new Version(8, 9));
            }
        }
示例#4
0
 [DataRow(false, "https://sonarcloud.io", "9.0")]    // SC is defined as "Version 8.0"
 public void IsSonarCloud(bool expected, string host, string version) =>
 SonarProduct.IsSonarCloud(host, new Version(version)).Should().Be(expected);
示例#5
0
 public void GetSonarProductToLog(string host, string expectedName) =>
 SonarProduct.GetSonarProductToLog(host).Should().Be(expectedName);
        /// <summary>
        /// Locates the ProjectInfo.xml files and uses the information in them to generate
        /// a sonar-scanner properties file
        /// </summary>
        /// <returns>Information about each of the project info files that was processed, together with
        /// the full path to generated file.
        /// Note: the path to the generated file will be null if the file could not be generated.</returns>
        public ProjectInfoAnalysisResult GenerateFile()
        {
            var projectPropertiesPath = Path.Combine(analysisConfig.SonarOutputDir, ProjectPropertiesFileName);

            logger.LogDebug(Resources.MSG_GeneratingProjectProperties, projectPropertiesPath, SonarProduct.GetSonarProductToLog(analysisConfig.SonarQubeHostUrl));

            var result = new ProjectInfoAnalysisResult();

            var writer = new PropertiesWriter(analysisConfig, logger);

            var success = TryWriteProperties(writer, out IEnumerable <ProjectData> projects);

            if (success)
            {
                var contents = writer.Flush();

                File.WriteAllText(projectPropertiesPath, contents, Encoding.ASCII);
                logger.LogDebug(Resources.DEBUG_DumpSonarProjectProperties, contents);

                result.FullPropertiesFilePath = projectPropertiesPath;
            }
            else
            {
                logger.LogInfo(Resources.MSG_PropertiesGenerationFailed);
            }

            result.Projects.AddRange(projects);

            return(result);
        }
 private void LogDuplicateGuidWarning(Guid projectGuid, string projectPath) =>
 logger.LogWarning(Resources.WARN_DuplicateProjectGuid, projectGuid, projectPath, SonarProduct.GetSonarProductToLog(analysisConfig.SonarQubeHostUrl));
        private void LogStartupSettings(AnalysisConfig config, ITeamBuildSettings settings)
        {
            var configFileName = config == null ? string.Empty : config.FileName;

            logger.LogDebug(Resources.MSG_LoadingConfig, configFileName, config != null ? SonarProduct.GetSonarProductToLog(config.SonarQubeHostUrl) : "Sonar");

            switch (settings.BuildEnvironment)
            {
            case BuildEnvironment.LegacyTeamBuild:
                logger.LogDebug(Resources.SETTINGS_InLegacyTeamBuild);

                break;

            case BuildEnvironment.TeamBuild:
                logger.LogDebug(Resources.SETTINGS_InTeamBuild);
                break;

            case BuildEnvironment.NotTeamBuild:
                logger.LogDebug(Resources.SETTINGS_NotInTeamBuild);
                break;

            default:
                break;
            }

            logger.LogDebug(Resources.SETTING_DumpSettings,
                            settings.AnalysisBaseDirectory,
                            settings.BuildDirectory,
                            settings.SonarBinDirectory,
                            settings.SonarConfigDirectory,
                            settings.SonarOutputDirectory,
                            settings.AnalysisConfigFilePath);
        }
示例#9
0
 private async Task <bool> IsSonarCloud() =>
 SonarProduct.IsSonarCloud(this.serverUrl, await GetServerVersion());