Exemple #1
0
        public override bool Execute()
        {
#if DEBUG
            var debugRestoreTask = Environment.GetEnvironmentVariable("DEBUG_RESTORE_TASK");
            if (!string.IsNullOrEmpty(debugRestoreTask) && debugRestoreTask.Equals(bool.TrueString, StringComparison.OrdinalIgnoreCase))
            {
#if IS_CORECLR
                Console.WriteLine("Waiting for debugger to attach.");
                Console.WriteLine($"Process ID: {Process.GetCurrentProcess().Id}");

                while (!Debugger.IsAttached)
                {
                    System.Threading.Thread.Sleep(100);
                }
                Debugger.Break();
#else
                Debugger.Launch();
#endif
            }
#endif
            var log = new MSBuildLogger(Log);

            // Log inputs
            log.LogDebug($"(in) RestoreGraphItems Count '{RestoreGraphItems?.Count() ?? 0}'");
            log.LogDebug($"(in) RestoreDisableParallel '{RestoreDisableParallel}'");
            log.LogDebug($"(in) RestoreNoCache '{RestoreNoCache}'");
            log.LogDebug($"(in) RestoreIgnoreFailedSources '{RestoreIgnoreFailedSources}'");
            log.LogDebug($"(in) RestoreRecursive '{RestoreRecursive}'");
            log.LogDebug($"(in) RestoreForce '{RestoreForce}'");
            log.LogDebug($"(in) HideWarningsAndErrors '{HideWarningsAndErrors}'");
            log.LogDebug($"(in) RestoreForceEvaluate '{RestoreForceEvaluate}'");

            try
            {
                DefaultCredentialServiceUtility.SetupDefaultCredentialService(log, !Interactive);
                return(ExecuteAsync(log).Result);
            }
            catch (AggregateException ex) when(_cts.Token.IsCancellationRequested && ex.InnerException is TaskCanceledException)
            {
                // Canceled by user
                log.LogError(Strings.RestoreCanceled);
                return(false);
            }
            catch (Exception e)
            {
                ExceptionUtilities.LogException(e, log);
                return(false);
            }
            finally
            {
                // The CredentialService lifetime is for the duration of the process. We should not leave a potentially unavailable logger.
                // We need to update the delegating logger with a null instance
                // because the tear downs of the plugins and similar rely on idleness and process exit.
                DefaultCredentialServiceUtility.UpdateCredentialServiceDelegatingLogger(NullLogger.Instance);
            }
        }
