/// <summary> /// Will install the NuGet packages for the current managed projects. /// The packages that will be installed will be based on the information from <see cref="Analyzer.GetRequiredNuGetPackages"/> /// and is specific to the <see cref="RuleSet"/>. /// </summary> internal /*for testing purposes*/ void InstallPackages(IProgressController controller, CancellationToken token, IProgressStepExecutionEvents notificationEvents) { if (!this.NuGetPackages.Any()) { return; } Debug.Assert(this.NuGetPackages.Count == this.NuGetPackages.Distinct().Count(), "Duplicate NuGet packages specified"); if (!this.BindingProjects.Any()) { Debug.Fail("Not expected to be called when there are no projects"); return; } var projectNugets = this.BindingProjects .SelectMany(bindingProject => { var projectLanguage = Language.ForProject(bindingProject); List <NuGetPackageInfoResponse> nugetPackages; if (!this.NuGetPackages.TryGetValue(projectLanguage, out nugetPackages)) { var message = string.Format(Strings.BindingProjectLanguageNotMatchingAnyQualityProfileLanguage, bindingProject.Name); VsShellUtils.WriteToSonarLintOutputPane(this.host, Strings.SubTextPaddingFormat, message); nugetPackages = new List <NuGetPackageInfoResponse>(); } return(nugetPackages.Select(nugetPackage => new { Project = bindingProject, NugetPackage = nugetPackage })); }) .ToArray(); DeterminateStepProgressNotifier progressNotifier = new DeterminateStepProgressNotifier(notificationEvents, projectNugets.Length); foreach (var projectNuget in projectNugets) { if (token.IsCancellationRequested) { break; } string message = string.Format(CultureInfo.CurrentCulture, Strings.EnsuringNugetPackagesProgressMessage, projectNuget.NugetPackage.Id, projectNuget.Project.Name); VsShellUtils.WriteToSonarLintOutputPane(this.host, Strings.SubTextPaddingFormat, message); var isNugetInstallSuccessful = NuGetHelper.TryInstallPackage(this.host, projectNuget.Project, projectNuget.NugetPackage.Id, projectNuget.NugetPackage.Version); if (isNugetInstallSuccessful) // NuGetHelper.TryInstallPackage already displayed the error message so only take care of the success message { message = string.Format(CultureInfo.CurrentCulture, Strings.SuccessfullyInstalledNugetPackageForProject, projectNuget.NugetPackage.Id, projectNuget.Project.Name); VsShellUtils.WriteToSonarLintOutputPane(this.host, Strings.SubTextPaddingFormat, message); } // TODO: SVS-33 (https://jira.sonarsource.com/browse/SVS-33) Trigger a Team Explorer warning notification to investigate the partial binding in the output window. this.AllNuGetPackagesInstalled &= isNugetInstallSuccessful; progressNotifier.NotifyIncrementedProgress(string.Empty); } }
public void DeterminateStepProgressNotifier_IncrementProgress_ArgChecks() { // Arrange var testSubject = new DeterminateStepProgressNotifier(new ConfigurableProgressController(null), 11); Exceptions.Expect <ArgumentOutOfRangeException>(() => testSubject.IncrementProgress(0)); Exceptions.Expect <ArgumentOutOfRangeException>(() => testSubject.IncrementProgress(-1)); Exceptions.Expect <ArgumentOutOfRangeException>(() => testSubject.IncrementProgress(12)); // Check successful case (the last valid one) testSubject.IncrementProgress(11); testSubject.CurrentValue.Should().Be(11); }
public void DeterminateStepProgressNotifier_NotifyCurrentProgress() { // Arrange var controller = new ConfigurableProgressController(null); const int Steps = 2; var testSubject = new DeterminateStepProgressNotifier(controller, Steps); List <Tuple <string, double> > expectedProgress = new List <Tuple <string, double> >(); // Act + Assert for (int i = 0; i < Steps; i++) { expectedProgress.Add(Tuple.Create("hello world " + i, 0.0)); testSubject.NotifyCurrentProgress(expectedProgress.Last().Item1); testSubject.CurrentValue.Should().Be(0, "Should not change"); controller.progressChanges.Should().Equal(expectedProgress); } }
public void DeterminateStepProgressNotifier_IncrementProgress() { // Arrange var controller = new ConfigurableProgressController(null); const int Steps = 227; // Quite a few values for which N * (1 / N) > 1.0 var testSubject = new DeterminateStepProgressNotifier(controller, Steps); List <Tuple <string, double> > expectedProgress = new List <Tuple <string, double> >(); // Act + Assert int expectedValue = 0; int i = 0; while (expectedValue < Steps) { int increment = i % 2 == 0 ? 2 : 1; i++; expectedValue += increment; testSubject.IncrementProgress(increment); testSubject.CurrentValue.Should().Be(expectedValue); } }
public void DeterminateStepProgressNotifier_NotifyIncrementedProgress() { // Arrange var controller = new ConfigurableProgressController(null); const int Steps = 11; // there are two numbers (9 and 11) for which N * (1 / N) > 1.0 var testSubject = new DeterminateStepProgressNotifier(controller, Steps); List <Tuple <string, double> > expectedProgress = new List <Tuple <string, double> >(); // Act + Assert for (int i = 0; i < Steps; i++) { int incrementedStepValue = i + 1; double progress = incrementedStepValue == Steps ? 1.0 : (double)incrementedStepValue / Steps; expectedProgress.Add(Tuple.Create("hello world " + i, progress)); testSubject.CurrentValue.Should().Be(i); testSubject.NotifyIncrementedProgress(expectedProgress.Last().Item1); testSubject.CurrentValue.Should().Be(incrementedStepValue); controller.progressChanges.Should().Equal(expectedProgress); } }
internal /*for testing purposes*/ async System.Threading.Tasks.Task DownloadQualityProfileAsync( IProgressController controller, IProgressStepExecutionEvents notificationEvents, IEnumerable <Language> languages, CancellationToken cancellationToken) { Debug.Assert(controller != null); Debug.Assert(notificationEvents != null); var rulesets = new Dictionary <Language, RuleSet>(); var languageList = languages as IList <Language> ?? languages.ToList(); DeterminateStepProgressNotifier notifier = new DeterminateStepProgressNotifier(notificationEvents, languageList.Count); notifier.NotifyCurrentProgress(Strings.DownloadingQualityProfileProgressMessage); foreach (var language in languageList) { var serverLanguage = language.ToServerLanguage(); var qualityProfileInfo = await SafeServiceCall( () => this.host.SonarQubeService.GetQualityProfileAsync(this.project.Key, serverLanguage, cancellationToken)); if (qualityProfileInfo == null) { VsShellUtils.WriteToSonarLintOutputPane(this.host, string.Format(Strings.SubTextPaddingFormat, string.Format(Strings.CannotDownloadQualityProfileForLanguage, language.Name))); this.AbortWorkflow(controller, cancellationToken); return; } this.QualityProfiles[language] = qualityProfileInfo; var roslynProfileExporter = await SafeServiceCall( () => this.host.SonarQubeService.GetRoslynExportProfileAsync(qualityProfileInfo.Name, serverLanguage, cancellationToken)); if (roslynProfileExporter == null) { VsShellUtils.WriteToSonarLintOutputPane(this.host, string.Format(Strings.SubTextPaddingFormat, string.Format(Strings.QualityProfileDownloadFailedMessageFormat, qualityProfileInfo.Name, qualityProfileInfo.Key, language.Name))); this.AbortWorkflow(controller, cancellationToken); return; } var tempRuleSetFilePath = Path.GetTempFileName(); File.WriteAllText(tempRuleSetFilePath, roslynProfileExporter.Configuration.RuleSet.OuterXml); RuleSet ruleSet = RuleSet.LoadFromFile(tempRuleSetFilePath); if (ruleSet == null || ruleSet.Rules.Count == 0 || ruleSet.Rules.All(rule => rule.Action == RuleAction.None)) { VsShellUtils.WriteToSonarLintOutputPane(this.host, string.Format(Strings.SubTextPaddingFormat, string.Format(Strings.NoSonarAnalyzerActiveRulesForQualityProfile, qualityProfileInfo.Name, language.Name))); this.AbortWorkflow(controller, cancellationToken); return; } if (roslynProfileExporter.Deployment.NuGetPackages.Count == 0) { VsShellUtils.WriteToSonarLintOutputPane(this.host, string.Format(Strings.SubTextPaddingFormat, string.Format(Strings.NoNuGetPackageForQualityProfile, language.Name))); this.AbortWorkflow(controller, cancellationToken); return; } this.NuGetPackages.Add(language, roslynProfileExporter.Deployment.NuGetPackages); // Remove/Move/Refactor code when XML ruleset file is no longer downloaded but the proper API is used to retrieve rules UpdateDownloadedSonarQubeQualityProfile(ruleSet, qualityProfileInfo); rulesets[language] = ruleSet; notifier.NotifyIncrementedProgress(string.Empty); VsShellUtils.WriteToSonarLintOutputPane(this.host, string.Format(Strings.SubTextPaddingFormat, string.Format(Strings.QualityProfileDownloadSuccessfulMessageFormat, qualityProfileInfo.Name, qualityProfileInfo.Key, language.Name))); } // Set the rule set which should be available for the following steps foreach (var keyValue in rulesets) { this.Rulesets[keyValue.Key] = keyValue.Value; } }
internal /*for testing purposes*/ void DownloadQualityProfile(IProgressController controller, CancellationToken cancellationToken, IProgressStepExecutionEvents notificationEvents, IEnumerable <Language> languages) { Debug.Assert(controller != null); Debug.Assert(notificationEvents != null); bool failed = false; var rulesets = new Dictionary <Language, RuleSet>(); var languageList = languages as IList <Language> ?? languages.ToList(); DeterminateStepProgressNotifier notifier = new DeterminateStepProgressNotifier(notificationEvents, languageList.Count); notifier.NotifyCurrentProgress(Strings.DownloadingQualityProfileProgressMessage); foreach (var language in languageList) { QualityProfile qualityProfileInfo; if (!host.SonarQubeService.TryGetQualityProfile(this.connectionInformation, this.project, language, cancellationToken, out qualityProfileInfo)) { failed = true; InformAboutQualityProfileToDownload(qualityProfileInfo.Name, qualityProfileInfo.Key, language.Name, true); break; } this.QualityProfiles[language] = qualityProfileInfo; RoslynExportProfile export; if (!this.host.SonarQubeService.TryGetExportProfile(this.connectionInformation, qualityProfileInfo, language, cancellationToken, out export)) { failed = true; InformAboutQualityProfileToDownload(qualityProfileInfo.Name, qualityProfileInfo.Key, language.Name, true); break; } this.NuGetPackages.Add(language, export.Deployment.NuGetPackages); var tempRuleSetFilePath = Path.GetTempFileName(); File.WriteAllText(tempRuleSetFilePath, export.Configuration.RuleSet.OuterXml); RuleSet ruleSet = RuleSet.LoadFromFile(tempRuleSetFilePath); // Remove/Move/Refactor code when XML ruleset file is no longer downloaded but the proper API is used to retrieve rules UpdateDownloadedSonarQubeQualityProfile(ruleSet, qualityProfileInfo); rulesets[language] = ruleSet; notifier.NotifyIncrementedProgress(string.Empty); if (rulesets[language] == null) { failed = true; InformAboutQualityProfileToDownload(qualityProfileInfo.Name, qualityProfileInfo.Key, language.Name, true); break; } InformAboutQualityProfileToDownload(qualityProfileInfo.Name, qualityProfileInfo.Key, language.Name, false); } if (failed) { this.AbortWorkflow(controller, cancellationToken); } else { // Set the rule set which should be available for the following steps foreach (var keyValue in rulesets) { this.Rulesets[keyValue.Key] = keyValue.Value; } } }