public async Task DependencyGraphRestoreUtility_NoopRestoreTest()
        {
            // Arrange
            var projectName = "testproj";
            var logger      = new TestLogger();

            using (var rootFolder = TestDirectory.Create())
            {
                var projectFolder = new DirectoryInfo(Path.Combine(rootFolder, projectName));
                projectFolder.Create();
                var msbuildProjectPath = new FileInfo(Path.Combine(projectFolder.FullName, $"{projectName}.csproj"));

                var sources = new[]
                {
                    Repository.Factory.GetVisualStudio(new PackageSource("https://www.nuget.org/api/v2/"))
                };

                var targetFramework = NuGetFramework.Parse("net46");

                var msBuildNuGetProjectSystem = new TestMSBuildNuGetProjectSystem(targetFramework, new TestNuGetProjectContext());
                var project = new TestMSBuildNuGetProject(msBuildNuGetProjectSystem, rootFolder, projectFolder.FullName);

                var effectiveGlobalPackagesFolder = SettingsUtility.GetGlobalPackagesFolder(NullSettings.Instance);

                var restoreContext = new DependencyGraphCacheContext(logger, NullSettings.Instance);

                var projects = new List <IDependencyGraphProject>()
                {
                    project
                };

                using (var solutionManager = new TestSolutionManager())
                {
                    solutionManager.NuGetProjects.Add(project);

                    // Act
                    await DependencyGraphRestoreUtility.RestoreAsync(
                        solutionManager,
                        await DependencyGraphRestoreUtility.GetSolutionRestoreSpec(solutionManager, restoreContext),
                        restoreContext,
                        new RestoreCommandProvidersCache(),
                        (c) => { },
                        sources,
                        Guid.Empty,
                        false,
                        true,
                        logger,
                        CancellationToken.None);

                    // Assert
                    Assert.Equal(0, logger.Errors);
                    Assert.Equal(0, logger.Warnings);
                }
            }
        }
        public async Task GetPackageSpecsAsync_PackageSpecExistsInCache_CachedPackageSpecReturned()
        {
            CreateNuGetProject("MyProject", @"d:\projects\MyProject\MyProject.csproj");
            var cachedSpec = new PackageSpec();

            dependencyGraphCacheContext = new DependencyGraphCacheContext();
            dependencyGraphCacheContext.PackageSpecCache.Add(dotNetProject.FileName.ToString(), cachedSpec);

            PackageSpec spec = await GetPackageSpecsAsync(dependencyGraphCacheContext);

            Assert.AreSame(cachedSpec, spec);
        }
        public async Task GetPackageSpecsAsync_WithPackageReference_Succeeds()
        {
            // Arrange
            using (var randomTestFolder = TestDirectory.Create())
            {
                var framework = NuGetFramework.Parse("netstandard13");

                var projectAdapter = CreateProjectAdapter(randomTestFolder);

                var projectServices = new TestProjectSystemServices();
                projectServices.SetupInstalledPackages(
                    framework,
                    new LibraryDependency
                {
                    LibraryRange = new LibraryRange(
                        "packageA",
                        VersionRange.Parse("1.*"),
                        LibraryDependencyTarget.Package)
                });

                var testProject = new LegacyPackageReferenceProject(
                    projectAdapter,
                    Guid.NewGuid().ToString(),
                    projectServices,
                    _threadingService);

                var testDependencyGraphCacheContext = new DependencyGraphCacheContext();

                await _threadingService.JoinableTaskFactory.SwitchToMainThreadAsync();

                // Act
                var packageSpecs = await testProject.GetPackageSpecsAsync(testDependencyGraphCacheContext);

                // Assert
                Assert.NotNull(packageSpecs);

                var actualRestoreSpec = packageSpecs.Single();
                SpecValidationUtility.ValidateProjectSpec(actualRestoreSpec);
                //No top level dependencies
                Assert.Equal(0, actualRestoreSpec.Dependencies.Count);

                var actualDependency = actualRestoreSpec.TargetFrameworks.SingleOrDefault().Dependencies.Single();
                Assert.NotNull(actualDependency);
                Assert.Equal("packageA", actualDependency.LibraryRange.Name);
                Assert.Equal(VersionRange.Parse("1.*"), actualDependency.LibraryRange.VersionRange);

                // Verify
                Mock.Get(projectServices.ReferencesReader)
                .Verify(
                    x => x.GetPackageReferencesAsync(framework, CancellationToken.None),
                    Times.AtLeastOnce);
            }
        }
        public async Task BuildIntegratedRestoreUtility_RestoreProjectNameProjectJson()
        {
            // Arrange
            var projectName = "testproj";

            using (var rootFolder = TestDirectory.Create())
            {
                var projectFolder = new DirectoryInfo(Path.Combine(rootFolder, projectName));
                projectFolder.Create();
                var projectConfig      = new FileInfo(Path.Combine(projectFolder.FullName, "testproj.project.json"));
                var msbuildProjectPath = new FileInfo(Path.Combine(projectFolder.FullName, $"{projectName}.csproj"));

                BuildIntegrationTestUtility.CreateConfigJson(projectConfig.FullName);

                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);

                using (var solutionManager = new TestSolutionManager())
                {
                    solutionManager.NuGetProjects.Add(project);

                    var testLogger = new TestLogger();

                    var restoreContext = new DependencyGraphCacheContext(testLogger, NullSettings.Instance);

                    // Act
                    await DependencyGraphRestoreUtility.RestoreAsync(
                        solutionManager,
                        await DependencyGraphRestoreUtility.GetSolutionRestoreSpec(solutionManager, restoreContext),
                        restoreContext,
                        new RestoreCommandProvidersCache(),
                        (c) => { },
                        sources,
                        Guid.Empty,
                        false,
                        true,
                        testLogger,
                        CancellationToken.None);

                    // Assert
                    Assert.True(File.Exists(Path.Combine(projectFolder.FullName, "testproj.project.lock.json")));
                    Assert.True(testLogger.Errors == 0);
                    Assert.False(File.Exists(Path.Combine(projectFolder.FullName, "project.lock.json")));
                }
            }
        }
        public async Task GetPackageSpecsAsync_WithPackageTargetFallback_Succeeds()
        {
            // Arrange
            using (var testDirectory = TestDirectory.Create())
            {
                var projectAdapter = CreateProjectAdapter(testDirectory);
                Mock.Get(projectAdapter)
                .SetupGet(x => x.PackageTargetFallback)
                .Returns("portable-net45+win8;dnxcore50");

                var testProject = new LegacyPackageReferenceProject(
                    projectAdapter,
                    Guid.NewGuid().ToString(),
                    new TestProjectSystemServices(),
                    _threadingService);

                var testDependencyGraphCacheContext = new DependencyGraphCacheContext();

                await _threadingService.JoinableTaskFactory.SwitchToMainThreadAsync();

                // Act
                var packageSpecs = await testProject.GetPackageSpecsAsync(testDependencyGraphCacheContext);

                // Assert
                Assert.NotNull(packageSpecs);

                var actualRestoreSpec = packageSpecs.Single();
                SpecValidationUtility.ValidateProjectSpec(actualRestoreSpec);

                var actualTfi = actualRestoreSpec.TargetFrameworks.First();
                Assert.NotNull(actualTfi);
                Assert.Equal(
                    new NuGetFramework[]
                {
                    NuGetFramework.Parse("portable-net45+win8"),
                    NuGetFramework.Parse("dnxcore50")
                },
                    actualTfi.Imports);
                Assert.IsType <FallbackFramework>(actualTfi.FrameworkName);
                Assert.Equal(
                    new NuGetFramework[]
                {
                    NuGetFramework.Parse("portable-net45+win8"),
                    NuGetFramework.Parse("dnxcore50")
                },
                    ((FallbackFramework)actualTfi.FrameworkName).Fallback);

                // Verify
                Mock.Get(projectAdapter)
                .Verify(x => x.PackageTargetFallback, Times.AtLeastOnce);
            }
        }
        public async Task GetPackageSpecsAsync_ReadLockFileSettings(
            string restorePackagesWithLockFile,
            string lockFilePath,
            bool restoreLockedMode)
        {
            // Arrange
            using (var testDirectory = TestDirectory.Create())
            {
                var projectAdapter = CreateProjectAdapter(testDirectory);
                Mock.Get(projectAdapter)
                .Setup(x => x.GetRestorePackagesWithLockFileAsync())
                .ReturnsAsync(restorePackagesWithLockFile);

                Mock.Get(projectAdapter)
                .Setup(x => x.GetNuGetLockFilePathAsync())
                .ReturnsAsync(lockFilePath);

                Mock.Get(projectAdapter)
                .Setup(x => x.IsRestoreLockedAsync())
                .ReturnsAsync(restoreLockedMode);

                var projectServices = new TestProjectSystemServices();

                var testProject = new LegacyPackageReferenceProject(
                    projectAdapter,
                    Guid.NewGuid().ToString(),
                    projectServices,
                    _threadingService);

                var settings = NullSettings.Instance;
                var testDependencyGraphCacheContext = new DependencyGraphCacheContext(NullLogger.Instance, settings);

                await _threadingService.JoinableTaskFactory.SwitchToMainThreadAsync();

                // Act
                var packageSpecs = await testProject.GetPackageSpecsAsync(testDependencyGraphCacheContext);

                // Assert
                Assert.NotNull(packageSpecs);
                var actualRestoreSpec = packageSpecs.Single();
                SpecValidationUtility.ValidateProjectSpec(actualRestoreSpec);

                // Assert restorePackagesWithLockFile
                Assert.Equal(restorePackagesWithLockFile, actualRestoreSpec.RestoreMetadata.RestoreLockProperties.RestorePackagesWithLockFile);

                // assert lockFilePath
                Assert.Equal(lockFilePath, actualRestoreSpec.RestoreMetadata.RestoreLockProperties.NuGetLockFilePath);

                // assert restoreLockedMode
                Assert.Equal(restoreLockedMode, actualRestoreSpec.RestoreMetadata.RestoreLockProperties.RestoreLockedMode);
            }
        }
        public async Task BuildIntegratedNuGetProject_GetPackageSpec_UAPWithImports()
        {
            // Arrange

            var configJson = @"
                {
                    ""dependencies"": {
                    },
                    ""frameworks"": {
                        ""uap10.0"": {
                            ""imports"": ""netstandard1.3"",
                            ""warn"": false
                        }
                    }
                }";

            using (var randomProjectFolderPath = TestDirectory.Create())
            {
                var projectJsonPath = Path.Combine(randomProjectFolderPath, "project.json");
                File.WriteAllText(projectJsonPath, configJson);

                var FallbackTargetFramework   = NuGetFramework.Parse("netstandard1.3");
                var projectTargetFramework    = NuGetFramework.Parse("uap10.0");
                var testNuGetProjectContext   = new TestNuGetProjectContext();
                var msBuildNuGetProjectSystem = new TestMSBuildNuGetProjectSystem(projectTargetFramework, testNuGetProjectContext, randomProjectFolderPath);
                var projectFilePath           = Path.Combine(randomProjectFolderPath, $"{msBuildNuGetProjectSystem.ProjectName}.csproj");
                var buildIntegratedProject    = new ProjectJsonNuGetProject(projectJsonPath, projectFilePath);

                var referenceContext = new DependencyGraphCacheContext(new TestLogger(), NullSettings.Instance);

                // Act
                var actual = (await buildIntegratedProject.GetPackageSpecsAsync(referenceContext)).SingleOrDefault();

                // Assert
                Assert.NotNull(actual);
                Assert.Equal(msBuildNuGetProjectSystem.ProjectName, actual.Name);
                Assert.Equal(projectJsonPath, actual.FilePath);
                Assert.NotNull(actual.RestoreMetadata);
                Assert.Equal(ProjectStyle.ProjectJson, actual.RestoreMetadata.ProjectStyle);
                Assert.Equal(projectFilePath, actual.RestoreMetadata.ProjectPath);
                Assert.Equal(msBuildNuGetProjectSystem.ProjectName, actual.RestoreMetadata.ProjectName);
                Assert.Equal(projectFilePath, actual.RestoreMetadata.ProjectUniqueName);
                Assert.Equal(1, actual.TargetFrameworks.Count);
                Assert.Equal(projectTargetFramework, actual.TargetFrameworks[0].FrameworkName);
                Assert.Equal(1, actual.TargetFrameworks[0].Imports.Count);
                Assert.Equal(FallbackTargetFramework, actual.TargetFrameworks[0].Imports[0]);

                Assert.Empty(actual.Dependencies);
                Assert.Empty(actual.TargetFrameworks[0].Dependencies);
                Assert.Empty(actual.RestoreMetadata.TargetFrameworks.SelectMany(e => e.ProjectReferences));
            }
        }
