public async Task BuildIntegratedNuGetProject_RestoreFailed_PersistDGSpecFile() { // Arrange var projectName = "testproj"; using (var packagesFolder = TestDirectory.Create()) using (var rootFolder = TestDirectory.Create()) { var projectFolder = new DirectoryInfo(Path.Combine(rootFolder, projectName)); projectFolder.Create(); var projectConfig = new FileInfo(Path.Combine(projectFolder.FullName, "project.json")); var msbuildProjectPath = new FileInfo(Path.Combine(projectFolder.FullName, $"{projectName}.csproj")); BuildIntegrationTestUtility.CreateConfigJson(projectConfig.FullName); var json = JObject.Parse(File.ReadAllText(projectConfig.FullName)); // invalid version for nuget.versioning package which will make this restore fail. JsonConfigUtility.AddDependency(json, new PackageDependency("nuget.versioning", VersionRange.Parse("3000.0.0"))); using (var writer = new StreamWriter(projectConfig.FullName)) { writer.Write(json.ToString()); } var sources = new List <SourceRepository> { }; var testLogger = new TestLogger(); var settings = new Settings(rootFolder); settings.SetValue(SettingsUtility.ConfigSection, "globalPackagesFolder", packagesFolder); var project = new ProjectJsonNuGetProject(projectConfig.FullName, msbuildProjectPath.FullName); var solutionManager = new TestSolutionManager(false); solutionManager.NuGetProjects.Add(project); var restoreContext = new DependencyGraphCacheContext(testLogger, settings); var providersCache = new RestoreCommandProvidersCache(); var dgSpec = await DependencyGraphRestoreUtility.GetSolutionRestoreSpec(solutionManager, restoreContext); var restoreSummaries = await DependencyGraphRestoreUtility.RestoreAsync( solutionManager, restoreContext, providersCache, (c) => { }, sources, Guid.Empty, false, dgSpec, testLogger, CancellationToken.None); foreach (var restoreSummary in restoreSummaries) { Assert.False(restoreSummary.Success); } var filePath = Path.Combine( NuGetEnvironment.GetFolderPath(NuGetFolderPath.Temp), "nuget-dg", "nugetSpec.dg"); Assert.True(File.Exists(filePath)); } }
private async Task RestorePackageSpecProjectsAsync( List <IDependencyGraphProject> projects, bool forceRestore, bool isSolutionAvailable, RestoreOperationSource restoreSource, IntervalTracker intervalTracker, CancellationToken token) { // Only continue if there are some build integrated type projects. if (!(projects.Any(project => project is BuildIntegratedNuGetProject))) { return; } if (_packageRestoreConsent.IsGranted) { if (!isSolutionAvailable) { var globalPackagesFolder = SettingsUtility.GetGlobalPackagesFolder(_settings); if (!Path.IsPathRooted(globalPackagesFolder)) { var message = string.Format( CultureInfo.CurrentCulture, Resources.RelativeGlobalPackagesFolder, globalPackagesFolder); await _logger.WriteLineAsync(VerbosityLevel.Quiet, message); // Cannot restore packages since globalPackagesFolder is a relative path // and the solution is not available return; } } DependencyGraphCacheContext cacheContext; DependencyGraphSpec originalDgSpec; DependencyGraphSpec dgSpec; IReadOnlyList <IAssetsLogMessage> additionalMessages; using (intervalTracker.Start(RestoreTelemetryEvent.SolutionDependencyGraphSpecCreation)) { // Cache p2ps discovered from DTE cacheContext = new DependencyGraphCacheContext(_logger, _settings); var pathContext = NuGetPathContext.Create(_settings); // Get full dg spec (originalDgSpec, additionalMessages) = await DependencyGraphRestoreUtility.GetSolutionRestoreSpecAndAdditionalMessages(_solutionManager, cacheContext); } using (intervalTracker.Start(RestoreTelemetryEvent.SolutionUpToDateCheck)) { // Run solution based up to date check. var projectsNeedingRestore = _solutionUpToDateChecker.PerformUpToDateCheck(originalDgSpec, _logger).AsList(); dgSpec = originalDgSpec; // Only use the optimization results if the restore is not `force`. // Still run the optimization check anyways to prep the cache. if (!forceRestore) { // Update the dg spec. dgSpec = originalDgSpec.WithoutRestores(); foreach (var uniqueProjectId in projectsNeedingRestore) { dgSpec.AddRestore(uniqueProjectId); } // recorded the number of up to date projects _upToDateProjectCount = originalDgSpec.Restore.Count - projectsNeedingRestore.Count; _noOpProjectsCount = _upToDateProjectCount; } } using (intervalTracker.Start(RestoreTelemetryEvent.PackageReferenceRestoreDuration)) { // Avoid restoring if all the projects are up to date, or the solution does not have build integrated projects. if (DependencyGraphRestoreUtility.IsRestoreRequired(dgSpec)) { // NOTE: During restore for build integrated projects, // We might show the dialog even if there are no packages to restore // When both currentStep and totalSteps are 0, we get a marquee on the dialog await _logger.RunWithProgressAsync( async (l, _, t) => { // Display the restore opt out message if it has not been shown yet await l.WriteHeaderAsync(); var sources = _sourceRepositoryProvider .GetRepositories() .ToList(); var providerCache = new RestoreCommandProvidersCache(); Action <SourceCacheContext> cacheModifier = (cache) => { }; var isRestoreOriginalAction = true; var restoreSummaries = await DependencyGraphRestoreUtility.RestoreAsync( _solutionManager, dgSpec, cacheContext, providerCache, cacheModifier, sources, _nuGetProjectContext.OperationId, forceRestore, isRestoreOriginalAction, additionalMessages, l, t); _packageCount += restoreSummaries.Select(summary => summary.InstallCount).Sum(); var isRestoreFailed = restoreSummaries.Any(summary => summary.Success == false); _noOpProjectsCount += restoreSummaries.Where(summary => summary.NoOpRestore == true).Count(); _solutionUpToDateChecker.SaveRestoreStatus(restoreSummaries); if (isRestoreFailed) { _status = NuGetOperationStatus.Failed; } else if (_noOpProjectsCount < restoreSummaries.Count) { _status = NuGetOperationStatus.Succeeded; } }, token); } } } else if (restoreSource == RestoreOperationSource.Explicit) { _logger.ShowError(Resources.PackageRefNotRestoredBecauseOfNoConsent); } }
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 // 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 (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); } }
private async Task RestorePackageSpecProjectsAsync( List <IDependencyGraphProject> projects, bool forceRestore, bool isSolutionAvailable, IReadOnlyList <PackageSpec> packageSpecs, CancellationToken token) { // Only continue if there are some build integrated type projects. if (!(projects.Any(project => project is BuildIntegratedNuGetProject) || packageSpecs.Any(project => IsProjectBuildIntegrated(project)))) { return; } if (IsConsentGranted(_settings)) { if (!isSolutionAvailable) { var globalPackagesFolder = SettingsUtility.GetGlobalPackagesFolder(_settings); if (!Path.IsPathRooted(globalPackagesFolder)) { await _logger.DoAsync((l, _) => { var message = string.Format( CultureInfo.CurrentCulture, Resources.RelativeGlobalPackagesFolder, globalPackagesFolder); l.WriteLine(VerbosityLevel.Quiet, message); }); // Cannot restore packages since globalPackagesFolder is a relative path // and the solution is not available return; } } // Cache p2ps discovered from DTE var cacheContext = new DependencyGraphCacheContext(_logger); var pathContext = NuGetPathContext.Create(_settings); // add deferred projects package spec in cacheContext packageSpecCache cacheContext.DeferredPackageSpecs.AddRange(packageSpecs); var isRestoreRequired = await DependencyGraphRestoreUtility.IsRestoreRequiredAsync( _solutionManager, forceRestore, pathContext, cacheContext, _dependencyGraphProjectCacheHash); // No-op all project closures are up to date and all packages exist on disk. if (isRestoreRequired) { // Save the project between operations. _dependencyGraphProjectCacheHash = cacheContext.SolutionSpecHash; // NOTE: During restore for build integrated projects, // We might show the dialog even if there are no packages to restore // When both currentStep and totalSteps are 0, we get a marquee on the dialog await _logger.RunWithProgressAsync( async (l, _, t) => { // Display the restore opt out message if it has not been shown yet await l.WriteHeaderAsync(); var sources = _sourceRepositoryProvider .GetRepositories() .ToList(); var providerCache = new RestoreCommandProvidersCache(); Action <SourceCacheContext> cacheModifier = (cache) => { }; var restoreSummaries = await DependencyGraphRestoreUtility.RestoreAsync( _solutionManager, cacheContext, providerCache, cacheModifier, sources, _settings, l, t); _packageCount += restoreSummaries.Select(summary => summary.InstallCount).Sum(); var isRestoreFailed = restoreSummaries.Any(summary => summary.Success == false); if (isRestoreFailed) { _status = NuGetOperationStatus.Failed; } }, token); } } }
public override async Task ExecuteCommandAsync() { if (DisableParallelProcessing) { HttpSourceResourceProvider.Throttle = SemaphoreSlimThrottle.CreateBinarySemaphore(); } CalculateEffectivePackageSaveMode(); var restoreSummaries = new List <RestoreSummary>(); if (!string.IsNullOrEmpty(SolutionDirectory)) { SolutionDirectory = Path.GetFullPath(SolutionDirectory); } var restoreInputs = await DetermineRestoreInputsAsync(); var hasPackagesConfigFiles = restoreInputs.PackagesConfigFiles.Count > 0; var hasProjectJsonOrPackageReferences = restoreInputs.RestoreV3Context.Inputs.Any(); if (!hasPackagesConfigFiles && !hasProjectJsonOrPackageReferences) { Console.LogMinimal(LocalizedResourceManager.GetString(restoreInputs.RestoringWithSolutionFile ? "SolutionRestoreCommandNoPackagesConfigOrProjectJson" : "ProjectRestoreCommandNoPackagesConfigOrProjectJson")); return; } // packages.config if (hasPackagesConfigFiles) { var v2RestoreResult = await PerformNuGetV2RestoreAsync(restoreInputs); restoreSummaries.Add(v2RestoreResult); if (!v2RestoreResult.Success) { v2RestoreResult .Errors .Where(l => l.Level == LogLevel.Warning) .ForEach(l => Console.LogWarning(l.FormatWithCode())); } } // project.json and PackageReference if (hasProjectJsonOrPackageReferences) { // Read the settings outside of parallel loops. ReadSettings(restoreInputs); // Check if we can restore based on the nuget.config settings CheckRequireConsent(); using (var cacheContext = new SourceCacheContext()) { cacheContext.NoCache = NoCache; cacheContext.DirectDownload = DirectDownload; var restoreContext = restoreInputs.RestoreV3Context; var providerCache = new RestoreCommandProvidersCache(); // Add restore args to the restore context restoreContext.CacheContext = cacheContext; restoreContext.DisableParallel = DisableParallelProcessing; restoreContext.AllowNoOp = !Force; // if force, no-op is not allowed restoreContext.ConfigFile = ConfigFile; restoreContext.MachineWideSettings = MachineWideSettings; restoreContext.Log = Console; restoreContext.CachingSourceProvider = GetSourceRepositoryProvider(); var packageSaveMode = EffectivePackageSaveMode; if (packageSaveMode != Packaging.PackageSaveMode.None) { restoreContext.PackageSaveMode = EffectivePackageSaveMode; } // Providers // Use the settings loaded above in ReadSettings(restoreInputs) if (restoreInputs.ProjectReferenceLookup.Restore.Count > 0) { // Remove input list, everything has been loaded already restoreContext.Inputs.Clear(); restoreContext.PreLoadedRequestProviders.Add(new DependencyGraphSpecRequestProvider( providerCache, restoreInputs.ProjectReferenceLookup)); } else { // Allow an external .dg file restoreContext.RequestProviders.Add(new DependencyGraphFileRequestProvider(providerCache)); } // Run restore var v3Summaries = await RestoreRunner.RunAsync(restoreContext); restoreSummaries.AddRange(v3Summaries); } } // Summaries RestoreSummary.Log(Console, restoreSummaries, logErrors: true); if (restoreSummaries.Any(x => !x.Success)) { throw new ExitCodeException(exitCode: 1); } }
public async Task RestoreRunner_RestoreWithRuntime() { // Arrange var sources = new List <PackageSource>(); var project1Json = @" { ""version"": ""1.0.0"", ""description"": """", ""authors"": [ ""author"" ], ""tags"": [ """" ], ""projectUrl"": """", ""licenseUrl"": """", ""frameworks"": { ""net45"": { } } }"; using (var workingDir = TestFileSystemUtility.CreateRandomTestFolder()) { var packagesDir = new DirectoryInfo(Path.Combine(workingDir, "globalPackages")); var packageSource = new DirectoryInfo(Path.Combine(workingDir, "packageSource")); var project1 = new DirectoryInfo(Path.Combine(workingDir, "projects", "project1")); packagesDir.Create(); packageSource.Create(); project1.Create(); sources.Add(new PackageSource(packageSource.FullName)); File.WriteAllText(Path.Combine(project1.FullName, "project.json"), project1Json); var specPath1 = Path.Combine(project1.FullName, "project.json"); var spec1 = JsonPackageSpecReader.GetPackageSpec(project1Json, "project1", specPath1); var logger = new TestLogger(); var lockPath1 = Path.Combine(project1.FullName, "project.lock.json"); var sourceRepos = sources.Select(source => Repository.Factory.GetCoreV3(source.Source)).ToList(); var providerCache = new RestoreCommandProvidersCache(); var restoreContext = new RestoreArgs() { CacheContext = new SourceCacheContext(), DisableParallel = true, GlobalPackagesFolder = packagesDir.FullName, Sources = new List <string>() { packageSource.FullName }, Inputs = new List <string>() { specPath1 }, Log = logger, CachingSourceProvider = new CachingSourceProvider(new TestPackageSourceProvider(sources)), RequestProviders = new List <IRestoreRequestProvider>() { new ProjectJsonRestoreRequestProvider(providerCache) } }; restoreContext.Runtimes.Add("linux-x86"); // Act var summaries = await RestoreRunner.Run(restoreContext); var success = summaries.All(s => s.Success); var lockFormat = new LockFileFormat(); var lockFile = lockFormat.Read(lockPath1); // Assert Assert.True(success, "Failed: " + string.Join(Environment.NewLine, logger.Messages)); Assert.True(lockFile.Targets.Any(graph => graph.RuntimeIdentifier == "linux-x86")); } }
private async Task RestorePackageSpecProjectsAsync( List <IDependencyGraphProject> projects, bool forceRestore, bool isSolutionAvailable, RestoreOperationSource restoreSource, CancellationToken token) { // Only continue if there are some build integrated type projects. if (!(projects.Any(project => project is BuildIntegratedNuGetProject))) { return; } if (_packageRestoreConsent.IsGranted) { if (!isSolutionAvailable) { var globalPackagesFolder = SettingsUtility.GetGlobalPackagesFolder(_settings); if (!Path.IsPathRooted(globalPackagesFolder)) { await _logger.DoAsync((l, _) => { var message = string.Format( CultureInfo.CurrentCulture, Resources.RelativeGlobalPackagesFolder, globalPackagesFolder); l.WriteLine(VerbosityLevel.Quiet, message); }); // Cannot restore packages since globalPackagesFolder is a relative path // and the solution is not available return; } } // Cache p2ps discovered from DTE var cacheContext = new DependencyGraphCacheContext(_logger, _settings); var pathContext = NuGetPathContext.Create(_settings); // Get full dg spec var dgSpec = await DependencyGraphRestoreUtility.GetSolutionRestoreSpec(_solutionManager, cacheContext); // Avoid restoring solutions with zero potential PackageReference projects. if (DependencyGraphRestoreUtility.IsRestoreRequired(dgSpec)) { // NOTE: During restore for build integrated projects, // We might show the dialog even if there are no packages to restore // When both currentStep and totalSteps are 0, we get a marquee on the dialog await _logger.RunWithProgressAsync( async (l, _, t) => { // Display the restore opt out message if it has not been shown yet await l.WriteHeaderAsync(); var sources = _sourceRepositoryProvider .GetRepositories() .ToList(); var providerCache = new RestoreCommandProvidersCache(); Action <SourceCacheContext> cacheModifier = (cache) => { }; var isRestoreOriginalAction = true; var restoreSummaries = await DependencyGraphRestoreUtility.RestoreAsync( _solutionManager, dgSpec, cacheContext, providerCache, cacheModifier, sources, _nuGetProjectContext.OperationId, forceRestore, isRestoreOriginalAction, l, t); _packageCount += restoreSummaries.Select(summary => summary.InstallCount).Sum(); var isRestoreFailed = restoreSummaries.Any(summary => summary.Success == false); _noOpProjectsCount = restoreSummaries.Where(summary => summary.NoOpRestore == true).Count(); if (isRestoreFailed) { _status = NuGetOperationStatus.Failed; } else if (_noOpProjectsCount < restoreSummaries.Count) { _status = NuGetOperationStatus.Succeeded; } }, token); } } else if (restoreSource == RestoreOperationSource.Explicit) { // Log an error when restore is disabled and user explicitly restore. await _logger.DoAsync((l, _) => { l.ShowError(Resources.PackageRefNotRestoredBecauseOfNoConsent); }); } }
async Task RestorePackagesAsync( IEnumerable <InteractivePackage> packages, SourceCacheContext cacheContext, CancellationToken cancellationToken) { var restoreContext = new RestoreArgs { CacheContext = cacheContext, Log = Logger, }; // NOTE: This path is typically empty. It could in theory contain nuget.config settings // files, but really we just use it to satisfy nuget API that requires paths, // even when they are never used. var rootPath = packageConfigDirectory; var globalPath = restoreContext.GetEffectiveGlobalPackagesFolder(rootPath, settings); var fallbackPaths = restoreContext.GetEffectiveFallbackPackageFolders(settings); var providerCache = new RestoreCommandProvidersCache(); var restoreProviders = providerCache.GetOrCreate( globalPath, fallbackPaths, SourceRepositories, cacheContext, Logger); // Set up a project spec similar to what you would see in a project.json. // This is sufficient for the dependency graph work done within RestoreCommand. // TODO: XF version pinning during restore? var targetFrameworkInformation = new TargetFrameworkInformation { FrameworkName = TargetFramework, Dependencies = packages.Select(ToLibraryDependency).ToList(), }; var projectSpec = new PackageSpec(new [] { targetFrameworkInformation }) { Name = project.Name, FilePath = rootPath, }; var restoreRequest = new RestoreRequest(projectSpec, restoreProviders, cacheContext, Logger); var restoreCommand = new RestoreCommand(restoreRequest); var result = await restoreCommand.ExecuteAsync(cancellationToken); if (!result.Success) { return; } project.ResetInstallationContext(); // As with installation, restore simply ensures that packages are present in the user's // global package cache. We reference them out of there just like .NET core projects do. // // All resolved packages, including the explicit inputs and their dependencies, are // available as LockFileLibrary instances. foreach (var library in result.LockFile.Libraries) { project.InstallationContext.AddInstalledPackage( GetInteractivePackageFromLibrary(library, project, packages)); } installedPackages = project.InstallationContext.InstalledPackages; UpdateInstalledPackages(); }
private async Task <bool> ExecuteAsync(Common.ILogger log) { if (RestoreGraphItems.Length < 1) { log.LogWarning(Strings.NoProjectsProvidedToTask); return(true); } // Set user agent and connection settings. ConfigureProtocol(); // Convert to the internal wrapper var wrappedItems = RestoreGraphItems.Select(MSBuildUtility.WrapMSBuildItem); //var graphLines = RestoreGraphItems; var providerCache = new RestoreCommandProvidersCache(); using (var cacheContext = new SourceCacheContext()) { cacheContext.NoCache = RestoreNoCache; cacheContext.IgnoreFailedSources = RestoreIgnoreFailedSources; // Pre-loaded request provider containing the graph file var providers = new List <IPreLoadedRestoreRequestProvider>(); var dgFile = MSBuildRestoreUtility.GetDependencySpec(wrappedItems); if (dgFile.Restore.Count < 1) { // Restore will fail if given no inputs, but here we should skip it and provide a friendly message. log.LogMinimal(Strings.NoProjectsToRestore); return(true); } // Add all child projects if (RestoreRecursive) { BuildTasksUtility.AddAllProjectsForRestore(dgFile); } providers.Add(new DependencyGraphSpecRequestProvider(providerCache, dgFile)); var defaultSettings = Settings.LoadDefaultSettings(root: null, configFileName: null, machineWideSettings: null); var sourceProvider = new CachingSourceProvider(new PackageSourceProvider(defaultSettings)); var restoreContext = new RestoreArgs() { CacheContext = cacheContext, LockFileVersion = LockFileFormat.Version, DisableParallel = RestoreDisableParallel, Log = log, MachineWideSettings = new XPlatMachineWideSetting(), PreLoadedRequestProviders = providers, CachingSourceProvider = sourceProvider, AllowNoOp = !RestoreForce, HideWarningsAndErrors = HideWarningsAndErrors }; if (restoreContext.DisableParallel) { HttpSourceResourceProvider.Throttle = SemaphoreSlimThrottle.CreateBinarySemaphore(); } _cts.Token.ThrowIfCancellationRequested(); var restoreSummaries = await RestoreRunner.RunAsync(restoreContext, _cts.Token); // Summary RestoreSummary.Log(log, restoreSummaries); return(restoreSummaries.All(x => x.Success)); } }
public async Task BuildIntegratedNuGetProject_IsRestoreNotRequiredWithFloatingVersion() { // Arrange var projectName = "testproj"; using (var packagesFolder = TestDirectory.Create()) using (var rootFolder = TestDirectory.Create()) { var projectFolder = new DirectoryInfo(Path.Combine(rootFolder, projectName)); projectFolder.Create(); var projectConfig = new FileInfo(Path.Combine(projectFolder.FullName, "project.json")); var msbuildProjectPath = new FileInfo(Path.Combine(projectFolder.FullName, $"{projectName}.csproj")); BuildIntegrationTestUtility.CreateConfigJson(projectConfig.FullName); var json = JObject.Parse(File.ReadAllText(projectConfig.FullName)); json.Add("dependencies", JObject.Parse("{ \"nuget.versioning\": \"1.0.*\" }")); using (var writer = new StreamWriter(projectConfig.FullName)) { writer.Write(json.ToString()); } var sources = new List <SourceRepository> { Repository.Factory.GetVisualStudio("https://www.nuget.org/api/v2/") }; var projectTargetFramework = NuGetFramework.Parse("uap10.0"); var msBuildNuGetProjectSystem = new TestMSBuildNuGetProjectSystem(projectTargetFramework, new TestNuGetProjectContext()); var project = new ProjectJsonNuGetProject(projectConfig.FullName, msbuildProjectPath.FullName); var testLogger = new TestLogger(); var settings = new Settings(rootFolder); settings.SetValue(SettingsUtility.ConfigSection, "globalPackagesFolder", packagesFolder); var solutionManager = new TestSolutionManager(false); solutionManager.NuGetProjects.Add(project); var restoreContext = new DependencyGraphCacheContext(testLogger, settings); var providersCache = new RestoreCommandProvidersCache(); await DependencyGraphRestoreUtility.RestoreAsync( solutionManager, await DependencyGraphRestoreUtility.GetSolutionRestoreSpec(solutionManager, restoreContext), restoreContext, providersCache, (c) => { }, sources, Guid.Empty, false, true, testLogger, CancellationToken.None); var noOpRestoreSummaries = await DependencyGraphRestoreUtility.RestoreAsync( solutionManager, await DependencyGraphRestoreUtility.GetSolutionRestoreSpec(solutionManager, restoreContext), restoreContext, providersCache, (c) => { }, sources, Guid.Empty, false, true, testLogger, CancellationToken.None); foreach (var restoreSummary in noOpRestoreSummaries) { Assert.True(restoreSummary.NoOpRestore); } } }
public async Task InstallPackageFromAnotherProcessVerifyCacheIsClearedAsync() { // Arrange var logger = new TestLogger(); using (var cacheContext = new SourceCacheContext()) using (var pathContext = new SimpleTestPathContext()) { var tfi = new List <TargetFrameworkInformation> { new TargetFrameworkInformation() { FrameworkName = NuGetFramework.Parse("net462") } }; var spec = NETCoreRestoreTestUtility.GetProject(projectName: "projectA", framework: "net46"); spec.Dependencies.Add(new LibraryDependency() { LibraryRange = new LibraryRange("a", VersionRange.Parse("1.0.0"), LibraryDependencyTarget.Package) }); var project = NETCoreRestoreTestUtility.CreateProjectsFromSpecs(pathContext, spec).Single(); var packageA = new SimpleTestPackageContext("a"); await SimpleTestPackageUtility.CreatePackagesAsync(pathContext.PackageSource, packageA); // Create dg file var dgFile = new DependencyGraphSpec(); dgFile.AddProject(spec); dgFile.AddRestore(spec.RestoreMetadata.ProjectUniqueName); dgFile.Save(Path.Combine(pathContext.WorkingDirectory, "out.dg")); var providerCache = new RestoreCommandProvidersCache(); var sources = new List <string>() { pathContext.PackageSource }; var restoreContext = new RestoreArgs() { CacheContext = cacheContext, DisableParallel = true, GlobalPackagesFolder = pathContext.UserPackagesFolder, Sources = sources, Log = logger, CachingSourceProvider = new CachingSourceProvider(new TestPackageSourceProvider(new List <PackageSource>() { new PackageSource(pathContext.PackageSource) })), PreLoadedRequestProviders = new List <IPreLoadedRestoreRequestProvider>() { new DependencyGraphSpecRequestProvider(providerCache, dgFile) } }; var request = (await RestoreRunner.GetRequests(restoreContext)).Single(); var providers = providerCache.GetOrCreate(pathContext.UserPackagesFolder, sources, new List <SourceRepository>(), cacheContext, logger); var command = new RestoreCommand(request.Request); // Add to cache before install on all providers var globalPackages = providers.GlobalPackages; var packages = globalPackages.FindPackagesById("a"); packages.Should().BeEmpty("has not been installed yet"); foreach (var local in providers.LocalProviders) { await local.GetDependenciesAsync(new LibraryIdentity("a", NuGetVersion.Parse("1.0.0"), LibraryType.Package), NuGetFramework.Parse("net46"), cacheContext, logger, CancellationToken.None); } // Install the package without updating the cache await SimpleTestPackageUtility.CreateFolderFeedV3Async(pathContext.UserPackagesFolder, PackageSaveMode.Defaultv3, packageA); // Run restore using an incorrect cache var result = await command.ExecuteAsync(); // Verify a is in the output assets file result.Success.Should().BeTrue(); result.LockFile.GetLibrary("a", new NuGetVersion(1, 0, 0)).Should().NotBeNull(); } }
public async Task BuildIntegratedNuGetProject_IsRestoreRequiredChangedSha512() { // Arrange var projectName = "testproj"; using (var solutionManager = new TestSolutionManager(false)) { var projectFolder = new DirectoryInfo(Path.Combine(solutionManager.SolutionDirectory, projectName)); projectFolder.Create(); var projectConfig = new FileInfo(Path.Combine(projectFolder.FullName, "project.json")); var msbuildProjectPath = new FileInfo(Path.Combine(projectFolder.FullName, $"{projectName}.csproj")); BuildIntegrationTestUtility.CreateConfigJson(projectConfig.FullName); var json = JObject.Parse(File.ReadAllText(projectConfig.FullName)); JsonConfigUtility.AddDependency(json, new PackageDependency("nuget.versioning", VersionRange.Parse("1.0.7"))); using (var writer = new StreamWriter(projectConfig.FullName)) { writer.Write(json.ToString()); } var sources = new List <SourceRepository> { }; var testLogger = new TestLogger(); var settings = Settings.LoadSpecificSettings(solutionManager.SolutionDirectory, "NuGet.Config"); var project = new ProjectJsonNuGetProject(projectConfig.FullName, msbuildProjectPath.FullName); solutionManager.NuGetProjects.Add(project); var restoreContext = new DependencyGraphCacheContext(testLogger, settings); var providersCache = new RestoreCommandProvidersCache(); var dgSpec1 = await DependencyGraphRestoreUtility.GetSolutionRestoreSpec(solutionManager, restoreContext); await DependencyGraphRestoreUtility.RestoreAsync( solutionManager, dgSpec1, restoreContext, providersCache, (c) => { }, sources, Guid.Empty, false, true, testLogger, CancellationToken.None); var dgSpec2 = await DependencyGraphRestoreUtility.GetSolutionRestoreSpec(solutionManager, restoreContext); var noOpRestoreSummaries = await DependencyGraphRestoreUtility.RestoreAsync( solutionManager, dgSpec2, restoreContext, providersCache, (c) => { }, sources, Guid.Empty, false, true, testLogger, CancellationToken.None); foreach (var restoreSummary in noOpRestoreSummaries) { Assert.True(restoreSummary.NoOpRestore); } var resolver = new VersionFolderPathResolver(solutionManager.GlobalPackagesFolder); var hashPath = resolver.GetHashPath("nuget.versioning", NuGetVersion.Parse("1.0.7")); File.Delete(hashPath); var restoreSummaries = await DependencyGraphRestoreUtility.RestoreAsync( solutionManager, await DependencyGraphRestoreUtility.GetSolutionRestoreSpec(solutionManager, restoreContext), restoreContext, new RestoreCommandProvidersCache(), (c) => { }, sources, Guid.Empty, false, true, testLogger, CancellationToken.None); foreach (var restoreSummary in restoreSummaries) { Assert.True(restoreSummary.Success); Assert.False(restoreSummary.NoOpRestore); } var filePath = Path.Combine( NuGetEnvironment.GetFolderPath(NuGetFolderPath.Temp), "nuget-dg", "nugetSpec.dg"); Assert.True(File.Exists(filePath)); } }
public WorkaroundProjectJsonRestoreRequestProvider(RestoreCommandProvidersCache providerCache) : base(providerCache) { _providerCache = providerCache; }
public async Task RestoreRunner_BasicRestoreWithConfigFile() { // Arrange var sources = new List <PackageSource>(); var project1Json = @" { ""version"": ""1.0.0"", ""description"": """", ""authors"": [ ""author"" ], ""tags"": [ """" ], ""projectUrl"": """", ""licenseUrl"": """", ""frameworks"": { ""net45"": { } } }"; var configFile = @"<?xml version=""1.0"" encoding=""utf-8""?> <configuration> <packageSources> <add key=""nuget.org"" value=""{0}"" /> </packageSources> </configuration> "; using (var workingDir = TestFileSystemUtility.CreateRandomTestFolder()) { var packagesDir = new DirectoryInfo(Path.Combine(workingDir, "globalPackages")); var packageSource = new DirectoryInfo(Path.Combine(workingDir, "packageSource")); var project1 = new DirectoryInfo(Path.Combine(workingDir, "projects", "project1")); packagesDir.Create(); packageSource.Create(); project1.Create(); File.WriteAllText(Path.Combine(project1.FullName, "project.json"), project1Json); File.WriteAllText(Path.Combine(workingDir, "NuGet.Config"), String.Format(configFile, packageSource.FullName)); var specPath1 = Path.Combine(project1.FullName, "project.json"); var spec1 = JsonPackageSpecReader.GetPackageSpec(project1Json, "project1", specPath1); var configPath = Path.Combine(workingDir, "NuGet.Config"); var logger = new TestLogger(); var lockPath = Path.Combine(project1.FullName, "project.lock.json"); var providerCache = new RestoreCommandProvidersCache(); var restoreContext = new RestoreArgs() { CacheContext = new SourceCacheContext(), DisableParallel = true, GlobalPackagesFolder = packagesDir.FullName, ConfigFile = configPath, Inputs = new List <string>() { specPath1 }, Log = logger, CachingSourceProvider = new CachingSourceProvider(new TestPackageSourceProvider(new List <PackageSource>())), RequestProviders = new List <IRestoreRequestProvider>() { new ProjectJsonRestoreRequestProvider(providerCache) } }; // Act var summaries = await RestoreRunner.Run(restoreContext); var summary = summaries.Single(); // Assert Assert.True(summary.Success, "Failed: " + string.Join(Environment.NewLine, logger.Messages)); Assert.Equal(1, summary.FeedsUsed.Count); Assert.True(File.Exists(lockPath), lockPath); } }
public async Task BuildIntegratedNuGetProject_IsRestoreRequiredMissingPackage() { // Arrange var projectName = "testproj"; using (var packagesFolder = TestDirectory.Create()) using (var rootFolder = TestDirectory.Create()) { var projectFolder = new DirectoryInfo(Path.Combine(rootFolder, projectName)); projectFolder.Create(); var projectConfig = new FileInfo(Path.Combine(projectFolder.FullName, "project.json")); var msbuildProjectPath = new FileInfo(Path.Combine(projectFolder.FullName, $"{projectName}.csproj")); BuildIntegrationTestUtility.CreateConfigJson(projectConfig.FullName); var json = JObject.Parse(File.ReadAllText(projectConfig.FullName)); JsonConfigUtility.AddDependency(json, new NuGet.Packaging.Core.PackageDependency("nuget.versioning", VersionRange.Parse("1.0.7"))); using (var writer = new StreamWriter(projectConfig.FullName)) { writer.Write(json.ToString()); } var sources = new List <SourceRepository> { }; var projectTargetFramework = NuGetFramework.Parse("uap10.0"); var msBuildNuGetProjectSystem = new TestMSBuildNuGetProjectSystem(projectTargetFramework, new TestNuGetProjectContext()); var project = new ProjectJsonNuGetProject(projectConfig.FullName, msbuildProjectPath.FullName); var solutionManager = new TestSolutionManager(false); solutionManager.NuGetProjects.Add(project); var testLogger = new TestLogger(); var settings = new Settings(rootFolder); settings.SetValue(SettingsUtility.ConfigSection, "globalPackagesFolder", packagesFolder); var restoreContext = new DependencyGraphCacheContext(testLogger, settings); var providersCache = new RestoreCommandProvidersCache(); await DependencyGraphRestoreUtility.RestoreAsync( solutionManager, restoreContext, providersCache, (c) => { }, sources, Guid.Empty, false, await DependencyGraphRestoreUtility.GetSolutionRestoreSpec(solutionManager, restoreContext), testLogger, CancellationToken.None); var noOpRestoreSummaries = await DependencyGraphRestoreUtility.RestoreAsync( solutionManager, restoreContext, providersCache, (c) => { }, sources, Guid.Empty, false, await DependencyGraphRestoreUtility.GetSolutionRestoreSpec(solutionManager, restoreContext), testLogger, CancellationToken.None); foreach (var restoreSummary in noOpRestoreSummaries) { Assert.True(restoreSummary.NoOpRestore); } var resolver = new VersionFolderPathResolver(packagesFolder); var pathToDelete = resolver.GetInstallPath("nuget.versioning", NuGetVersion.Parse("1.0.7")); TestFileSystemUtility.DeleteRandomTestFolder(pathToDelete); var restoreSummaries = await DependencyGraphRestoreUtility.RestoreAsync( solutionManager, restoreContext, new RestoreCommandProvidersCache(), (c) => { }, sources, Guid.Empty, false, await DependencyGraphRestoreUtility.GetSolutionRestoreSpec(solutionManager, restoreContext), testLogger, CancellationToken.None); foreach (var restoreSummary in restoreSummaries) { Assert.True(restoreSummary.Success); Assert.False(restoreSummary.NoOpRestore); } } }
private async Task <bool> ExecuteAsync(Common.ILogger log) { if (RestoreGraphItems.Length < 1 && !HideWarningsAndErrors) { log.LogWarning(Strings.NoProjectsProvidedToTask); return(true); } // Set user agent and connection settings. ConfigureProtocol(); // Convert to the internal wrapper var wrappedItems = RestoreGraphItems.Select(MSBuildUtility.WrapMSBuildItem); //var graphLines = RestoreGraphItems; var providerCache = new RestoreCommandProvidersCache(); using (var cacheContext = new SourceCacheContext()) { cacheContext.NoCache = RestoreNoCache; cacheContext.IgnoreFailedSources = RestoreIgnoreFailedSources; // Pre-loaded request provider containing the graph file var providers = new List <IPreLoadedRestoreRequestProvider>(); var dgFile = MSBuildRestoreUtility.GetDependencySpec(wrappedItems); if (dgFile.Restore.Count < 1) { // Restore will fail if given no inputs, but here we should skip it and provide a friendly message. log.LogMinimal(Strings.NoProjectsToRestore); return(true); } // Add all child projects if (RestoreRecursive) { BuildTasksUtility.AddAllProjectsForRestore(dgFile); } providers.Add(new DependencyGraphSpecRequestProvider(providerCache, dgFile)); var restoreContext = new RestoreArgs() { CacheContext = cacheContext, LockFileVersion = LockFileFormat.Version, DisableParallel = RestoreDisableParallel, Log = log, MachineWideSettings = new XPlatMachineWideSetting(), PreLoadedRequestProviders = providers, AllowNoOp = !RestoreForce, HideWarningsAndErrors = HideWarningsAndErrors, RestoreForceEvaluate = RestoreForceEvaluate }; // '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. if (Environment.ProcessorCount == 1) { restoreContext.DisableParallel = true; } if (restoreContext.DisableParallel) { HttpSourceResourceProvider.Throttle = SemaphoreSlimThrottle.CreateBinarySemaphore(); } DefaultCredentialServiceUtility.SetupDefaultCredentialService(log, !Interactive); _cts.Token.ThrowIfCancellationRequested(); var restoreSummaries = await RestoreRunner.RunAsync(restoreContext, _cts.Token); // Summary RestoreSummary.Log(log, restoreSummaries); return(restoreSummaries.All(x => x.Success)); } }
public static void Register( CommandLineApplication cmdApp, CommandOutputLogger log) { cmdApp.Command("restore", (Action<CommandLineApplication>)(restore => { restore.Description = "Restores packages for a project and writes a lock file."; restore.HelpOption(XPlatUtility.HelpOption); var sources = restore.Option( "-s|--source <source>", "Specifies a NuGet package source to use during the restore.", CommandOptionType.MultipleValue); var packagesDirectory = restore.Option( "--packages <packagesDirectory>", "Directory to install packages in.", CommandOptionType.SingleValue); var disableParallel = restore.Option( "--disable-parallel", "Disables restoring multiple projects in parallel.", CommandOptionType.NoValue); var fallBack = restore.Option( "-f|--fallbacksource <FEED>", "A list of packages sources to use as a fallback.", CommandOptionType.MultipleValue); var runtime = restore.Option( "--runtime <RID>", "List of runtime identifiers to restore for.", CommandOptionType.MultipleValue); var configFile = restore.Option( "--configfile <file>", "The NuGet configuration file to use.", CommandOptionType.SingleValue); var noCache = restore.Option( "--no-cache", "Do not cache packages and http requests.", CommandOptionType.NoValue); var verbosity = restore.Option( XPlatUtility.VerbosityOption, "The verbosity of logging to use. Allowed values: Debug, Verbose, Information, Minimal, Warning, Error.", CommandOptionType.SingleValue); var argRoot = restore.Argument( "[root]", "List of projects and project folders to restore. Each value can be: a path to a project.json or global.json file, or a folder to recursively search for project.json files.", multipleValues: true); restore.OnExecute(async () => { var logLevel = XPlatUtility.GetLogLevel(verbosity); log.SetLogLevel(logLevel); using (var cacheContext = new SourceCacheContext()) { cacheContext.NoCache = noCache.HasValue(); var providerCache = new RestoreCommandProvidersCache(); // Ordered request providers var providers = new List<IRestoreRequestProvider>(); providers.Add(new MSBuildP2PRestoreRequestProvider(providerCache)); providers.Add(new ProjectJsonRestoreRequestProvider(providerCache)); var restoreContext = new RestoreArgs() { CacheContext = cacheContext, LockFileVersion = LockFileFormat.Version, ConfigFileName = configFile.HasValue() ? configFile.Value() : null, DisableParallel = true, GlobalPackagesFolder = packagesDirectory.HasValue() ? packagesDirectory.Value() : null, Inputs = new List<string>(argRoot.Values), Log = log, MachineWideSettings = new CommandLineXPlatMachineWideSetting(), RequestProviders = providers, Sources = sources.Values, FallbackSources = fallBack.Values, CachingSourceProvider = _sourceProvider }; restoreContext.Runtimes.UnionWith(runtime.Values); var restoreSummaries = await RestoreRunner.Run(restoreContext); // Summary RestoreSummary.Log(log, restoreSummaries, logLevel < LogLevel.Minimal); return restoreSummaries.All(x => x.Success) ? 0 : 1; } }); })); }
public async Task RestoreRunner_RestoreWithExternalFile() { // Arrange var sources = new List <PackageSource>(); var project1Json = @" { ""version"": ""1.0.0"", ""description"": """", ""authors"": [ ""author"" ], ""tags"": [ """" ], ""projectUrl"": """", ""licenseUrl"": """", ""frameworks"": { ""net45"": { } } }"; var project2Json = @" { ""version"": ""1.0.0"", ""description"": """", ""authors"": [ ""author"" ], ""tags"": [ """" ], ""projectUrl"": """", ""licenseUrl"": """", ""frameworks"": { ""net45"": { } } }"; using (var workingDir = TestFileSystemUtility.CreateRandomTestFolder()) { var packagesDir = new DirectoryInfo(Path.Combine(workingDir, "globalPackages")); var packageSource = new DirectoryInfo(Path.Combine(workingDir, "packageSource")); var project1 = new DirectoryInfo(Path.Combine(workingDir, "projects", "project1")); var project2 = new DirectoryInfo(Path.Combine(workingDir, "projects", "project2")); packagesDir.Create(); packageSource.Create(); project1.Create(); project2.Create(); sources.Add(new PackageSource(packageSource.FullName)); File.WriteAllText(Path.Combine(project1.FullName, "project.json"), project1Json); File.WriteAllText(Path.Combine(project2.FullName, "project.json"), project1Json); var specPath1 = Path.Combine(project1.FullName, "project.json"); var spec1 = JsonPackageSpecReader.GetPackageSpec(project1Json, "project1", specPath1); var specPath2 = Path.Combine(project2.FullName, "project.json"); var spec2 = JsonPackageSpecReader.GetPackageSpec(project2Json, "project2", specPath2); var projPath1 = Path.Combine(project1.FullName, "project1.csproj"); var projPath2 = Path.Combine(project2.FullName, "project2.xproj"); File.WriteAllText(projPath1, string.Empty); File.WriteAllText(projPath2, string.Empty); var logger = new TestLogger(); var lockPath1 = Path.Combine(project1.FullName, "project.lock.json"); var lockPath2 = Path.Combine(project2.FullName, "project.lock.json"); var dgPath = Path.Combine(workingDir, "external.dg"); var dgContent = new StringBuilder(); dgContent.AppendLine($"#:{projPath1}"); dgContent.AppendLine($"{projPath1}|{projPath2}"); dgContent.AppendLine($"#:{projPath2}"); File.WriteAllText(dgPath, dgContent.ToString()); var sourceRepos = sources.Select(source => Repository.Factory.GetCoreV3(source.Source)).ToList(); var providerCache = new RestoreCommandProvidersCache(); var restoreContext = new RestoreArgs() { CacheContext = new SourceCacheContext(), DisableParallel = true, GlobalPackagesFolder = packagesDir.FullName, Sources = new List <string>() { packageSource.FullName }, Inputs = new List <string>() { dgPath }, Log = logger, CachingSourceProvider = new CachingSourceProvider(new TestPackageSourceProvider(sources)), RequestProviders = new List <IRestoreRequestProvider>() { new MSBuildP2PRestoreRequestProvider(providerCache), new ProjectJsonRestoreRequestProvider(providerCache) } }; // Act var summaries = await RestoreRunner.Run(restoreContext); var success = summaries.All(s => s.Success); var lockFormat = new LockFileFormat(); var lockFile1 = lockFormat.Read(lockPath1); var project2Lib = lockFile1.Libraries.First(); // Assert Assert.True(success, "Failed: " + string.Join(Environment.NewLine, logger.Messages)); Assert.True(File.Exists(lockPath1), lockPath1); Assert.True(File.Exists(lockPath2), lockPath2); Assert.Equal("project2", project2Lib.Name); } }