public void ReportStatus(IReadOnlyList <RestoreSummary> restoreSummaries) { _failedProjects.Clear(); foreach (var summary in restoreSummaries) { if (summary.Success) { var packageSpec = _cachedDependencyGraphSpec.GetProjectSpec(summary.InputPath); GetOutputFilePaths(packageSpec, out string assetsFilePath, out string cacheFilePath, out string targetsFilePath, out string propsFilePath, out string lockFilePath); _outputWriteTimes[summary.InputPath] = new RestoreOutputData() { _lastAssetsFileWriteTime = GetLastWriteTime(assetsFilePath), _lastCacheFileWriteTime = GetLastWriteTime(cacheFilePath), _lastTargetsFileWriteTime = GetLastWriteTime(targetsFilePath), _lastPropsFileWriteTime = GetLastWriteTime(propsFilePath), _lastLockFileWriteTime = GetLastWriteTime(lockFilePath), _globalPackagesFolderCreationTime = GetCreationTime(packageSpec.RestoreMetadata.PackagesPath) }; } else { _failedProjects.Add(summary.InputPath); } } }
private RestoreSummaryRequest Create( string projectNameToRestore, ExternalProjectReference project, HashSet <ExternalProjectReference> projectReferenceClosure, RestoreArgs restoreArgs, DependencyGraphSpec projectDgSpec) { //fallback paths, global packages path and sources need to all be passed in the dg spec var fallbackPaths = projectDgSpec.GetProjectSpec(projectNameToRestore).RestoreMetadata.FallbackFolders; var globalPath = GetPackagesPath(restoreArgs, projectDgSpec.GetProjectSpec(projectNameToRestore)); var settings = Settings.LoadSettingsGivenConfigPaths(projectDgSpec.GetProjectSpec(projectNameToRestore).RestoreMetadata.ConfigFilePaths); var sources = restoreArgs.GetEffectiveSources(settings, projectDgSpec.GetProjectSpec(projectNameToRestore).RestoreMetadata.Sources); var sharedCache = _providerCache.GetOrCreate( globalPath, fallbackPaths.AsList(), sources, restoreArgs.CacheContext, restoreArgs.Log); var rootPath = Path.GetDirectoryName(project.PackageSpec.FilePath); // Create request var request = new RestoreRequest( project.PackageSpec, sharedCache, restoreArgs.CacheContext, restoreArgs.Log) { // Set properties from the restore metadata ProjectStyle = project.PackageSpec.RestoreMetadata.ProjectStyle, RestoreOutputPath = project.PackageSpec.RestoreMetadata.ProjectStyle == ProjectStyle.ProjectJson ? rootPath : project.PackageSpec.RestoreMetadata.OutputPath, DependencyGraphSpec = projectDgSpec, BaseIntermediateOutputPath = project.PackageSpec.RestoreMetadata.OutputPath }; var restoreLegacyPackagesDirectory = project.PackageSpec?.RestoreMetadata?.LegacyPackagesDirectory ?? DefaultRestoreLegacyPackagesDirectory; request.IsLowercasePackagesDirectory = !restoreLegacyPackagesDirectory; // Standard properties restoreArgs.ApplyStandardProperties(request); // Add project references request.ExternalProjects = projectReferenceClosure.ToList(); // The lock file is loaded later since this is an expensive operation var summaryRequest = new RestoreSummaryRequest( request, project.MSBuildProjectPath, settings, // TODO NK - We don't need to pass the settings down here. We just need the config files sources); return(summaryRequest); }
/// <summary> /// Write the dg file to a temp location if NUGET_PERSIST_NOOP_DG. /// </summary> /// <remarks>This is a noop if NUGET_PERSIST_NOOP_DG is not set to true.</remarks> private static void PersistHashedDGFileIfDebugging(DependencyGraphSpec spec, ILogger log) { if (_isPersistDGSet.Value) { string path; var envPath = Environment.GetEnvironmentVariable("NUGET_PERSIST_NOOP_DG_PATH"); if (!string.IsNullOrEmpty(envPath)) { path = envPath; Directory.CreateDirectory(Path.GetDirectoryName(path)); } else { path = Path.Combine( NuGetEnvironment.GetFolderPath(NuGetFolderPath.Temp), "nuget-dg", $"{spec.GetProjectSpec(spec.Restore.FirstOrDefault()).RestoreMetadata.ProjectName}-{DateTime.Now.ToString("yyyyMMddHHmmss")}.dg"); DirectoryUtility.CreateSharedDirectory(Path.GetDirectoryName(path)); } log.LogMinimal($"Persisting no-op dg to {path}"); spec.Save(path); } }
/// <summary> /// Updates the project Id in packageSpec. /// </summary> /// <param name="nuGetProject">NuGetProject containing the project Id.</param> /// <param name="projectUniqueName">Project unique name used to get the package spec from the dgSpec.</param> /// <param name="projectRestoreInfo">DgSpec of containing the packageSpec for the project.</param> private void UpdateProjectIdInPackageSpec(NuGetProject nuGetProject, string projectUniqueName, DependencyGraphSpec projectRestoreInfo) { var packageSpec = projectRestoreInfo.GetProjectSpec(projectUniqueName); if (packageSpec != null && nuGetProject != null && string.IsNullOrEmpty(packageSpec.ProjectId)) { packageSpec.ProjectId = nuGetProject.GetProjectId(); } }
public override Task <(IReadOnlyList <PackageSpec> dgSpecs, IReadOnlyList <IAssetsLogMessage> additionalMessages)> GetPackageSpecsAndAdditionalMessagesAsync(DependencyGraphCacheContext context) { DependencyGraphSpec dgSpec = DependencyGraphSpecTestUtilities.CreateMinimalDependencyGraphSpec(ProjectFullPath, MSBuildProjectPath); List <PackageSpec> packageSpecs = new List <PackageSpec>(); packageSpecs.Add(dgSpec.GetProjectSpec(ProjectFullPath)); (IReadOnlyList <PackageSpec>, IReadOnlyList <IAssetsLogMessage>)result = (packageSpecs, null); return(Task.FromResult(result)); }
public void SaveRestoreStatus(IReadOnlyList <RestoreSummary> restoreSummaries) { if (restoreSummaries == null) { throw new ArgumentNullException(nameof(restoreSummaries)); } _failedProjects.Clear(); foreach (var summary in restoreSummaries) { if (summary.Success) { var packageSpec = _cachedDependencyGraphSpec.GetProjectSpec(summary.InputPath); GetOutputFilePaths(packageSpec, out string assetsFilePath, out string cacheFilePath, out string targetsFilePath, out string propsFilePath, out string lockFilePath); var messages = !packageSpec.RestoreSettings.HideWarningsAndErrors && summary.Errors.Count > 0 ? summary.Errors : null; _restoreData[summary.InputPath] = new RestoreData() { _lastAssetsFileWriteTime = GetLastWriteTime(assetsFilePath), _lastCacheFileWriteTime = GetLastWriteTime(cacheFilePath), _lastTargetsFileWriteTime = GetLastWriteTime(targetsFilePath), _lastPropsFileWriteTime = GetLastWriteTime(propsFilePath), _lastLockFileWriteTime = GetLastWriteTime(lockFilePath), _globalPackagesFolderCreationTime = GetCreationTime(packageSpec.RestoreMetadata.PackagesPath), _messages = messages }; } else { _failedProjects.Add(summary.InputPath); } } }
async Task <PackageSpec> CreateProjectPackageSpec(DependencyGraphCacheContext context) { DependencyGraphSpec dependencySpec = await MSBuildPackageSpecCreator.GetDependencyGraphSpec(project, configuration, context?.Logger); context.AddToCache(dependencySpec); PackageSpec spec = dependencySpec.GetProjectSpec(project.FileName); if (spec != null) { return(spec); } throw new InvalidOperationException(GettextCatalog.GetString("Unable to create package spec for project. '{0}'", project.FileName)); }
public void AddProject_DoesNotClone(bool cpvmEnabled) { // Arrange var dependencyFoo = new LibraryDependency() { LibraryRange = new LibraryRange("foo", versionRange: cpvmEnabled ? null : VersionRange.Parse("1.0.0"), LibraryDependencyTarget.Package), }; var centralVersions = cpvmEnabled ? new List <CentralPackageVersion>() { new CentralPackageVersion("foo", VersionRange.Parse("1.0.0")) } : new List <CentralPackageVersion>(); var tfi = CreateTargetFrameworkInformation( new List <LibraryDependency>() { dependencyFoo }, centralVersions); var packageSpec = new PackageSpec(new List <TargetFrameworkInformation>() { tfi }); packageSpec.RestoreMetadata = new ProjectRestoreMetadata() { ProjectUniqueName = "a", CentralPackageVersionsEnabled = cpvmEnabled }; var dgSpec = new DependencyGraphSpec(); dgSpec.AddRestore("a"); dgSpec.AddProject(packageSpec); // Act var packageSpecFromDGSpec = dgSpec.GetProjectSpec("a"); // Assert Assert.True(packageSpec.Equals(packageSpecFromDGSpec)); }
private void DumpProjectRestoreInfo(string projectUniqueName, DependencyGraphSpec projectRestoreInfo) { try { var packageSpec = projectRestoreInfo.GetProjectSpec(projectUniqueName); var outputPath = packageSpec.RestoreMetadata.OutputPath; if (!Directory.Exists(outputPath)) { Directory.CreateDirectory(outputPath); } var dgPath = Path.Combine(outputPath, $"{Guid.NewGuid()}.dg"); projectRestoreInfo.Save(dgPath); } catch (Exception e) { _logger.LogError(e.ToString()); } }
// recursive static void ReportProjectReferences(ProjectReferenceNode source, PackageSpec project, NuGetFramework rootNuGetFramework, DependencyGraphSpec dependencyGraph, int indentLevel, HashSet <Node> vertices, HashSet <Edge> edges) { const int INDENT_SIZE = 2; NuGetFramework nearest = project.GetNearestFrameworkMatching(rootNuGetFramework); // TODO: This is done be caller....delete //var projectReference = new ProjectReferenceNode(project.FilePath, project.Version.ToString(), nearest); //projects.Add(projectReference); // indent shows levels of the graph Console.Write(new string(' ', indentLevel * INDENT_SIZE)); Console.WriteLine($"{project.RestoreMetadata.ProjectUniqueName}, v{project.Version}, ({nearest.GetShortFolderName()})"); ProjectRestoreMetadataFrameworkInfo resolvedTargetFramework = project.RestoreMetadata.TargetFrameworks.Single(tf => nearest.Equals(tf.FrameworkName)); // project references of a targetFramework foreach (ProjectRestoreReference projectRestoreReference in resolvedTargetFramework.ProjectReferences) { // TODO: PrivateAssets, ExcludeAssets, IncludeAssets //dependency.ProjectPath //dependency.ProjectUniqueName PackageSpec projectDependency = dependencyGraph.GetProjectSpec(projectRestoreReference.ProjectUniqueName); var projectDependencyReference = new ProjectReferenceNode( projectDependency.FilePath, projectDependency.Version.ToString(), projectDependency.GetNearestFrameworkMatching(rootNuGetFramework)); vertices.Add(projectDependencyReference); edges.Add(new Edge(source, projectDependencyReference)); //Console.WriteLine($"({projectDependency.Name}, {Path.GetFileName(projectDependency.FilePath)}) is a project reference of ({project.Name}, {Path.GetFileName(project.FilePath)}"); // recursive ReportProjectReferences(projectDependencyReference, projectDependency, rootNuGetFramework, dependencyGraph, indentLevel + 1, vertices, edges); } }
public static IReadOnlyList <PackageSpec> GetProjectSpecs(this DependencyGraphSpec dependencySpec, string projectPath) { var mainProjectSpec = dependencySpec.GetProjectSpec(projectPath); if (mainProjectSpec == null) { return(null); } var specs = new List <PackageSpec> (); specs.Add(mainProjectSpec); // Look for any DotNetCliTools foreach (var spec in dependencySpec.Projects) { if (spec.IsDotNetCliToolPackageSpecForProject(projectPath)) { specs.Add(spec); } } return(specs); }
private RestoreSummaryRequest Create( string projectNameToRestore, ExternalProjectReference project, HashSet <ExternalProjectReference> projectReferenceClosure, RestoreArgs restoreArgs, DependencyGraphSpec projectDgSpec, SettingsLoadingContext settingsLoadingContext) { var projectPackageSpec = projectDgSpec.GetProjectSpec(projectNameToRestore); //fallback paths, global packages path and sources need to all be passed in the dg spec var fallbackPaths = projectPackageSpec.RestoreMetadata.FallbackFolders; var globalPath = GetPackagesPath(restoreArgs, projectPackageSpec); var settings = Settings.LoadImmutableSettingsGivenConfigPaths(projectPackageSpec.RestoreMetadata.ConfigFilePaths, settingsLoadingContext); var sources = restoreArgs.GetEffectiveSources(settings, projectPackageSpec.RestoreMetadata.Sources); var clientPolicyContext = ClientPolicyContext.GetClientPolicy(settings, restoreArgs.Log); var sharedCache = _providerCache.GetOrCreate( globalPath, fallbackPaths.AsList(), sources, restoreArgs.CacheContext, restoreArgs.Log); var rootPath = Path.GetDirectoryName(project.PackageSpec.FilePath); // Create request var request = new RestoreRequest( project.PackageSpec, sharedCache, restoreArgs.CacheContext, clientPolicyContext, restoreArgs.Log) { // Set properties from the restore metadata ProjectStyle = project.PackageSpec.RestoreMetadata.ProjectStyle, // Project.json is special cased to put assets file and generated .props and targets in the project folder RestoreOutputPath = project.PackageSpec.RestoreMetadata.ProjectStyle == ProjectStyle.ProjectJson ? rootPath : project.PackageSpec.RestoreMetadata.OutputPath, DependencyGraphSpec = projectDgSpec, MSBuildProjectExtensionsPath = projectPackageSpec.RestoreMetadata.OutputPath }; var restoreLegacyPackagesDirectory = project.PackageSpec?.RestoreMetadata?.LegacyPackagesDirectory ?? DefaultRestoreLegacyPackagesDirectory; request.IsLowercasePackagesDirectory = !restoreLegacyPackagesDirectory; // Standard properties restoreArgs.ApplyStandardProperties(request); // Add project references request.ExternalProjects = projectReferenceClosure.ToList(); // The lock file is loaded later since this is an expensive operation var summaryRequest = new RestoreSummaryRequest( request, project.MSBuildProjectPath, settings.GetConfigFilePaths(), sources); return(summaryRequest); }
/// <summary> /// Gets a <see cref="DependencyGraphSpec" /> for the specified project. /// </summary> /// <param name="entryProjectPath">The full path to a project or Visual Studio Solution File.</param> /// <param name="globalProperties">An <see cref="IDictionary{String,String}" /> containing the global properties to use when evaluation MSBuild projects.</param> /// <returns>A <see cref="DependencyGraphSpec" /> for the specified project if they could be loaded, otherwise <code>null</code>.</returns> private DependencyGraphSpec GetDependencyGraphSpec(string entryProjectPath, IDictionary <string, string> globalProperties) { try { // TODO: Use a localized resource from https://github.com/NuGet/NuGet.Client/pull/3111 MSBuildLogger.LogMinimal("Determining projects to restore..."); var entryProjects = GetProjectGraphEntryPoints(entryProjectPath, globalProperties); // Load the projects via MSBuild and create an array of them since Parallel.ForEach is optimized for arrays var projects = LoadProjects(entryProjects)?.ToArray(); // If no projects were loaded, return null indicating that the projects could not be loaded. if (projects == null || projects.Length == 0) { return(null); } var sw = Stopwatch.StartNew(); var dependencyGraphSpec = new DependencyGraphSpec(isReadOnly: true); // Unique names created by the MSBuild restore target are project paths, these // can be different on case-insensitive file systems for the same project file. // To workaround this unique names should be compared based on the OS. var uniqueNameComparer = PathUtility.GetStringComparerBasedOnOS(); var projectPathLookup = new ConcurrentDictionary <string, string>(uniqueNameComparer); try { // Get the PackageSpecs in parallel because creating each one is relatively expensive so parallelism speeds things up Parallel.ForEach(projects, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, project => { var packageSpec = GetPackageSpec(project.OuterProject, project); if (packageSpec != null) { // Keep track of all project path casings var uniqueName = packageSpec.RestoreMetadata.ProjectUniqueName; if (uniqueName != null && !projectPathLookup.ContainsKey(uniqueName)) { projectPathLookup.TryAdd(uniqueName, uniqueName); } var projectPath = packageSpec.RestoreMetadata.ProjectPath; if (projectPath != null && !projectPathLookup.ContainsKey(projectPath)) { projectPathLookup.TryAdd(projectPath, projectPath); } // TODO: Remove this lock once https://github.com/NuGet/Home/issues/9002 is fixed lock (dependencyGraphSpec) { dependencyGraphSpec.AddProject(packageSpec); } } }); } catch (AggregateException e) { // Log exceptions thrown while creating PackageSpec objects foreach (var exception in e.Flatten().InnerExceptions) { LoggingQueue.TaskLoggingHelper.LogErrorFromException(exception); } return(null); } // Fix project reference casings to match the original project on case insensitive file systems. MSBuildRestoreUtility.NormalizePathCasings(projectPathLookup, dependencyGraphSpec); // Add all entry projects if they support restore. In most cases this is just a single project but if the entry // project is a solution, then all projects in the solution are added (if they support restore) foreach (var entryPoint in entryProjects) { PackageSpec project = dependencyGraphSpec.GetProjectSpec(entryPoint.ProjectFile); if (project != null && BuildTasksUtility.DoesProjectSupportRestore(project)) { dependencyGraphSpec.AddRestore(entryPoint.ProjectFile); } } sw.Stop(); MSBuildLogger.LogDebug(string.Format(CultureInfo.CurrentCulture, Strings.CreatedDependencyGraphSpec, sw.ElapsedMilliseconds)); return(dependencyGraphSpec); } catch (Exception e) { LoggingQueue.TaskLoggingHelper.LogErrorFromException(e, showStackTrace: true); } return(null); }