示例#8
0
        public static PackageSpec GetExistingProjectPackageSpec(this DependencyGraphCacheContext context, string projectPath)
        {
            if (context == null)
            {
                return(null);
            }

            if (context.PackageSpecCache.TryGetValue(projectPath, out PackageSpec packageSpec))
            {
                return(packageSpec);
            }
            return(null);
        }
示例#9
0
        public MonoDevelopBuildIntegratedRestorer(
            IMonoDevelopSolutionManager solutionManager,
            ISourceRepositoryProvider repositoryProvider,
            ISettings settings)
        {
            this.solutionManager = solutionManager;
            sourceRepositories   = repositoryProvider.GetRepositories().ToList();
            this.settings        = settings;

            packageManagementEvents = PackageManagementServices.PackageManagementEvents;

            context = CreateRestoreContext();
        }
        public static Task <DependencyGraphSpec> GetSolutionRestoreSpec(
            IMonoDevelopSolutionManager solutionManager,
            IEnumerable <BuildIntegratedNuGetProject> projects,
            DependencyGraphCacheContext context,
            CancellationToken cancellationToken)
        {
            if (projects.Count() > MaxSupportedProjectsForMSBuildHost)
            {
                return(MSBuildUtility.GetSolutionRestoreSpec(solutionManager.Solution, projects, solutionManager.Configuration, context.Logger, cancellationToken));
            }

            return(DependencyGraphRestoreUtility.GetSolutionRestoreSpec(solutionManager, context));
        }
