internal async Task OnRestoreInfoChangedAsync(IProjectVersionedValue <IVsProjectRestoreInfo2> e) { // Restore service always does work regardless of whether the value we pass them to actually // contains changes, only nominate if there are any. if (RestoreComparer.RestoreInfos.Equals(_latestValue, e.Value)) { return; } // No configurations - likely during project close if (e.Value == null) { return; } _latestValue = e.Value; JoinableTask joinableTask = JoinableFactory.RunAsync(() => { return(NominateProjectRestoreAsync(e.Value, _projectAsynchronousTasksService.UnloadCancellationToken)); }); _projectAsynchronousTasksService.RegisterAsyncTask(joinableTask, ProjectCriticalOperation.Build | ProjectCriticalOperation.Unload | ProjectCriticalOperation.Rename, registerFaultHandler: true); // Prevent overlap until Restore completes await joinableTask; }
public ProjectRestoreUpdate(ProjectConfiguration projectConfiguration, IVsProjectRestoreInfo2 restoreInfo) { Requires.NotNull(projectConfiguration, nameof(projectConfiguration)); Requires.NotNull(restoreInfo, nameof(restoreInfo)); ProjectConfiguration = projectConfiguration; RestoreInfo = restoreInfo; }
private static void AssertNoItems(IVsProjectRestoreInfo2 result) { Assert.Empty(result.ToolReferences); Assert.Equal(1, result.TargetFrameworks.Count); var targetFramework = result.TargetFrameworks.Item(0); Assert.Empty(targetFramework.FrameworkReferences); Assert.Empty(targetFramework.PackageDownloads); Assert.Empty(targetFramework.PackageReferences); Assert.Empty(targetFramework.ProjectReferences); }
private async Task NominateProjectRestoreAsync(IVsProjectRestoreInfo2 restoreInfo, CancellationToken cancellationToken) { RestoreLogger.BeginNominateRestore(_logger, _project.FullPath, restoreInfo); // Nominate NuGet with the restore data. This will complete when we're guaranteed // that the assets files *at least* contains the changes that we pushed to it. await _solutionRestoreService.NominateProjectAsync(_project.FullPath, restoreInfo, cancellationToken); CodeMarkers.Instance.CodeMarker(CodeMarkerTimerId.PerfPackageRestoreEnd); RestoreLogger.EndNominateRestore(_logger, _project.FullPath); }
public async Task OnRestoreInfoChangedAsync_PushesRestoreInfoToRestoreService() { IVsProjectRestoreInfo2 result = null; var solutionRestoreService = IVsSolutionRestoreServiceFactory.ImplementNominateProjectAsync((projectFile, info, cancellationToken) => { result = info; }); var instance = await CreateInitializedInstance(solutionRestoreService : solutionRestoreService); var restoreInfo = IVsProjectRestoreInfo2Factory.Create(); var value = IProjectVersionedValueFactory.Create(restoreInfo); await instance.OnRestoreInfoChangedAsync(value); Assert.Same(restoreInfo, result); }
private PackageRestoreConfiguredInput CreateRestoreInput(ConfiguredProject project, IImmutableDictionary <string, IProjectRuleSnapshot> update) { IVsProjectRestoreInfo2 restoreInfo = RestoreBuilder.ToProjectRestoreInfo(update); return(new PackageRestoreConfiguredInput(project, restoreInfo)); }
/// <summary> /// This is where the nominate calls for the IVs1 and IVS3 APIs combine. The reason for this method is to avoid duplication and potential issues /// The issue with this method is that it has some weird custom logging to ensure backward compatibility. It's on the implementer to ensure these calls are correct. /// <param name="projectUniqueName">projectUniqueName</param> /// <param name="projectRestoreInfo">projectRestoreInfo. Can be null</param> /// <param name="projectRestoreInfo2">proectRestoreInfo2. Can be null</param> /// <param name="token"></param> /// <remarks>Exactly one of projectRestoreInfos has to null.</remarks> /// <returns>The task that scheduled restore</returns> private Task <bool> NominateProjectAsync(string projectUniqueName, IVsProjectRestoreInfo projectRestoreInfo, IVsProjectRestoreInfo2 projectRestoreInfo2, CancellationToken token) { if (string.IsNullOrEmpty(projectUniqueName)) { throw new ArgumentException(Resources.Argument_Cannot_Be_Null_Or_Empty, nameof(projectUniqueName)); } if (projectRestoreInfo == null && projectRestoreInfo2 == null) { throw new ArgumentNullException(nameof(projectRestoreInfo)); } if (projectRestoreInfo != null && projectRestoreInfo2 != null) { throw new ArgumentException($"Internal error: Both {nameof(projectRestoreInfo)} and {nameof(projectRestoreInfo2)} cannot have values. Please file an issue at NuGet/Home if you see this exception."); } if (projectRestoreInfo != null) { if (projectRestoreInfo.TargetFrameworks == null) { throw new InvalidOperationException("TargetFrameworks cannot be null."); } } else { if (projectRestoreInfo2.TargetFrameworks == null) { throw new InvalidOperationException("TargetFrameworks cannot be null."); } } try { _logger.LogInformation( $"The nominate API is called for '{projectUniqueName}'."); var projectNames = ProjectNames.FromFullProjectPath(projectUniqueName); DependencyGraphSpec dgSpec; IReadOnlyList <IAssetsLogMessage> nominationErrors = null; try { dgSpec = ToDependencyGraphSpec(projectNames, projectRestoreInfo, projectRestoreInfo2); } catch (Exception e) { var restoreLogMessage = RestoreLogMessage.CreateError(NuGetLogCode.NU1105, string.Format(Resources.NU1105, projectNames.ShortName, e.Message)); restoreLogMessage.LibraryId = projectUniqueName; nominationErrors = new List <IAssetsLogMessage>() { AssetsLogMessage.Create(restoreLogMessage) }; var projectDirectory = Path.GetDirectoryName(projectUniqueName); string projectIntermediatePath = projectRestoreInfo == null ? projectRestoreInfo2.BaseIntermediatePath : projectRestoreInfo.BaseIntermediatePath; var dgSpecOutputPath = GetProjectOutputPath(projectDirectory, projectIntermediatePath); dgSpec = CreateMinimalDependencyGraphSpec(projectUniqueName, dgSpecOutputPath); } _projectSystemCache.AddProjectRestoreInfo(projectNames, dgSpec, nominationErrors); // returned task completes when scheduled restore operation completes. var restoreTask = _restoreWorker.ScheduleRestoreAsync( SolutionRestoreRequest.OnUpdate(), token); return(restoreTask); } catch (OperationCanceledException) { throw; } catch (Exception e) { _logger.LogError(e.ToString()); TelemetryUtility.EmitException(nameof(VsSolutionRestoreService), nameof(NominateProjectAsync), e); return(Task.FromResult(false)); } }
public Task <bool> NominateProjectAsync(string projectUniqueName, IVsProjectRestoreInfo2 projectRestoreInfo, CancellationToken token) { return(NominateProjectAsync(projectUniqueName, null, projectRestoreInfo, token)); }
private static DependencyGraphSpec ToDependencyGraphSpec(ProjectNames projectNames, IVsProjectRestoreInfo projectRestoreInfo, IVsProjectRestoreInfo2 projectRestoreInfo2) { var dgSpec = new DependencyGraphSpec(); var packageSpec = projectRestoreInfo != null? ToPackageSpec(projectNames, projectRestoreInfo.TargetFrameworks, projectRestoreInfo.OriginalTargetFrameworks, projectRestoreInfo.BaseIntermediatePath) : ToPackageSpec(projectNames, projectRestoreInfo2.TargetFrameworks, projectRestoreInfo2.OriginalTargetFrameworks, projectRestoreInfo2.BaseIntermediatePath); dgSpec.AddRestore(packageSpec.RestoreMetadata.ProjectUniqueName); dgSpec.AddProject(packageSpec); if (projectRestoreInfo != null && projectRestoreInfo.ToolReferences != null) { VSNominationUtilities.ProcessToolReferences(projectNames, projectRestoreInfo.TargetFrameworks, projectRestoreInfo.ToolReferences, dgSpec); } else if (projectRestoreInfo2 != null && projectRestoreInfo2.ToolReferences != null) { VSNominationUtilities.ProcessToolReferences(projectNames, projectRestoreInfo2.TargetFrameworks, projectRestoreInfo2.ToolReferences, dgSpec); } return(dgSpec); }
public static void BeginNominateRestore(IProjectDiagnosticOutputService logger, string fullPath, IVsProjectRestoreInfo2 projectRestoreInfo) { if (logger.IsEnabled) { using var batch = new BatchLogger(logger); batch.WriteLine(); batch.WriteLine("------------------------------------------"); batch.WriteLine($"BEGIN Nominate Restore for {fullPath}"); batch.IndentLevel++; batch.WriteLine($"MSBuildProjectExtensionsPath: {projectRestoreInfo.BaseIntermediatePath}"); batch.WriteLine($"OriginalTargetFrameworks: {projectRestoreInfo.OriginalTargetFrameworks}"); LogTargetFrameworks(batch, projectRestoreInfo.TargetFrameworks); LogReferenceItems(batch, "Tool References", projectRestoreInfo.ToolReferences); batch.IndentLevel--; batch.WriteLine(); } }
/// <summary> /// This is where the nominate calls for the IVs1 and IVS3 APIs combine. The reason for this method is to avoid duplication and potential issues /// The issue with this method is that it has some weird custom logging to ensure backward compatibility. It's on the implementer to ensure these calls are correct. /// <param name="projectUniqueName">projectUniqueName</param> /// <param name="projectRestoreInfo">projectRestoreInfo. Can be null</param> /// <param name="projectRestoreInfo2">proectRestoreInfo2. Can be null</param> /// <param name="token"></param> /// <remarks>Exactly one of projectRestoreInfos has to null.</remarks> /// <returns>The task that scheduled restore</returns> private Task <bool> NominateProjectAsync(string projectUniqueName, IVsProjectRestoreInfo projectRestoreInfo, IVsProjectRestoreInfo2 projectRestoreInfo2, CancellationToken token) { if (string.IsNullOrEmpty(projectUniqueName)) { throw new ArgumentException(Resources.Argument_Cannot_Be_Null_Or_Empty, nameof(projectUniqueName)); } if (projectRestoreInfo == null && projectRestoreInfo2 == null) { throw new ArgumentNullException(nameof(projectRestoreInfo)); } if (projectRestoreInfo != null && projectRestoreInfo2 != null) { throw new ArgumentException($"Internal error: Both {nameof(projectRestoreInfo)} and {nameof(projectRestoreInfo2)} cannot have values. Please file an issue at NuGet/Home if you see this exception."); } if (projectRestoreInfo != null) { if (projectRestoreInfo.TargetFrameworks == null) { throw new InvalidOperationException("TargetFrameworks cannot be null."); } } else { if (projectRestoreInfo2.TargetFrameworks == null) { throw new InvalidOperationException("TargetFrameworks cannot be null."); } } try { _logger.LogInformation( $"The nominate API is called for '{projectUniqueName}'."); var projectNames = ProjectNames.FromFullProjectPath(projectUniqueName); var dgSpec = ToDependencyGraphSpec(projectNames, projectRestoreInfo, projectRestoreInfo2); _projectSystemCache.AddProjectRestoreInfo(projectNames, dgSpec); // returned task completes when scheduled restore operation completes. var restoreTask = _restoreWorker.ScheduleRestoreAsync( SolutionRestoreRequest.OnUpdate(), token); return(restoreTask); } catch (OperationCanceledException) { throw; } catch (Exception e) { _logger.LogError(e.ToString()); return(Task.FromResult(false)); } }
private ProjectRestoreUpdate CreateRestoreUpdate(ProjectConfiguration projectConfiguration, IImmutableDictionary <string, IProjectRuleSnapshot> update) { IVsProjectRestoreInfo2 restoreInfo = RestoreBuilder.ToProjectRestoreInfo(update); return(new ProjectRestoreUpdate(projectConfiguration, restoreInfo)); }
public PackageRestoreConfiguredInput(ConfiguredProject project, IVsProjectRestoreInfo2 restoreInfo) { Project = project; RestoreInfo = restoreInfo; }