//returns the lock file, if it changed async Task <string> RestorePackagesInternal( BuildIntegratedNuGetProject project, CancellationToken cancellationToken) { var nugetPaths = NuGetPathContext.Create(settings); RestoreResult restoreResult = await BuildIntegratedRestoreUtility.RestoreAsync( project, context, sourceRepositories, nugetPaths.UserPackageFolder, nugetPaths.FallbackPackageFolders, cancellationToken); if (restoreResult.Success) { if (!object.Equals(restoreResult.LockFile, restoreResult.PreviousLockFile)) { return(restoreResult.LockFilePath); } } else { ReportRestoreError(restoreResult); } return(null); }
public Task <bool> IsRestoreRequired(BuildIntegratedNuGetProject project) { var pathResolver = new VersionFolderPathResolver(packagesFolder); var projects = new BuildIntegratedNuGetProject[] { project }; return(BuildIntegratedRestoreUtility.IsRestoreRequired(projects, pathResolver, context)); }
/// <summary> /// Determine if a full restore is required. For scenarios with no floating versions /// where all packages are already on disk and no server requests are needed /// we can skip the restore after some validation checks. /// </summary> private async Task <bool> IsRestoreRequired( List <BuildIntegratedProjectSystem> projects, bool forceRestore, ExternalProjectReferenceContext referenceContext) { try { // Swap caches var oldCache = _buildIntegratedCache; _buildIntegratedCache = await BuildIntegratedRestoreUtility.CreateBuildIntegratedProjectStateCache( projects, referenceContext); if (forceRestore) { // The cache has been updated, now skip the check since we are doing a restore anyways. return(true); } if (BuildIntegratedRestoreUtility.CacheHasChanges(oldCache, _buildIntegratedCache)) { // A new project has been added return(true); } var globalPackagesFolder = SettingsUtility.GetGlobalPackagesFolder(Settings); var pathResolver = new VersionFolderPathResolver(globalPackagesFolder); var restoreRequired = await BuildIntegratedRestoreUtility.IsRestoreRequired( projects, pathResolver, referenceContext); if (restoreRequired) { // The project.json file does not match the lock file return(true); } } catch (Exception ex) { Debug.Fail("Unable to validate lock files."); ActivityLog.LogError(LogEntrySource, ex.ToString()); WriteLine(VerbosityLevel.Diagnostic, "{0}", ex.ToString()); // If we are unable to validate, run a full restore // This may occur if the lock files are corrupt return(true); } // Validation passed, no restore is needed return(false); }
public Task <bool> IsRestoreRequired(BuildIntegratedNuGetProject project) { var nugetPaths = NuGetPathContext.Create(settings); var packageFolderPaths = new List <string>(); packageFolderPaths.Add(nugetPaths.UserPackageFolder); packageFolderPaths.AddRange(nugetPaths.FallbackPackageFolders); var projects = new BuildIntegratedNuGetProject[] { project }; return(BuildIntegratedRestoreUtility.IsRestoreRequired(projects, packageFolderPaths, context)); }
public async Task RestorePackages( BuildIntegratedNuGetProject project, CancellationToken cancellationToken) { RestoreResult restoreResult = await BuildIntegratedRestoreUtility.RestoreAsync( project, context, sourceRepositories, packagesFolder, cancellationToken); if (!restoreResult.Success) { ReportRestoreError(restoreResult); } }
private async Task BuildIntegratedProjectRestoreAsync( BuildIntegratedNuGetProject project, string solutionDirectory, List <SourceRepository> enabledSources, ExternalProjectReferenceContext context, RestoreCommandProvidersCache providerCache, CancellationToken token) { // Go off the UI thread to perform I/O operations await TaskScheduler.Default; var projectName = NuGetProject.GetUniqueNameOrName(project); var nugetPathContext = NuGetPathContext.Create(Settings); using (var cacheContext = new SourceCacheContext()) { providerCache.GetOrCreate( nugetPathContext.UserPackageFolder, nugetPathContext.FallbackPackageFolders, enabledSources, cacheContext, context.Logger); // Pass down the CancellationToken from the dialog var restoreResult = await BuildIntegratedRestoreUtility.RestoreAsync(project, context, enabledSources, nugetPathContext.UserPackageFolder, nugetPathContext.FallbackPackageFolders, token); if (!restoreResult.Success) { // Mark this as having errors _hasErrors = true; // Invalidate cached results for the project. This will cause it to restore the next time. _buildIntegratedCache.Remove(projectName); await BuildIntegratedProjectReportErrorAsync(projectName, restoreResult, token); } } }
//returns the lock file, if it changed async Task <string> RestorePackagesInternal( BuildIntegratedNuGetProject project, CancellationToken cancellationToken) { RestoreResult restoreResult = await BuildIntegratedRestoreUtility.RestoreAsync( project, context, sourceRepositories, packagesFolder, cancellationToken); if (restoreResult.Success) { if (!object.Equals(restoreResult.LockFile, restoreResult.PreviousLockFile)) { return(restoreResult.LockFilePath); } } else { ReportRestoreError(restoreResult); } return(null); }
/// <summary> /// Determine if a full restore is required. For scenarios with no floating versions /// where all packages are already on disk and no server requests are needed /// we can skip the restore after some validation checks. /// </summary> private async Task <bool> IsRestoreRequired( List <BuildIntegratedProjectSystem> projects, bool forceRestore, ExternalProjectReferenceContext referenceContext) { try { // Swap caches var oldCache = _buildIntegratedCache; _buildIntegratedCache = await BuildIntegratedRestoreUtility.CreateBuildIntegratedProjectStateCache( projects, referenceContext); if (forceRestore) { // The cache has been updated, now skip the check since we are doing a restore anyways. return(true); } if (BuildIntegratedRestoreUtility.CacheHasChanges(oldCache, _buildIntegratedCache)) { // A new project has been added return(true); } // Read package folder locations var nugetPaths = NuGetPathContext.Create(Settings); var packageFolderPaths = new List <string>(); // Folder paths must be in order of priority packageFolderPaths.Add(nugetPaths.UserPackageFolder); packageFolderPaths.AddRange(nugetPaths.FallbackPackageFolders); // Verify all packages exist and have the expected hashes var restoreRequired = await BuildIntegratedRestoreUtility.IsRestoreRequired( projects, packageFolderPaths, referenceContext); if (restoreRequired) { // The project.json file does not match the lock file return(true); } } catch (Exception ex) { Debug.Fail("Unable to validate lock files."); ActivityLog.LogError(LogEntrySource, ex.ToString()); WriteLine(VerbosityLevel.Diagnostic, "{0}", ex.ToString()); // If we are unable to validate, run a full restore // This may occur if the lock files are corrupt return(true); } // Validation passed, no restore is needed return(false); }
/// <summary> /// Returns the closure of all project to project references below this project. /// The code is a port of src/NuGet.Clients/PackageManagement.VisualStudio/ProjectSystems/BuildIntegratedProjectSystem.cs /// </summary> Task <IReadOnlyList <ExternalProjectReference> > GetExternalProjectReferenceClosureAsync(ExternalProjectReferenceContext context) { var logger = context.Logger; var cache = context.Cache; var results = new HashSet <ExternalProjectReference> (); // projects to walk - DFS var toProcess = new Stack <DotNetProjectReference> (); // keep track of found projects to avoid duplicates string rootProjectPath = dotNetProject.FileName; // start with the current project toProcess.Push(new DotNetProjectReference(dotNetProject.DotNetProject, rootProjectPath)); var uniqueNames = new HashSet <string>(StringComparer.OrdinalIgnoreCase); // continue walking all project references until we run out while (toProcess.Count > 0) { var reference = toProcess.Pop(); // Find the path of the current project string projectFileFullPath = reference.Path; var project = reference.Project; if (string.IsNullOrEmpty(projectFileFullPath) || !uniqueNames.Add(projectFileFullPath)) { // This has already been processed or does not exist continue; } IReadOnlyList <ExternalProjectReference> cacheReferences; if (cache.TryGetValue(projectFileFullPath, out cacheReferences)) { // The cached value contains the entire closure, add it to the results and skip // all child references. results.UnionWith(cacheReferences); } else { // Get direct references var projectResult = GetDirectProjectReferences( reference.Project, projectFileFullPath, context, rootProjectPath); // Add results to the closure results.UnionWith(projectResult.Processed); // Continue processing foreach (var item in projectResult.ToProcess) { toProcess.Push(item); } } } // Cache the results for this project and every child project which has not been cached foreach (var project in results) { if (!context.Cache.ContainsKey(project.UniqueName)) { var closure = BuildIntegratedRestoreUtility.GetExternalClosure(project.UniqueName, results); context.Cache.Add(project.UniqueName, closure.ToList()); } } var result = cache[rootProjectPath]; return(Task.FromResult(result)); }
/// <summary> /// Returns the closure of all project to project references below this project. /// </summary> /// <remarks>This uses DTE and should be called from the UI thread.</remarks> public override async Task <IReadOnlyList <ExternalProjectReference> > GetProjectReferenceClosureAsync( ExternalProjectReferenceContext context) { var logger = context.Logger; var cache = context.Cache; // DTE calls need to be done from the main thread await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); var results = new HashSet <ExternalProjectReference>(); // projects to walk - DFS var toProcess = new Stack <DTEReference>(); // keep track of found projects to avoid duplicates var rootProjectPath = EnvDTEProjectUtility.GetFullProjectPath(EnvDTEProject); // start with the current project toProcess.Push(new DTEReference(EnvDTEProject, rootProjectPath)); var itemsFactory = ServiceLocator.GetInstance <IVsEnumHierarchyItemsFactory>(); var uniqueNames = new HashSet <string>(StringComparer.OrdinalIgnoreCase); // continue walking all project references until we run out while (toProcess.Count > 0) { var dteReference = toProcess.Pop(); // Find the path of the current project var projectFileFullPath = dteReference.Path; var project = dteReference.Project; if (string.IsNullOrEmpty(projectFileFullPath) || !uniqueNames.Add(projectFileFullPath)) { // This has already been processed or does not exist continue; } IReadOnlyList <ExternalProjectReference> cacheReferences; if (cache.TryGetValue(projectFileFullPath, out cacheReferences)) { // The cached value contains the entire closure, add it to the results and skip // all child references. results.UnionWith(cacheReferences); } else { // Get direct references var projectResult = GetDirectProjectReferences( dteReference.Project, projectFileFullPath, context, itemsFactory, rootProjectPath); // Add results to the closure results.UnionWith(projectResult.Processed); // Continue processing foreach (var item in projectResult.ToProcess) { toProcess.Push(item); } } } // Cache the results for this project and every child project which has not been cached foreach (var project in results) { if (!context.Cache.ContainsKey(project.UniqueName)) { var closure = BuildIntegratedRestoreUtility.GetExternalClosure(project.UniqueName, results); context.Cache.Add(project.UniqueName, closure.ToList()); } } return(cache[rootProjectPath]); }