示例#11
0
        PackageSpec GetExistingProjectPackageSpec(DependencyGraphCacheContext context)
        {
            PackageSpec packageSpec = null;

            if (context != null)
            {
                if (context.PackageSpecCache.TryGetValue(MSBuildProjectPath, out packageSpec))
                {
                    return(packageSpec);
                }
            }
            return(packageSpec);
        }
        /// <summary>
        /// Restore many projects without writing the lock file
        /// SourceRepositories(sources) is only used for the CachingSourceProvider, the project-specific sources will still be resolved in RestoreRunner.
        /// </summary>
        internal static async Task <IEnumerable <RestoreResultPair> > PreviewRestoreProjectsAsync(
            ISolutionManager solutionManager,
            IEnumerable <BuildIntegratedNuGetProject> projects,
            IEnumerable <PackageSpec> updatedNugetPackageSpecs,
            DependencyGraphCacheContext context,
            RestoreCommandProvidersCache providerCache,
            Action <SourceCacheContext> cacheContextModifier,
            IEnumerable <SourceRepository> sources,
            Guid parentId,
            ILogger log,
            CancellationToken token)
        {
            token.ThrowIfCancellationRequested();

            // Add the new spec to the dg file and fill in the rest.
            var dgFile = await GetSolutionRestoreSpec(solutionManager, context);

            dgFile = dgFile.WithoutRestores()
                     .WithPackageSpecs(updatedNugetPackageSpecs);

            foreach (var project in projects)
            {
                dgFile.AddRestore(project.MSBuildProjectPath);
            }

            using (var sourceCacheContext = new SourceCacheContext())
            {
                // Update cache context
                cacheContextModifier(sourceCacheContext);

                // Settings passed here will be used to populate the restore requests.
                var restoreContext = GetRestoreArgs(
                    context,
                    providerCache,
                    sourceCacheContext,
                    sources,
                    dgFile,
                    parentId,
                    forceRestore: true,
                    isRestoreOriginalAction: false,
                    restoreForceEvaluate: true,
                    additionalMessasges: null,
                    progressReporter: null);

                var requests = await RestoreRunner.GetRequests(restoreContext);

                var results = await RestoreRunner.RunWithoutCommit(requests, restoreContext);

                return(results);
            }
        }
        /// <summary>
        /// Restore a solution and cache the dg spec to context.
        /// </summary>
        public static async Task <IReadOnlyList <RestoreSummary> > RestoreAsync(
            ISolutionManager solutionManager,
            DependencyGraphSpec dgSpec,
            DependencyGraphCacheContext context,
            RestoreCommandProvidersCache providerCache,
            Action <SourceCacheContext> cacheContextModifier,
            IEnumerable <SourceRepository> sources,
            Guid parentId,
            bool forceRestore,
            bool isRestoreOriginalAction,
            IReadOnlyList <IAssetsLogMessage> additionalMessages,
            ILogger log,
            CancellationToken token)
        {
            // TODO: This will flow from UI once we enable UI option to trigger reevaluation
            var restoreForceEvaluate = false;

            // Check if there are actual projects to restore before running.
            if (dgSpec.Restore.Count > 0)
            {
                using (var sourceCacheContext = new SourceCacheContext())
                {
                    // Update cache context
                    cacheContextModifier(sourceCacheContext);

                    var restoreContext = GetRestoreContext(
                        context,
                        providerCache,
                        sourceCacheContext,
                        sources,
                        dgSpec,
                        parentId,
                        forceRestore,
                        isRestoreOriginalAction,
                        restoreForceEvaluate,
                        additionalMessages);

                    var restoreSummaries = await RestoreRunner.RunAsync(restoreContext, token);

                    RestoreSummary.Log(log, restoreSummaries);

                    await PersistDGSpec(dgSpec);

                    return(restoreSummaries);
                }
            }

            return(new List <RestoreSummary>());
        }
        public override Task <IReadOnlyList <PackageSpec> > GetPackageSpecsAsync(DependencyGraphCacheContext context)
        {
            var projects = new List <PackageSpec>();

            DependencyGraphSpec projectRestoreInfo;

            if (!_projectSystemCache.TryGetProjectRestoreInfo(_projectFullPath, out projectRestoreInfo))
            {
                throw new InvalidOperationException(
                          string.Format(Strings.ProjectNotLoaded_RestoreFailed, ProjectName));
            }

            // Apply ISettings when needed to the return values.
            // This should not change the cached specs since they
            // contain values such as CLEAR which need to be persisted
            // and used here.
            var originalProjects = projectRestoreInfo.Projects;

            var settings = context?.Settings ?? NullSettings.Instance;

            foreach (var originalProject in originalProjects)
            {
                var project = originalProject.Clone();

                // Read restore settings from ISettings if it doesn't exist in the project
                // NOTE: Very important that the original project is used in the arguments, because cloning sorts the sources and compromises how the sources will be evaluated
                project.RestoreMetadata.PackagesPath    = VSRestoreSettingsUtilities.GetPackagesPath(settings, originalProject);
                project.RestoreMetadata.Sources         = VSRestoreSettingsUtilities.GetSources(settings, originalProject);
                project.RestoreMetadata.FallbackFolders = VSRestoreSettingsUtilities.GetFallbackFolders(settings, originalProject);
                project.RestoreMetadata.ConfigFilePaths = GetConfigFilePaths(settings);
                IgnoreUnsupportProjectReference(project);
                projects.Add(project);
            }

            if (context != null)
            {
                PackageSpec ignore;
                foreach (var project in projects
                         .Where(p => !context.PackageSpecCache.TryGetValue(
                                    p.RestoreMetadata.ProjectUniqueName, out ignore)))
                {
                    context.PackageSpecCache.Add(
                        project.RestoreMetadata.ProjectUniqueName,
                        project);
                }
            }

            return(Task.FromResult <IReadOnlyList <PackageSpec> >(projects));
        }
        public static async Task <DependencyGraphSpec> GetSolutionRestoreSpec(
            IMonoDevelopSolutionManager solutionManager,
            BuildIntegratedNuGetProject project,
            DependencyGraphCacheContext context,
            CancellationToken cancellationToken)
        {
            // NuGet when restoring a single project will request the DependencyGraphSpec from every project in the
            // solution so we obtain this up front so it can be cached and avoid getting the package spec
            // individually for each project. To do this we need all the BuildIntegratedNuGetProjects in the solution.
            var projects = await solutionManager.GetNuGetProjectsAsync();

            var buildIntegratedProjects = projects.OfType <BuildIntegratedNuGetProject> ().ToList();

            return(await GetSolutionRestoreSpec(solutionManager, buildIntegratedProjects, context, cancellationToken));
        }
        async Task <PackageSpec> CreateProjectPackageSpec(DependencyGraphCacheContext context)
        {
            DependencyGraphSpec dependencySpec = await MSBuildPackageSpecCreator.GetDependencyGraphSpec(project, configuration, context?.Logger);

            context.AddToCache(dependencySpec);

            PackageSpec spec = dependencySpec.GetProjectSpec(project.FileName);

            if (spec != null)
            {
                return(spec);
            }

            throw new InvalidOperationException(GettextCatalog.GetString("Unable to create package spec for project. '{0}'", project.FileName));
        }