Exemple #2
0
        public static async Task <bool> RestoreAsync(
            DependencyGraphSpec dependencyGraphSpec,
            bool interactive,
            bool recursive,
            bool noCache,
            bool ignoreFailedSources,
            bool disableParallel,
            bool force,
            bool forceEvaluate,
            bool hideWarningsAndErrors,
            bool restorePC,
            Common.ILogger log,
            CancellationToken cancellationToken)
        {
            if (dependencyGraphSpec == null)
            {
                throw new ArgumentNullException(nameof(dependencyGraphSpec));
            }

            if (log == null)
            {
                throw new ArgumentNullException(nameof(log));
            }

            try
            {
                DefaultCredentialServiceUtility.SetupDefaultCredentialService(log, !interactive);

                // Set connection limit
                NetworkProtocolUtility.SetConnectionLimit();

                // Set user agent string used for network calls
#if IS_CORECLR
                UserAgent.SetUserAgentString(new UserAgentStringBuilder("NuGet .NET Core MSBuild Task")
                                             .WithOSDescription(RuntimeInformation.OSDescription));
#else
                // OS description is set by default on Desktop
                UserAgent.SetUserAgentString(new UserAgentStringBuilder("NuGet Desktop MSBuild Task"));
#endif

                // This method has no effect on .NET Core.
                NetworkProtocolUtility.ConfigureSupportedSslProtocols();

                var restoreSummaries = new List <RestoreSummary>();
                var providerCache    = new RestoreCommandProvidersCache();

#if IS_DESKTOP
                if (restorePC && dependencyGraphSpec.Projects.Any(i => i.RestoreMetadata.ProjectStyle == ProjectStyle.PackagesConfig))
                {
                    var v2RestoreResult = await PerformNuGetV2RestoreAsync(log, dependencyGraphSpec, noCache, disableParallel, interactive);

                    restoreSummaries.Add(v2RestoreResult);

                    if (restoreSummaries.Count < 1)
                    {
                        var message = string.Format(
                            Strings.InstallCommandNothingToInstall,
                            "packages.config"
                            );

                        log.LogMinimal(message);
                    }

                    if (!v2RestoreResult.Success)
                    {
                        v2RestoreResult
                        .Errors
                        .Where(l => l.Level == LogLevel.Warning)
                        .ForEach(message =>
                        {
                            log.LogWarning(message.Message);
                        });
                    }
                }
#endif

                using (var cacheContext = new SourceCacheContext())
                {
                    cacheContext.NoCache             = noCache;
                    cacheContext.IgnoreFailedSources = ignoreFailedSources;

                    // Pre-loaded request provider containing the graph file
                    var providers = new List <IPreLoadedRestoreRequestProvider>();

                    if (dependencyGraphSpec.Restore.Count > 0)
                    {
                        // Add all child projects
                        if (recursive)
                        {
                            AddAllProjectsForRestore(dependencyGraphSpec);
                        }

                        providers.Add(new DependencyGraphSpecRequestProvider(providerCache, dependencyGraphSpec));

                        var restoreContext = new RestoreArgs()
                        {
                            CacheContext    = cacheContext,
                            LockFileVersion = LockFileFormat.Version,
                            // 'dotnet restore' fails on slow machines (https://github.com/NuGet/Home/issues/6742)
                            // The workaround is to pass the '--disable-parallel' option.
                            // We apply the workaround by default when the system has 1 cpu.
                            // This will fix restore failures on VMs with 1 CPU and containers with less or equal to 1 CPU assigned.
                            DisableParallel           = Environment.ProcessorCount == 1 ? true : disableParallel,
                            Log                       = log,
                            MachineWideSettings       = new XPlatMachineWideSetting(),
                            PreLoadedRequestProviders = providers,
                            AllowNoOp                 = !force,
                            HideWarningsAndErrors     = hideWarningsAndErrors,
                            RestoreForceEvaluate      = forceEvaluate
                        };

                        if (restoreContext.DisableParallel)
                        {
                            HttpSourceResourceProvider.Throttle = SemaphoreSlimThrottle.CreateBinarySemaphore();
                        }

                        cancellationToken.ThrowIfCancellationRequested();

                        restoreSummaries.AddRange(await RestoreRunner.RunAsync(restoreContext, cancellationToken));
                    }
                }

                if (restoreSummaries.Count < 1)
                {
                    log.LogMinimal(Strings.NoProjectsToRestore);
                }
                else
                {
                    RestoreSummary.Log(log, restoreSummaries);
                }
                return(restoreSummaries.All(x => x.Success));
            }
            finally
            {
                // The CredentialService lifetime is for the duration of the process. We should not leave a potentially unavailable logger.
                // We need to update the delegating logger with a null instance
                // because the tear downs of the plugins and similar rely on idleness and process exit.
                DefaultCredentialServiceUtility.UpdateCredentialServiceDelegatingLogger(NullLogger.Instance);
            }
        }
        public static async Task <bool> RestoreAsync(
            DependencyGraphSpec dependencyGraphSpec,
            bool interactive,
            bool recursive,
            bool noCache,
            bool ignoreFailedSources,
            bool disableParallel,
            bool force,
            bool forceEvaluate,
            bool hideWarningsAndErrors,
            bool restorePC,
            bool cleanupAssetsForUnsupportedProjects,
            Common.ILogger log,
            CancellationToken cancellationToken)
        {
            if (dependencyGraphSpec == null)
            {
                throw new ArgumentNullException(nameof(dependencyGraphSpec));
            }

            if (log == null)
            {
                throw new ArgumentNullException(nameof(log));
            }

            try
            {
                DefaultCredentialServiceUtility.SetupDefaultCredentialService(log, !interactive);

                // Set connection limit
                NetworkProtocolUtility.SetConnectionLimit();

                // Set user agent string used for network calls
#if IS_CORECLR
                UserAgent.SetUserAgentString(new UserAgentStringBuilder("NuGet .NET Core MSBuild Task")
                                             .WithOSDescription(RuntimeInformation.OSDescription));
#else
                // OS description is set by default on Desktop
                UserAgent.SetUserAgentString(new UserAgentStringBuilder("NuGet Desktop MSBuild Task"));
#endif

                X509TrustStore.InitializeForDotNetSdk(log);

                var restoreSummaries = new List <RestoreSummary>();
                var providerCache    = new RestoreCommandProvidersCache();

#if IS_DESKTOP
                if (restorePC && dependencyGraphSpec.Projects.Any(i => i.RestoreMetadata.ProjectStyle == ProjectStyle.PackagesConfig))
                {
                    var v2RestoreResult = await PerformNuGetV2RestoreAsync(log, dependencyGraphSpec, noCache, disableParallel, interactive);

                    restoreSummaries.Add(v2RestoreResult);

                    if (restoreSummaries.Count < 1)
                    {
                        var message = string.Format(
                            Strings.InstallCommandNothingToInstall,
                            "packages.config"
                            );

                        log.LogMinimal(message);
                    }

                    if (!v2RestoreResult.Success)
                    {
                        v2RestoreResult
                        .Errors
                        .Where(l => l.Level == LogLevel.Warning)
                        .ForEach(message =>
                        {
                            log.LogWarning(message.Message);
                        });
                    }
                }
#endif

                using (var cacheContext = new SourceCacheContext())
                {
                    cacheContext.NoCache             = noCache;
                    cacheContext.IgnoreFailedSources = ignoreFailedSources;

                    // Pre-loaded request provider containing the graph file
                    var providers = new List <IPreLoadedRestoreRequestProvider>();

                    if (dependencyGraphSpec.Restore.Count > 0)
                    {
                        // Add all child projects
                        if (recursive)
                        {
                            AddAllProjectsForRestore(dependencyGraphSpec);
                        }

                        providers.Add(new DependencyGraphSpecRequestProvider(providerCache, dependencyGraphSpec));

                        var restoreContext = new RestoreArgs()
                        {
                            CacheContext    = cacheContext,
                            LockFileVersion = LockFileFormat.Version,
                            // 'dotnet restore' fails on slow machines (https://github.com/NuGet/Home/issues/6742)
                            // The workaround is to pass the '--disable-parallel' option.
                            // We apply the workaround by default when the system has 1 cpu.
                            // This will fix restore failures on VMs with 1 CPU and containers with less or equal to 1 CPU assigned.
                            DisableParallel           = Environment.ProcessorCount == 1 ? true : disableParallel,
                            Log                       = log,
                            MachineWideSettings       = new XPlatMachineWideSetting(),
                            PreLoadedRequestProviders = providers,
                            AllowNoOp                 = !force,
                            HideWarningsAndErrors     = hideWarningsAndErrors,
                            RestoreForceEvaluate      = forceEvaluate
                        };

                        if (restoreContext.DisableParallel)
                        {
                            HttpSourceResourceProvider.Throttle = SemaphoreSlimThrottle.CreateBinarySemaphore();
                        }

                        cancellationToken.ThrowIfCancellationRequested();

                        restoreSummaries.AddRange(await RestoreRunner.RunAsync(restoreContext, cancellationToken));
                    }

                    if (cleanupAssetsForUnsupportedProjects)
                    {
                        // Restore assets are normally left on disk between restores for all projects.  This can cause a condition where a project that supports PackageReference was restored
                        // but then a user changes a branch or some other condition and now the project does not use PackageReference. Since the restore assets are left on disk, the build
                        // consumes them which can cause build errors. The code below cleans up all of the files that we write so that they are not used during build
                        Parallel.ForEach(dependencyGraphSpec.Projects.Where(i => !DoesProjectSupportRestore(i)), project =>
                        {
                            if (project.RestoreMetadata == null || string.IsNullOrWhiteSpace(project.RestoreMetadata.OutputPath) || string.IsNullOrWhiteSpace(project.RestoreMetadata.ProjectPath))
                            {
                                return;
                            }

                            // project.assets.json
                            FileUtility.Delete(Path.Combine(project.RestoreMetadata.OutputPath, LockFileFormat.AssetsFileName));

                            // project.csproj.nuget.cache
                            FileUtility.Delete(project.RestoreMetadata.CacheFilePath);

                            // project.csproj.nuget.g.props
                            FileUtility.Delete(BuildAssetsUtils.GetMSBuildFilePathForPackageReferenceStyleProject(project, BuildAssetsUtils.PropsExtension));

                            // project..csproj.nuget.g.targets
                            FileUtility.Delete(BuildAssetsUtils.GetMSBuildFilePathForPackageReferenceStyleProject(project, BuildAssetsUtils.TargetsExtension));

                            // project.csproj.nuget.dgspec.json
                            FileUtility.Delete(Path.Combine(project.RestoreMetadata.OutputPath, DependencyGraphSpec.GetDGSpecFileName(Path.GetFileName(project.RestoreMetadata.ProjectPath))));
                        });
                    }
                }

                if (restoreSummaries.Count < 1)
                {
                    log.LogMinimal(Strings.NoProjectsToRestore);
                }
                else
                {
                    RestoreSummary.Log(log, restoreSummaries);
                }
                return(restoreSummaries.All(x => x.Success));
            }
            finally
            {
                // The CredentialService lifetime is for the duration of the process. We should not leave a potentially unavailable logger.
                // We need to update the delegating logger with a null instance
                // because the tear downs of the plugins and similar rely on idleness and process exit.
                DefaultCredentialServiceUtility.UpdateCredentialServiceDelegatingLogger(NullLogger.Instance);
            }
        }
            public static SdkResult GetSdkResult(SdkReference sdk, object nuGetVersion, SdkResolverContext context, SdkResultFactory factory)
            {
                // Cast the NuGet version since the caller does not want to consume NuGet classes directly
                var parsedSdkVersion = (NuGetVersion)nuGetVersion;

                // Stores errors and warnings for the result
                ICollection <string> errors   = new List <string>();
                ICollection <string> warnings = new List <string>();

                // Load NuGet settings and a path resolver
                var settings = Settings.LoadDefaultSettings(context.ProjectFilePath);

                var fallbackPackagePathResolver = new FallbackPackagePathResolver(NuGetPathContext.Create(settings));

                var libraryIdentity = new LibraryIdentity(sdk.Name, parsedSdkVersion, LibraryType.Package);

                // Attempt to find a package if its already installed
                if (!TryGetMSBuildSdkPackageInfo(fallbackPackagePathResolver, libraryIdentity, out var installedPath, out var installedVersion))
                {
                    try
                    {
                        var nugetSDKLogger = new NuGetSdkLogger(context.Logger, warnings, errors);
                        DefaultCredentialServiceUtility.SetupDefaultCredentialService(nugetSDKLogger, nonInteractive: context.IsNonInteractive());

                        // Asynchronously run the restore without a commit which find the package on configured feeds, download, and unzip it without generating any other files
                        // This must be run in its own task because legacy project system evaluates projects on the UI thread which can cause RunWithoutCommit() to deadlock
                        // https://developercommunity.visualstudio.com/content/problem/311379/solution-load-never-completes-when-project-contain.html
                        var restoreTask = Task.Run(() => RestoreRunnerEx.RunWithoutCommit(
                                                       libraryIdentity,
                                                       settings,
                                                       nugetSDKLogger));

                        var results = restoreTask.Result;

                        fallbackPackagePathResolver = new FallbackPackagePathResolver(NuGetPathContext.Create(settings));

                        // Look for a successful result, any errors are logged by NuGet
                        foreach (var result in results.Select(i => i.Result).Where(i => i.Success))
                        {
                            // Find the information about the package that was installed.  In some cases, the version can be different than what was specified (like you specify 1.0 but get 1.0.0)
                            var installedPackage = result.GetAllInstalled().FirstOrDefault(i => i == libraryIdentity);

                            if (installedPackage != null)
                            {
                                if (TryGetMSBuildSdkPackageInfo(fallbackPackagePathResolver, installedPackage, out installedPath, out installedVersion))
                                {
                                    break;
                                }

                                // This should never happen because we were told the package was successfully installed.
                                // If we can't find it, we probably did something wrong with the NuGet API
                                errors.Add(string.Format(CultureInfo.CurrentCulture, Strings.CouldNotFindInstalledPackage, sdk));
                            }
                            else
                            {
                                // This should never happen because we were told the restore succeeded.
                                // If we can't find the package from GetAllInstalled(), we probably did something wrong with the NuGet API
                                errors.Add(string.Format(CultureInfo.CurrentCulture, Strings.PackageWasNotInstalled, sdk, sdk.Name));
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        errors.Add(e.Message);
                    }
                    finally
                    {
                        // The CredentialService lifetime is for the duration of the process. We should not leave a potentially unavailable logger.
                        DefaultCredentialServiceUtility.UpdateCredentialServiceDelegatingLogger(NullLogger.Instance);
                    }
                }

                if (errors.Count == 0)
                {
                    return(factory.IndicateSuccess(path: installedPath, version: installedVersion, warnings: warnings));
                }

                return(factory.IndicateFailure(errors, warnings));
            }