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));
        }
Exemple #4
0
        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());
        }
Exemple #5
0
        public Task <IReadOnlyList <RestoreSummaryRequest> > CreateRequests(RestoreArgs restoreContext)
        {
            var requests = GetRequestsFromItems(restoreContext, _dgFile);

            return(Task.FromResult(requests));
        }
Exemple #6
0
        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);
        }
Exemple #11
0
        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);
        }
Exemple #12
0
        /// <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));
            }
        }