private static async Task <IReadOnlyList <RestoreSummaryRequest> > CreateRequests( string input, RestoreArgs restoreContext) { foreach (var provider in restoreContext.RequestProviders) { if (await provider.Supports(input)) { return(await provider.CreateRequests( input, restoreContext)); } } if (File.Exists(input) || Directory.Exists(input)) { // Not a file or directory we know about. Try to be helpful without response. throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, GetInvalidInputErrorMessage(input), input)); } throw new FileNotFoundException(input); }
private RestoreSummaryRequest Create( string inputPath, RestoreArgs restoreContext) { var file = new FileInfo(inputPath); // Get settings relative to the input file var settings = restoreContext.GetSettings(file.DirectoryName); var sources = restoreContext.GetEffectiveSources(settings, null); var FallbackPackageFolders = restoreContext.GetEffectiveFallbackPackageFolders(settings); var globalPath = restoreContext.GetEffectiveGlobalPackagesFolder(file.DirectoryName, settings); var sharedCache = _providerCache.GetOrCreate( globalPath, FallbackPackageFolders, sources, restoreContext.CacheContext, restoreContext.Log); var project = JsonPackageSpecReader.GetPackageSpec(file.Directory.Name, file.FullName); var request = new RestoreRequest( project, sharedCache, restoreContext.CacheContext, restoreContext.Log) { ParentId = restoreContext.ParentId }; restoreContext.ApplyStandardProperties(request); var summaryRequest = new RestoreSummaryRequest(request, inputPath, SettingsUtility.GetConfigFilePaths(settings), sources); return(summaryRequest); }
public Task <IReadOnlyList <RestoreSummaryRequest> > CreateRequests( string inputPath, RestoreArgs restoreContext) { var paths = new List <string>(); if (Directory.Exists(inputPath)) { paths.AddRange(GetProjectJsonFilesInDirectory(inputPath)); } else { paths.Add(inputPath); } var requests = new List <RestoreSummaryRequest>(paths.Count); foreach (var path in paths) { requests.Add(Create(path, restoreContext)); } return(Task.FromResult <IReadOnlyList <RestoreSummaryRequest> >(requests)); }
private IReadOnlyList <RestoreSummaryRequest> GetRequestsFromItems(RestoreArgs restoreContext, DependencyGraphSpec dgFile) { if (restoreContext == null) { throw new ArgumentNullException(nameof(restoreContext)); } if (dgFile == null) { throw new ArgumentNullException(nameof(dgFile)); } // Validate the dg file input, this throws if errors are found. SpecValidationUtility.ValidateDependencySpec(dgFile); // Create requests var requests = new ConcurrentBag <RestoreSummaryRequest>(); var toolRequests = new ConcurrentBag <RestoreSummaryRequest>(); var parallelOptions = new ParallelOptions { // By default, max degree of parallelism is -1 which means no upper bound. // Limiting to processor count reduces task context switching which is better MaxDegreeOfParallelism = Environment.ProcessorCount }; using (var settingsLoadingContext = new SettingsLoadingContext()) { // Parallel.Foreach has an optimization for Arrays, so calling .ToArray() is better and adds almost no overhead Parallel.ForEach(dgFile.Restore.ToArray(), parallelOptions, projectNameToRestore => { IReadOnlyList <PackageSpec> closure = dgFile.GetClosure(projectNameToRestore); DependencyGraphSpec projectDependencyGraphSpec = dgFile.CreateFromClosure(projectNameToRestore, closure); var externalClosure = new HashSet <ExternalProjectReference>(closure.Select(GetExternalProject)); ExternalProjectReference rootProject = externalClosure.Single(p => StringComparer.Ordinal.Equals(projectNameToRestore, p.UniqueName)); RestoreSummaryRequest request = Create( projectNameToRestore, rootProject, externalClosure, restoreContext, projectDependencyGraphSpec, settingsLoadingContext); if (request.Request.ProjectStyle == ProjectStyle.DotnetCliTool) { // Store tool requests to be filtered later toolRequests.Add(request); } else { requests.Add(request); } }); } // Filter out duplicate tool restore requests foreach (RestoreSummaryRequest subSetRequest in ToolRestoreUtility.GetSubSetRequests(toolRequests)) { requests.Add(subSetRequest); } return(requests.ToArray()); }
public Task <IReadOnlyList <RestoreSummaryRequest> > CreateRequests(RestoreArgs restoreContext) { var requests = GetRequestsFromItems(restoreContext, _dgFile); return(Task.FromResult(requests)); }
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> /// Restores a package by querying, downloading, and unzipping it without generating any other files (like project.assets.json). /// </summary> /// <param name="projectPath">The full path to the project.</param> /// <param name="id">The ID of the package.</param> /// <param name="version">The version of the package.</param> /// <param name="settings">The NuGet settings to use.</param> /// <param name="logger">An <see cref="ILogger"/> to use for logging.</param> /// <returns></returns> public static Task <IReadOnlyList <RestoreResultPair> > RunWithoutCommit(string projectPath, string id, string version, ISettings settings, ILogger logger) { using (SourceCacheContext sourceCacheContext = new SourceCacheContext { IgnoreFailedSources = true, }) { // The package spec details what packages to restore PackageSpec packageSpec = new PackageSpec(TargetFrameworks.Select(i => new TargetFrameworkInformation { FrameworkName = i, }).ToList()) { Dependencies = new List <LibraryDependency> { new LibraryDependency { LibraryRange = new LibraryRange(id, new VersionRange(NuGetVersion.Parse(version)), LibraryDependencyTarget.Package), SuppressParent = LibraryIncludeFlags.All, AutoReferenced = true, IncludeType = LibraryIncludeFlags.None, Type = LibraryDependencyType.Build } }, RestoreMetadata = new ProjectRestoreMetadata { ProjectPath = projectPath, ProjectName = Path.GetFileNameWithoutExtension(projectPath), ProjectStyle = ProjectStyle.PackageReference, ProjectUniqueName = projectPath, OutputPath = Path.GetTempPath(), OriginalTargetFrameworks = TargetFrameworks.Select(i => i.ToString()).ToList(), ConfigFilePaths = SettingsUtility.GetConfigFilePaths(settings).ToList(), PackagesPath = SettingsUtility.GetGlobalPackagesFolder(settings), Sources = SettingsUtility.GetEnabledSources(settings).ToList(), FallbackFolders = SettingsUtility.GetFallbackPackageFolders(settings).ToList() }, FilePath = projectPath, Name = Path.GetFileNameWithoutExtension(projectPath), }; DependencyGraphSpec dependencyGraphSpec = new DependencyGraphSpec(); dependencyGraphSpec.AddProject(packageSpec); dependencyGraphSpec.AddRestore(packageSpec.RestoreMetadata.ProjectUniqueName); IPreLoadedRestoreRequestProvider requestProvider = new DependencyGraphSpecRequestProvider(new RestoreCommandProvidersCache(), dependencyGraphSpec); RestoreArgs restoreArgs = new RestoreArgs { AllowNoOp = true, CacheContext = sourceCacheContext, CachingSourceProvider = new CachingSourceProvider(new PackageSourceProvider(settings)), Log = logger, }; // Create requests from the arguments IReadOnlyList <RestoreSummaryRequest> requests = requestProvider.CreateRequests(restoreArgs).Result; // Restore the package without generating extra files return(RestoreRunner.RunWithoutCommit(requests, restoreArgs)); } }
/// <summary> /// Restores a package by querying, downloading, and unzipping it without generating any other files (like project.assets.json). /// </summary> /// <param name="libraryIdentity">The <see cref="LibraryIdentity"/> of the package.</param> /// <param name="settings">The NuGet settings to use.</param> /// <param name="logger">An <see cref="ILogger"/> to use for logging.</param> /// <returns></returns> public static Task <IReadOnlyList <RestoreResultPair> > RunWithoutCommit(LibraryIdentity libraryIdentity, ISettings settings, ILogger logger) { using (var sourceCacheContext = new SourceCacheContext { IgnoreFailedSources = true, }) { var projectDirectory = Path.Combine(NuGetEnvironment.GetFolderPath(NuGetFolderPath.Temp), Guid.NewGuid().ToString("N")); var projectName = Guid.NewGuid().ToString("N"); var projectFullPath = Path.Combine(projectDirectory, $"{projectName}.proj"); // Iterate through TargetFrameworks to generate Lists required for packageSpec var frameworks = new List <TargetFrameworkInformation>(TargetFrameworks.Count); var originalTargetFrameworks = new List <string>(TargetFrameworks.Count); foreach (var tf in TargetFrameworks) { frameworks.Add(new TargetFrameworkInformation { FrameworkName = tf }); originalTargetFrameworks.Add(tf.ToString()); } // The package spec details what packages to restore var packageSpec = new PackageSpec(frameworks) { Dependencies = new List <LibraryDependency> { new LibraryDependency { LibraryRange = new LibraryRange( libraryIdentity.Name, new VersionRange( minVersion: libraryIdentity.Version, includeMinVersion: true, maxVersion: libraryIdentity.Version, includeMaxVersion: true), LibraryDependencyTarget.Package), SuppressParent = LibraryIncludeFlags.All, AutoReferenced = true, IncludeType = LibraryIncludeFlags.None, } }, RestoreMetadata = new ProjectRestoreMetadata { ProjectPath = projectFullPath, ProjectName = projectName, ProjectStyle = ProjectStyle.PackageReference, ProjectUniqueName = projectFullPath, OutputPath = projectDirectory, OriginalTargetFrameworks = originalTargetFrameworks, ConfigFilePaths = settings.GetConfigFilePaths(), PackagesPath = SettingsUtility.GetGlobalPackagesFolder(settings), Sources = SettingsUtility.GetEnabledSources(settings).AsList(), FallbackFolders = SettingsUtility.GetFallbackPackageFolders(settings).ToList() }, FilePath = projectFullPath, Name = projectName, }; var dependencyGraphSpec = new DependencyGraphSpec(); dependencyGraphSpec.AddProject(packageSpec); dependencyGraphSpec.AddRestore(packageSpec.RestoreMetadata.ProjectUniqueName); IPreLoadedRestoreRequestProvider requestProvider = new DependencyGraphSpecRequestProvider(new RestoreCommandProvidersCache(), dependencyGraphSpec); var restoreArgs = new RestoreArgs { AllowNoOp = false, CacheContext = sourceCacheContext, #pragma warning disable CS0618 // Type or member is obsolete CachingSourceProvider = new CachingSourceProvider(new PackageSourceProvider(settings, enablePackageSourcesChangedEvent: false)), #pragma warning restore CS0618 // Type or member is obsolete Log = logger, }; // Create requests from the arguments var requests = requestProvider.CreateRequests(restoreArgs).Result; // Restore the package without generating extra files return(RestoreRunner.RunWithoutCommit(requests, restoreArgs)); } }
/// <summary> /// Create requests, execute requests, and commit restore results. /// </summary> public static async Task <IReadOnlyList <RestoreSummary> > RunAsync(RestoreArgs restoreContext) { // Run requests return(await RunAsync(restoreContext, CancellationToken.None)); }
/// <summary> /// Create restore requests but do not execute them. /// </summary> public static async Task <IReadOnlyList <RestoreSummaryRequest> > GetRequests(RestoreArgs restoreContext) { // Get requests var requests = new List <RestoreSummaryRequest>(); var inputs = new List <string>(restoreContext.Inputs); // If there are no inputs, use the current directory if (restoreContext.PreLoadedRequestProviders.Count < 1 && !inputs.Any()) { inputs.Add(Path.GetFullPath(".")); } // Ignore casing on windows and mac var comparer = (RuntimeEnvironmentHelper.IsWindows || RuntimeEnvironmentHelper.IsMacOSX) ? StringComparer.OrdinalIgnoreCase : StringComparer.Ordinal; var uniqueRequest = new HashSet <string>(comparer); // Create requests // Pre-loaded requests foreach (var request in await CreatePreLoadedRequests(restoreContext)) { // De-dupe requests if (request.Request.LockFilePath == null || uniqueRequest.Add(request.Request.LockFilePath)) { requests.Add(request); } } // Input based requests foreach (var input in inputs) { var inputRequests = await CreateRequests(input, restoreContext); if (inputRequests.Count == 0) { // No need to throw here - the situation is harmless, and we want to report all possible // inputs that don't resolve to a project. var message = string.Format( CultureInfo.CurrentCulture, Strings.Error_UnableToLocateRestoreTarget, Path.GetFullPath(input)); await restoreContext.Log.LogAsync(RestoreLogMessage.CreateWarning(NuGetLogCode.NU1501, message)); } foreach (var request in inputRequests) { // De-dupe requests if (uniqueRequest.Add(request.Request.LockFilePath)) { requests.Add(request); } } } return(requests); }
public static async Task <IReadOnlyList <RestoreSummary> > Run(RestoreArgs restoreContext) { var maxTasks = 1; if (!restoreContext.DisableParallel && !RuntimeEnvironmentHelper.IsMono) { maxTasks = Environment.ProcessorCount; } if (maxTasks < 1) { maxTasks = 1; } var log = restoreContext.Log; if (maxTasks > 1) { log.LogVerbose(string.Format( CultureInfo.CurrentCulture, Strings.Log_RunningParallelRestore, maxTasks)); } else { log.LogVerbose(Strings.Log_RunningNonParallelRestore); } // Get requests var requests = new Queue <RestoreSummaryRequest>(); var restoreTasks = new List <Task <RestoreSummary> >(maxTasks); var restoreSummaries = new List <RestoreSummary>(requests.Count); var inputs = new List <string>(restoreContext.Inputs); // If there are no inputs, use the current directory if (!inputs.Any()) { inputs.Add(Path.GetFullPath(".")); } // Ignore casing on windows and mac var comparer = (RuntimeEnvironmentHelper.IsWindows || RuntimeEnvironmentHelper.IsMacOSX) ? StringComparer.OrdinalIgnoreCase : StringComparer.Ordinal; var uniqueRequest = new HashSet <string>(comparer); // Create requests foreach (var input in inputs) { var inputRequests = await CreateRequests(input, restoreContext); if (inputRequests.Count == 0) { // No need to throw here - the situation is harmless, and we want to report all possible // inputs that don't resolve to a project. log.LogWarning(string.Format( CultureInfo.CurrentCulture, Strings.Error_UnableToLocateRestoreTarget, Path.GetFullPath(input))); } foreach (var request in inputRequests) { // De-dupe requests if (uniqueRequest.Add(request.Request.LockFilePath)) { requests.Enqueue(request); } } } // Run requests while (requests.Count > 0) { // Throttle and wait for a task to finish if we have hit the limit if (restoreTasks.Count == maxTasks) { var restoreSummary = await CompleteTaskAsync(restoreTasks); restoreSummaries.Add(restoreSummary); } var request = requests.Dequeue(); var task = Task.Run(async() => await Execute(request)); restoreTasks.Add(task); } // Wait for all restores to finish while (restoreTasks.Count > 0) { var restoreSummary = await CompleteTaskAsync(restoreTasks); restoreSummaries.Add(restoreSummary); } // Summary return(restoreSummaries); }
/// <summary> /// Restores a package by querying, downloading, and unzipping it without generating any other files (like project.assets.json). /// </summary> /// <param name="libraryIdentity">The <see cref="LibraryIdentity"/> of the package.</param> /// <param name="settings">The NuGet settings to use.</param> /// <param name="logger">An <see cref="ILogger"/> to use for logging.</param> /// <returns></returns> public static Task <IReadOnlyList <RestoreResultPair> > RunWithoutCommit(LibraryIdentity libraryIdentity, ISettings settings, ILogger logger) { using (var sourceCacheContext = new SourceCacheContext { IgnoreFailedSources = true, }) { var projectPath = Path.Combine(Path.GetTempPath(), TempProjectName); // The package spec details what packages to restore var packageSpec = new PackageSpec(TargetFrameworks.Select(i => new TargetFrameworkInformation { FrameworkName = i, }).ToList()) { Dependencies = new List <LibraryDependency> { new LibraryDependency { LibraryRange = new LibraryRange( libraryIdentity.Name, new VersionRange( minVersion: libraryIdentity.Version, includeMinVersion: true, maxVersion: libraryIdentity.Version, includeMaxVersion: true), LibraryDependencyTarget.Package), SuppressParent = LibraryIncludeFlags.All, AutoReferenced = true, IncludeType = LibraryIncludeFlags.None, Type = LibraryDependencyType.Build } }, RestoreMetadata = new ProjectRestoreMetadata { ProjectPath = projectPath, ProjectName = Path.GetFileNameWithoutExtension(TempProjectName), ProjectStyle = ProjectStyle.PackageReference, ProjectUniqueName = TempProjectName, OutputPath = Path.GetTempPath(), OriginalTargetFrameworks = TargetFrameworks.Select(i => i.ToString()).ToList(), ConfigFilePaths = settings.GetConfigFilePaths(), PackagesPath = SettingsUtility.GetGlobalPackagesFolder(settings), Sources = SettingsUtility.GetEnabledSources(settings).ToList(), FallbackFolders = SettingsUtility.GetFallbackPackageFolders(settings).ToList() }, FilePath = projectPath, Name = Path.GetFileNameWithoutExtension(TempProjectName), }; var dependencyGraphSpec = new DependencyGraphSpec(); dependencyGraphSpec.AddProject(packageSpec); dependencyGraphSpec.AddRestore(packageSpec.RestoreMetadata.ProjectUniqueName); IPreLoadedRestoreRequestProvider requestProvider = new DependencyGraphSpecRequestProvider(new RestoreCommandProvidersCache(), dependencyGraphSpec); var restoreArgs = new RestoreArgs { AllowNoOp = true, CacheContext = sourceCacheContext, #pragma warning disable CS0618 // Type or member is obsolete CachingSourceProvider = new CachingSourceProvider(new PackageSourceProvider(settings, enablePackageSourcesChangedEvent: false)), #pragma warning restore CS0618 // Type or member is obsolete Log = logger, }; // Create requests from the arguments var requests = requestProvider.CreateRequests(restoreArgs).Result; // Restore the package without generating extra files return(RestoreRunner.RunWithoutCommit(requests, restoreArgs)); } }