private FilePathAndContent <SonarLintConfiguration> GetAdditionalFile(Language language, BindingConfiguration bindingConfiguration, IEnumerable <SonarQubeRule> activeRules, Dictionary <string, string> sonarProperties)
        {
            var additionalFilePath    = GetSolutionAdditionalFilePath(language, bindingConfiguration);
            var additionalFileContent = sonarLintConfigGenerator.Generate(activeRules, sonarProperties, language);

            var additionalFile = new FilePathAndContent <SonarLintConfiguration>(additionalFilePath, additionalFileContent);

            return(additionalFile);
        }
        private RuleSet CreateRuleset(SonarQubeQualityProfile qualityProfile, Language language, BindingConfiguration bindingConfiguration, IEnumerable <SonarQubeRule> rules, Dictionary <string, string> sonarProperties)
        {
            var coreRuleset = ruleSetGenerator.Generate(language.ServerLanguage.Key, rules, sonarProperties);

            // Set the name and description
            coreRuleset.Name = string.Format(Strings.SonarQubeRuleSetNameFormat, bindingConfiguration.Project.ProjectName, qualityProfile.Name);
            var descriptionSuffix = string.Format(Strings.SonarQubeQualityProfilePageUrlFormat, bindingConfiguration.Project.ServerUri, qualityProfile.Key);

            coreRuleset.Description = $"{coreRuleset.Description} {descriptionSuffix}";
            return(coreRuleset);
        }
            private bool IsUpdateRequired(BoundSonarQubeProject binding, IEnumerable <Language> projectLanguages,
                                          CancellationToken token)
            {
                Debug.Assert(binding != null);

                IDictionary <Language, SonarQubeQualityProfile> newProfiles = null;

                try
                {
                    newProfiles = TryGetLatestProfilesAsync(binding, projectLanguages, token).GetAwaiter().GetResult();
                }
                catch (Exception)
                {
                    this.host.Logger.WriteLine(Strings.SonarLintProfileCheckFailed);
                    return(false); // Error, can't proceed
                }

                if (!newProfiles.Keys.All(binding.Profiles.ContainsKey))
                {
                    this.host.Logger.WriteLine(Strings.SonarLintProfileCheckSolutionRequiresMoreProfiles);
                    return(true); // Missing profile, refresh
                }

                foreach (var keyValue in binding.Profiles)
                {
                    Language language = keyValue.Key;
                    ApplicableQualityProfile oldProfileInfo = keyValue.Value;

                    if (!newProfiles.ContainsKey(language))
                    {
                        // Not a relevant profile, we should just ignore it.
                        continue;
                    }

                    SonarQubeQualityProfile newProfileInfo = newProfiles[language];
                    if (this.HasProfileChanged(newProfileInfo, oldProfileInfo))
                    {
                        return(true);
                    }
                }

                this.host.Logger.WriteLine(Strings.SonarLintProfileCheckQualityProfileIsUpToDate);
                return(false); // Up-to-date
            }
Beispiel #4
0
        public async Task <IBindingConfigFile> GetConfigurationAsync(SonarQubeQualityProfile qualityProfile, string organizationKey, Language language, CancellationToken cancellationToken)
        {
            if (!IsLanguageSupported(language))
            {
                throw new ArgumentOutOfRangeException(nameof(language));
            }

            var serverLanguage = language.ServerLanguage;

            Debug.Assert(serverLanguage != null,
                         $"Server language should not be null for supported language: {language.Id}");

            // Generate the rules configuration file for the language
            var roslynProfileExporter = await WebServiceHelper.SafeServiceCallAsync(() =>
                                                                                    this.sonarQubeService.GetRoslynExportProfileAsync(qualityProfile.Name,
                                                                                                                                      organizationKey, serverLanguage, cancellationToken),
                                                                                    this.logger);

            if (roslynProfileExporter == null)
            {
                this.logger.WriteLine(string.Format(Strings.SubTextPaddingFormat,
                                                    string.Format(Strings.QualityProfileDownloadFailedMessageFormat, qualityProfile.Name,
                                                                  qualityProfile.Key, language.Name)));
                return(null);
            }

            var tempRuleSetFilePath = Path.GetTempFileName();

            File.WriteAllText(tempRuleSetFilePath, roslynProfileExporter.Configuration.RuleSet.OuterXml);
            RuleSet ruleSet = RuleSet.LoadFromFile(tempRuleSetFilePath);

            // Give up if the quality profile is empty
            if (ruleSet == null ||
                ruleSet.Rules.Count == 0 ||
                ruleSet.Rules.All(rule => rule.Action == RuleAction.None))
            {
                this.logger.WriteLine(string.Format(Strings.SubTextPaddingFormat,
                                                    string.Format(Strings.NoSonarAnalyzerActiveRulesForQualityProfile, qualityProfile.Name, language.Name)));
                return(null);
            }

            // Add the NuGet reference, if appropriate (only in legacy connected mode, and only C#/VB)
            if (!this.nuGetBindingOperation.ProcessExport(language, roslynProfileExporter))
            {
                return(null);
            }

            // Remove/Move/Refactor code when XML ruleset file is no longer downloaded but the proper API is used to retrieve rules
            UpdateDownloadedSonarQubeQualityProfile(ruleSet, qualityProfile, this.projectName, this.serverUrl);

            return(new DotNetBindingConfigFile(ruleSet));
        }