示例#17
0
        public static void AddToCache(this DependencyGraphCacheContext context, DependencyGraphSpec dependencyGraphSpec)
        {
            if (context == null)
            {
                return;
            }

            foreach (PackageSpec packageSpec in dependencyGraphSpec.Projects)
            {
                if (CanCachePackageSpec(packageSpec))
                {
                    AddToCache(context, packageSpec);
                }
            }
        }
        private async Task <FallbackPackagePathResolver> GetPackagesPathResolverAsync(BuildIntegratedNuGetProject project)
        {
            // To get packagesPath for build integrated projects, first read the packageSpec to know if
            // RestorePackagesPath property was specified. If yes, then use that property to get packages path
            // otherwise use global user cache folder from _settings.
            var context      = new DependencyGraphCacheContext();
            var packageSpecs = await project.GetPackageSpecsAsync(context);

            var packageSpec = packageSpecs.Single(e => e.RestoreMetadata.ProjectStyle == ProjectStyle.PackageReference ||
                                                  e.RestoreMetadata.ProjectStyle == ProjectStyle.ProjectJson);

            var packagesPath = VSRestoreSettingsUtilities.GetPackagesPath(_settings, packageSpec);

            return(new FallbackPackagePathResolver(packagesPath, VSRestoreSettingsUtilities.GetFallbackFolders(_settings, packageSpec)));
        }
        /// <summary>
        /// Restore without writing the lock file
        /// </summary>
        internal static async Task <RestoreResultPair> PreviewRestoreAsync(
            ISolutionManager solutionManager,
            BuildIntegratedNuGetProject project,
            PackageSpec packageSpec,
            DependencyGraphCacheContext context,
            RestoreCommandProvidersCache providerCache,
            Action <SourceCacheContext> cacheContextModifier,
            IEnumerable <SourceRepository> sources,
            Guid parentId,
            ILogger log,
            CancellationToken token)
        {
            // Restoring packages
            var logger = context.Logger;

            // Add the new spec to the dg file and fill in the rest.
            var dgFile = await GetSolutionRestoreSpec(solutionManager, context);

            dgFile = dgFile.WithoutRestores()
                     .WithReplacedSpec(packageSpec);

            dgFile.AddRestore(project.MSBuildProjectPath);

            using (var sourceCacheContext = new SourceCacheContext())
            {
                // Update cache context
                cacheContextModifier(sourceCacheContext);

                // Settings passed here will be used to populate the restore requests.
                var restoreContext = GetRestoreContext(
                    context,
                    providerCache,
                    sourceCacheContext,
                    sources,
                    dgFile,
                    parentId,
                    forceRestore: true,
                    isRestoreOriginalAction: false,
                    restoreForceEvaluate: true,
                    additionalMessasges: null);

                var requests = await RestoreRunner.GetRequests(restoreContext);

                var results = await RestoreRunner.RunWithoutCommit(requests, restoreContext);

                return(results.Single());
            }
        }