Beispiel #5
0
 public bool IsLanguageSupported(Language language)
 {
     return(Language.CSharp.Equals(language) || Language.VBNET.Equals(language));
 }
        private async Task <IBindingConfig> DoGetConfigurationAsync(SonarQubeQualityProfile qualityProfile, Language language, BindingConfiguration bindingConfiguration, CancellationToken cancellationToken)
        {
            var serverLanguage = language.ServerLanguage;

            Debug.Assert(serverLanguage != null,
                         $"Server language should not be null for supported language: {language.Id}");

            // First, fetch the active rules
            var activeRules = await FetchSupportedRulesAsync(true, qualityProfile.Key, cancellationToken);

            // Give up if the quality profile is empty - no point in fetching anything else
            if (!activeRules.Any())
            {
                logger.WriteLine(string.Format(Strings.SubTextPaddingFormat,
                                               string.Format(Strings.NoSonarAnalyzerActiveRulesForQualityProfile, qualityProfile.Name, language.Name)));
                return(null);
            }

            // Now fetch the data required for the NuGet configuration
            var sonarProperties = await FetchPropertiesAsync(bindingConfiguration.Project.ProjectKey, cancellationToken);

            // Get the NuGet package info and process it if appropriate (only in legacy connected mode, and only C#/VB)
            var nugetInfo = nuGetPackageInfoGenerator.GetNuGetPackageInfos(activeRules, sonarProperties);

            if (!nuGetBindingOperation.ProcessExport(language, nugetInfo))
            {
                return(null);
            }

            // Finally, fetch the remaining data needed to build the ruleset
            var inactiveRules = await FetchSupportedRulesAsync(false, qualityProfile.Key, cancellationToken);

            var ruleset        = GetRulesetFile(qualityProfile, language, bindingConfiguration, activeRules, inactiveRules, sonarProperties);
            var additionalFile = GetAdditionalFile(language, bindingConfiguration, activeRules, sonarProperties);

            return(new CSharpVBBindingConfig(ruleset, additionalFile));
        }
        public Task <IBindingConfig> GetConfigurationAsync(SonarQubeQualityProfile qualityProfile, Language language, BindingConfiguration bindingConfiguration, CancellationToken cancellationToken)
        {
            if (!IsLanguageSupported(language))
            {
                throw new ArgumentOutOfRangeException(nameof(language));
            }

            return(DoGetConfigurationAsync(qualityProfile, language, bindingConfiguration, cancellationToken));
        }
        internal static string GetSolutionAdditionalFilePath(Language language, BindingConfiguration bindingConfiguration)
        {
            var additionalFilePathDirectory = bindingConfiguration.BuildPathUnderConfigDirectory();

            return(Path.Combine(additionalFilePathDirectory, language.Id, "SonarLint.xml"));
        }
 internal static string GetSolutionRuleSetFilePath(Language language, BindingConfiguration bindingConfiguration)
 {
     return(bindingConfiguration.BuildPathUnderConfigDirectory(language.FileSuffixAndExtension));
 }
        private FilePathAndContent <RuleSet> GetRulesetFile(SonarQubeQualityProfile qualityProfile, Language language, BindingConfiguration bindingConfiguration, IEnumerable <SonarQubeRule> activeRules, IEnumerable <SonarQubeRule> inactiveRules, Dictionary <string, string> sonarProperties)
        {
            var RuleSet = CreateRuleset(qualityProfile, language, bindingConfiguration, activeRules.Union(inactiveRules), sonarProperties);

            var ruleSetFilePath = GetSolutionRuleSetFilePath(language, bindingConfiguration);

            return(new FilePathAndContent <RuleSet>(ruleSetFilePath, RuleSet));
        }