示例#20
0
        public static PackageSpec CreatePackageSpec(IDotNetProject project, DependencyGraphCacheContext context)
        {
            var packageSpec = new PackageSpec(GetTargetFrameworks(project));

            packageSpec.FilePath = project.FileName;
            packageSpec.Name     = project.Name;
            packageSpec.Version  = GetVersion(project);

            packageSpec.RestoreMetadata = CreateRestoreMetadata(packageSpec, project, context.Settings);
            packageSpec.RuntimeGraph    = GetRuntimeGraph(project);
            AddProjectReferences(packageSpec, project, context.Logger);
            AddPackageReferences(packageSpec, project);
            AddPackageTargetFallbacks(packageSpec, project);

            return(packageSpec);
        }
        public async Task GetPackageSpecsAsync_WithProjectReference_Succeeds()
        {
            // Arrange
            using (var randomTestFolder = TestDirectory.Create())
            {
                var framework = NuGetFramework.Parse("netstandard13");

                var projectAdapter = CreateProjectAdapter(randomTestFolder);

                var projectServices = new TestProjectSystemServices();
                projectServices.SetupProjectDependencies(
                    new ProjectRestoreReference
                {
                    ProjectUniqueName = "TestProjectA",
                    ProjectPath       = Path.Combine(randomTestFolder, "TestProjectA")
                });

                var testProject = new LegacyPackageReferenceProject(
                    projectAdapter,
                    Guid.NewGuid().ToString(),
                    projectServices,
                    _threadingService);

                var testDependencyGraphCacheContext = new DependencyGraphCacheContext();

                await _threadingService.JoinableTaskFactory.SwitchToMainThreadAsync();

                // Act
                var packageSpecs = await testProject.GetPackageSpecsAsync(testDependencyGraphCacheContext);

                // Assert
                Assert.NotNull(packageSpecs);

                var actualRestoreSpec = packageSpecs.Single();
                SpecValidationUtility.ValidateProjectSpec(actualRestoreSpec);

                var actualDependency = actualRestoreSpec.RestoreMetadata.TargetFrameworks.Single().ProjectReferences.Single();
                Assert.NotNull(actualDependency);
                Assert.Equal("TestProjectA", actualDependency.ProjectUniqueName);

                // Verify
                Mock.Get(projectServices.ReferencesReader)
                .Verify(
                    x => x.GetProjectReferencesAsync(It.IsAny <Common.ILogger>(), CancellationToken.None),
                    Times.AtLeastOnce);
            }
        }
示例#22
0
        /// <summary>
        /// Restore a solution and cache the dg spec to context.
        /// </summary>
        public static async Task <IReadOnlyList <RestoreSummary> > RestoreAsync(
            ISolutionManager solutionManager,
            DependencyGraphCacheContext context,
            RestoreCommandProvidersCache providerCache,
            Action <SourceCacheContext> cacheContextModifier,
            IEnumerable <SourceRepository> sources,
            string userPackagesPath,
            ISettings settings,
            ILogger log,
            CancellationToken token)
        {
            // Get full dg spec
            var dgSpec = await GetSolutionRestoreSpec(solutionManager, context);

            // Cache spec
            context.SolutionSpec     = dgSpec;
            context.SolutionSpecHash = dgSpec.GetHash();

            // Check if there are actual projects to restore before running.
            if (dgSpec.Restore.Count > 0)
            {
                using (var sourceCacheContext = new SourceCacheContext())
                {
                    // Update cache context
                    cacheContextModifier(sourceCacheContext);

                    var restoreContext = GetRestoreContext(
                        context,
                        providerCache,
                        settings,
                        sourceCacheContext,
                        sources,
                        dgSpec,
                        userPackagesPath);

                    var restoreSummaries = await RestoreRunner.RunAsync(restoreContext, token);

                    RestoreSummary.Log(log, restoreSummaries);

                    return(restoreSummaries);
                }
            }

            return(new List <RestoreSummary>());
        }
        public async Task GetPackageSpecAsync_CentralPackageVersionsRemovedDuplicates()
        {
            // Arrange
            var packageAv1 = (PackageId : "packageA", Version : "1.2.3");
            var packageB   = (PackageId : "packageB", Version : "3.4.5");
            var packageAv5 = (PackageId : "packageA", Version : "5.0.0");

            var projectNames = new ProjectNames(
                fullName: "projectName",
                uniqueName: "projectName",
                shortName: "projectName",
                customUniqueName: "projectName",
                projectId: Guid.NewGuid().ToString());

            var vsProjectAdapter = new TestVSProjectAdapter(
                "projectPath",
                projectNames,
                "framework",
                restorePackagesWithLockFile: null,
                nuGetLockFilePath: null,
                restoreLockedMode: false,
                projectPackageVersions: new List <(string Id, string Version)>()
            {
                packageAv1, packageB, packageAv5
            });

            var legacyPRProject = new LegacyPackageReferenceProject(
                vsProjectAdapter,
                Guid.NewGuid().ToString(),
                new TestProjectSystemServices(),
                _threadingService);

            var settings = NullSettings.Instance;
            var context  = new DependencyGraphCacheContext(NullLogger.Instance, settings);

            var packageSpecs = await legacyPRProject.GetPackageSpecsAsync(context);

            Assert.Equal(1, packageSpecs.Count);
            Assert.True(packageSpecs.First().RestoreMetadata.CentralPackageVersionsEnabled);
            var centralPackageVersions = packageSpecs.First().TargetFrameworks.First().CentralPackageVersions;

            Assert.Equal(2, centralPackageVersions.Count);
            Assert.Equal(VersionRange.Parse(packageAv1.Version), centralPackageVersions[packageAv1.PackageId].VersionRange);
            Assert.Equal(VersionRange.Parse(packageB.Version), centralPackageVersions[packageB.PackageId].VersionRange);
        }
        private async Task <(InstalledPackageResultStatus, IReadOnlyCollection <NuGetInstalledPackage>)> GetInstalledPackagesAsync(BuildIntegratedNuGetProject project, CancellationToken cancellationToken)
        {
            NuGetInstalledPackage ToNuGetInstalledPackage(PackageReference packageReference, FallbackPackagePathResolver pathResolver)
            {
                var id = packageReference.PackageIdentity.Id;

                var    versionRange   = packageReference.AllowedVersions;
                string requestedRange =
                    packageReference.AllowedVersions.OriginalString // most packages
                    ?? packageReference.AllowedVersions.ToShortString();
                string version          = versionRange.MinVersion.OriginalVersion ?? versionRange.MinVersion.ToNormalizedString();
                var    installPath      = pathResolver.GetPackageDirectory(id, version);
                bool   directDependency = true;

                return(NuGetContractsFactory.CreateNuGetInstalledPackage(id, requestedRange, version, installPath, directDependency));
            }

            InstalledPackageResultStatus status;
            IReadOnlyCollection <NuGetInstalledPackage> installedPackages;

            var cacheContext = new DependencyGraphCacheContext();

            var(packageSpecs, messages) = await project.GetPackageSpecsAndAdditionalMessagesAsync(cacheContext);

            if (messages?.Any(m => m.Level == LogLevel.Error) == true)
            {
                // Although we know that the project will fail to restore, we may still know about some direct dependencies, so let's return the packages that we know about.
                status = InstalledPackageResultStatus.ProjectInvalid;
            }
            else
            {
                status = InstalledPackageResultStatus.Successful;
            }

            var packageSpec  = packageSpecs.Single(s => s.RestoreMetadata.ProjectStyle == ProjectModel.ProjectStyle.PackageReference || s.RestoreMetadata.ProjectStyle == ProjectModel.ProjectStyle.ProjectJson);
            var packagesPath = VSRestoreSettingsUtilities.GetPackagesPath(_settings, packageSpec);
            FallbackPackagePathResolver pathResolver = new FallbackPackagePathResolver(packagesPath, VSRestoreSettingsUtilities.GetFallbackFolders(_settings, packageSpec));

            var packageReferences = await project.GetInstalledPackagesAsync(cancellationToken);

            installedPackages = packageReferences.Select(p => ToNuGetInstalledPackage(p, pathResolver))
                                .ToList();

            return(status, installedPackages);
        }
        public async Task GetPackageSpecsAsync_WithDefaultVersion_Succeeds()
        {
            // Arrange
            using (var testDirectory = TestDirectory.Create())
            {
                var projectAdapter  = CreateProjectAdapter(testDirectory);
                var projectServices = new TestProjectSystemServices();

                var testProject = new LegacyPackageReferenceProject(
                    projectAdapter,
                    Guid.NewGuid().ToString(),
                    projectServices,
                    _threadingService);

                var testDependencyGraphCacheContext = new DependencyGraphCacheContext();

                await _threadingService.JoinableTaskFactory.SwitchToMainThreadAsync();

                // Act
                var packageSpecs = await testProject.GetPackageSpecsAsync(testDependencyGraphCacheContext);

                // Assert
                Assert.NotNull(packageSpecs);

                var actualRestoreSpec = packageSpecs.Single();
                SpecValidationUtility.ValidateProjectSpec(actualRestoreSpec);

                Assert.Equal("1.0.0", actualRestoreSpec.Version.ToString());

                // Verify
                Mock.Get(projectAdapter)
                .VerifyGet(x => x.Version, Times.AtLeastOnce);
                Mock.Get(projectAdapter)
                .VerifyGet(x => x.ProjectName, Times.AtLeastOnce);
                Mock.Get(projectAdapter)
                .Verify(x => x.GetRuntimeIdentifiersAsync(), Times.AtLeastOnce);
                Mock.Get(projectAdapter)
                .Verify(x => x.GetRuntimeSupportsAsync(), Times.AtLeastOnce);
                Mock.Get(projectAdapter)
                .VerifyGet(x => x.FullProjectPath, Times.AtLeastOnce);
                Mock.Get(projectAdapter)
                .Verify(x => x.GetTargetFrameworkAsync(), Times.AtLeastOnce);
            }
        }
        /// <summary>
        /// True if all projects have been nominated and the restore worker has completed all work.
        /// </summary>
        public async Task <bool> IsRestoreCompleteAsync(CancellationToken token)
        {
            const string eventName = nameof(IVsSolutionRestoreStatusProvider) + "." + nameof(IsRestoreCompleteAsync);

            using var _ = NuGetETW.ExtensibilityEventSource.StartStopEvent(eventName);

            try
            {
                var complete = true;

                // Check if the solution is open, if there are no projects then consider it restored.
                if (await _solutionManager.Value.IsSolutionOpenAsync())
                {
                    var graphContext = new DependencyGraphCacheContext();
                    var projects     = (await _solutionManager.Value.GetNuGetProjectsAsync()).AsList();

                    // It could be that the project added to the solution has not yet been updated.
                    if (projects == null || projects.Count == 0)
                    {
                        return(false);
                    }

                    // Empty solutions with no projects are considered restored.
                    foreach (var project in projects)
                    {
                        token.ThrowIfCancellationRequested();

                        // Check if the project has a spec to see if nomination is complete.
                        complete &= await HasSpecAsync(project, graphContext);
                    }

                    // Check if the restore worker is currently active.
                    complete &= !_restoreWorker.Value.IsRunning;
                }

                return(complete);
            }
            catch (Exception ex)
            {
                await _telemetryProvider.PostFaultAsync(ex, nameof(VsSolutionRestoreStatusProvider));

                throw;
            }
        }
        public static async Task <RestoreResult> RestoreProjectAsync(
            ISolutionManager solutionManager,
            BuildIntegratedNuGetProject project,
            DependencyGraphCacheContext context,
            RestoreCommandProvidersCache providerCache,
            Action <SourceCacheContext> cacheContextModifier,
            IEnumerable <SourceRepository> sources,
            Guid parentId,
            ILogger log,
            CancellationToken token)
        {
            if (project == null)
            {
                throw new ArgumentNullException(nameof(project));
            }

            // Restore
            var specs = await project.GetPackageSpecsAsync(context);

            var spec = specs.Single(e => e.RestoreMetadata.ProjectStyle == ProjectStyle.PackageReference ||
                                    e.RestoreMetadata.ProjectStyle == ProjectStyle.ProjectJson); // Do not restore global tools Project Style in VS.

            var result = await PreviewRestoreAsync(
                solutionManager,
                project,
                spec,
                context,
                providerCache,
                cacheContextModifier,
                sources,
                parentId,
                token);

            // Throw before writing if this has been canceled
            token.ThrowIfCancellationRequested();

            // Write out the lock file and msbuild files
            var summary = await RestoreRunner.CommitAsync(result, token);

            RestoreSummary.Log(log, new[] { summary });

            return(result.Result);
        }
        public async Task GetPackageSpecsAsync_SkipContentFilesAlwaysTrue()
        {
            // Arrange
            using (var randomTestFolder = TestDirectory.Create())
            {
                var framework = NuGetFramework.Parse("netstandard13");

                var projectAdapter = CreateProjectAdapter(randomTestFolder);

                var projectServices = new TestProjectSystemServices();
                projectServices.SetupInstalledPackages(
                    framework,
                    new LibraryDependency
                {
                    LibraryRange = new LibraryRange(
                        "packageA",
                        VersionRange.Parse("1.*"),
                        LibraryDependencyTarget.Package)
                });

                var testProject = new LegacyPackageReferenceProject(
                    projectAdapter,
                    Guid.NewGuid().ToString(),
                    projectServices,
                    _threadingService);

                var testDependencyGraphCacheContext = new DependencyGraphCacheContext();

                await _threadingService.JoinableTaskFactory.SwitchToMainThreadAsync();

                // Act
                var packageSpecs = await testProject.GetPackageSpecsAsync(testDependencyGraphCacheContext);

                // Assert
                Assert.NotNull(packageSpecs);

                var actualRestoreSpec = packageSpecs.Single();
                SpecValidationUtility.ValidateProjectSpec(actualRestoreSpec);

                Assert.True(actualRestoreSpec.RestoreMetadata.SkipContentFileWrite);
            }
        }
        /// <summary>
        /// Create a restore args.
        /// </summary>
        private static RestoreArgs GetRestoreArgs(
            DependencyGraphCacheContext context,
            RestoreCommandProvidersCache providerCache,
            SourceCacheContext sourceCacheContext,
            IEnumerable <SourceRepository> sources,
            DependencyGraphSpec dgFile,
            Guid parentId,
            bool forceRestore,
            bool isRestoreOriginalAction,
            bool restoreForceEvaluate,
            IReadOnlyList <IAssetsLogMessage> additionalMessasges,
            IRestoreProgressReporter progressReporter)
        {
#pragma warning disable CS0618 // Type or member is obsolete
            var caching = new CachingSourceProvider(new PackageSourceProvider(context.Settings, enablePackageSourcesChangedEvent: false));
#pragma warning restore CS0618 // Type or member is obsolete
            foreach (var source in sources)
            {
                caching.AddSourceRepository(source);
            }

            var dgProvider = new DependencyGraphSpecRequestProvider(providerCache, dgFile);

            var restoreContext = new RestoreArgs()
            {
                CacheContext = sourceCacheContext,
                PreLoadedRequestProviders = new List <IPreLoadedRestoreRequestProvider>()
                {
                    dgProvider
                },
                Log                     = context.Logger,
                AllowNoOp               = !forceRestore,
                CachingSourceProvider   = caching,
                ParentId                = parentId,
                IsRestoreOriginalAction = isRestoreOriginalAction,
                RestoreForceEvaluate    = restoreForceEvaluate,
                AdditionalMessages      = additionalMessasges,
                ProgressReporter        = progressReporter,
            };

            return(restoreContext);
        }
        /// <summary>
        /// Restore a solution and cache the dg spec to context.
        /// </summary>
        public static async Task <IReadOnlyList <RestoreSummary> > RestoreAsync(
            ISolutionManager solutionManager,
            DependencyGraphCacheContext context,
            RestoreCommandProvidersCache providerCache,
            Action <SourceCacheContext> cacheContextModifier,
            IEnumerable <SourceRepository> sources,
            Guid parentId,
            bool forceRestore,
            DependencyGraphSpec dgSpec,
            ILogger log,
            CancellationToken token)
        {
            // Check if there are actual projects to restore before running.
            if (dgSpec.Restore.Count > 0)
            {
                using (var sourceCacheContext = new SourceCacheContext())
                {
                    // Update cache context
                    cacheContextModifier(sourceCacheContext);

                    var restoreContext = GetRestoreContext(
                        context,
                        providerCache,
                        sourceCacheContext,
                        sources,
                        dgSpec,
                        parentId,
                        forceRestore);

                    var restoreSummaries = await RestoreRunner.RunAsync(restoreContext, token);

                    RestoreSummary.Log(log, restoreSummaries);

                    await PersistDGSpec(dgSpec);

                    return(restoreSummaries);
                }
            }

            return(new List <RestoreSummary>());
        }