public void GetParents_WhenDirtySpecsListIsEmpty_ReturnsEmpty()
        {
            var projectA = GetPackageSpec("A");
            var projectB = GetPackageSpec("B");
            var projectC = GetPackageSpec("C");

            // A => B => C
            projectA = projectA.WithTestProjectReference(projectB);
            projectB = projectB.WithTestProjectReference(projectC);

            var dgSpec = new DependencyGraphSpec();

            dgSpec.AddProject(projectA);
            dgSpec.AddRestore(projectA.RestoreMetadata.ProjectUniqueName);
            dgSpec.AddProject(projectB);
            dgSpec.AddRestore(projectB.RestoreMetadata.ProjectUniqueName);
            dgSpec.AddProject(projectC);
            dgSpec.AddRestore(projectC.RestoreMetadata.ProjectUniqueName);

            Assert.Empty(SolutionUpToDateChecker.GetParents(new List <string>(), dgSpec));
        }
示例#2
0
        public void IsLockFileStillValid_NoCentralPackageVersions_DoesNotInvalidateLockFile()
        {
            // Arrange
            var framework   = CommonFrameworks.NetStandard20;
            var projectName = "project";

            var dependency1 = new LibraryDependency(
                new LibraryRange("cpvm1", versionRange: VersionRange.Parse("1.0.0"), LibraryDependencyTarget.Package),
                LibraryDependencyType.Default,
                LibraryIncludeFlags.All,
                LibraryIncludeFlags.All,
                new List <Common.NuGetLogCode>(),
                autoReferenced: false,
                generatePathProperty: true);

            var tfm = new TargetFrameworkInformation();

            tfm.FrameworkName = framework;
            tfm.Dependencies.Add(dependency1);

            var project = new PackageSpec(new List <TargetFrameworkInformation>()
            {
                tfm
            });

            project.RestoreMetadata = new ProjectRestoreMetadata()
            {
                ProjectUniqueName = projectName, CentralPackageVersionsEnabled = false
            };

            DependencyGraphSpec dgSpec = new DependencyGraphSpec();

            dgSpec.AddRestore(projectName);
            dgSpec.AddProject(project);

            var lockFile = new PackagesLockFileBuilder()
                           .WithTarget(target => target
                                       .WithFramework(CommonFrameworks.NetStandard20)
                                       .WithDependency(dep => dep
                                                       .WithId("cpvm1")
                                                       .WithRequestedVersion(VersionRange.Parse("1.0.0"))
                                                       .WithType(PackageDependencyType.Direct))
                                       .WithDependency(dep => dep
                                                       .WithId("otherDep")
                                                       .WithRequestedVersion(VersionRange.Parse("1.0.0"))
                                                       .WithType(PackageDependencyType.Transitive)))
                           .Build();

            // Nothing changed in central package versions
            var actual = PackagesLockFileUtilities.IsLockFileStillValid(dgSpec, lockFile);

            Assert.True(actual);
        }
示例#3
0
        public async Task Cycle_PackageWithSameNameAsProjectVerifyCycleDetectedAtEnd()
        {
            // Arrange
            using (var cacheContext = new SourceCacheContext())
                using (var pathContext = new SimpleTestPathContext())
                {
                    var logger  = new TestLogger();
                    var sources = new List <PackageSource>
                    {
                        new PackageSource(pathContext.PackageSource)
                    };

                    var spec1 = NETCoreRestoreTestUtility.GetProject(projectName: "projectA", framework: "netstandard1.6");
                    spec1.TargetFrameworks[0].Dependencies.Add(new LibraryDependency()
                    {
                        LibraryRange = new LibraryRange("x", VersionRange.Parse("1.0.0"), LibraryDependencyTarget.Package)
                    });

                    var specs = new[] { spec1 };

                    // Create fake projects, the real data is in the specs
                    var projects = NETCoreRestoreTestUtility.CreateProjectsFromSpecs(pathContext, specs);

                    // A -> X -> Y -> Z -> Z
                    var packageX = new SimpleTestPackageContext("x", "1.0.0");
                    var packageY = new SimpleTestPackageContext("y", "1.0.0");
                    var packageZ = new SimpleTestPackageContext("z", "1.0.0");

                    packageX.Dependencies.Add(packageY);
                    packageY.Dependencies.Add(packageZ);
                    packageZ.Dependencies.Add(packageZ);

                    SimpleTestPackageUtility.CreatePackages(pathContext.PackageSource, packageX, packageY, packageZ);

                    // Create dg file
                    var dgFile = new DependencyGraphSpec();

                    // Only add projectA
                    dgFile.AddProject(spec1);
                    dgFile.AddRestore(spec1.RestoreMetadata.ProjectUniqueName);

                    dgFile.Save(Path.Combine(pathContext.WorkingDirectory, "out.dg"));

                    // Act
                    var summaries = await NETCoreRestoreTestUtility.RunRestore(pathContext, logger, sources, dgFile, cacheContext);

                    var success = summaries.All(s => s.Success);

                    // Assert
                    Assert.False(success, "Failed: " + string.Join(Environment.NewLine, logger.Messages));
                    Assert.Contains("Cycle detected", string.Join(Environment.NewLine, logger.ErrorMessages));
                }
        }
示例#4
0
        public async Task NETCoreProject2Project_ProjectReference_IgnoredForTFM()
        {
            // Arrange
            using (var cacheContext = new SourceCacheContext())
                using (var pathContext = new SimpleTestPathContext())
                {
                    var logger  = new TestLogger();
                    var sources = new List <PackageSource>();
                    sources.Add(new PackageSource(pathContext.PackageSource));

                    var spec1 = NETCoreRestoreTestUtility.GetProject(projectName: "projectA", framework: "netstandard1.6");
                    var spec2 = NETCoreRestoreTestUtility.GetProject(projectName: "projectB", framework: "netstandard1.3");

                    var specs = new[] { spec1, spec2 };

                    // Create fake projects, the real data is in the specs
                    var projects = NETCoreRestoreTestUtility.CreateProjectsFromSpecs(pathContext, specs);

                    // Remove valid link
                    spec1.RestoreMetadata.TargetFrameworks.Clear();

                    // Add invalid link, net45 is not a project tfm
                    spec1.RestoreMetadata.TargetFrameworks.Add(new ProjectRestoreMetadataFrameworkInfo(NuGetFramework.Parse("net45")));
                    spec1.RestoreMetadata.TargetFrameworks.Single().ProjectReferences.Add(new ProjectRestoreReference()
                    {
                        ProjectPath       = projects[1].ProjectPath,
                        ProjectUniqueName = spec2.RestoreMetadata.ProjectUniqueName
                    });

                    // Create dg file
                    var dgFile = new DependencyGraphSpec();
                    foreach (var spec in specs)
                    {
                        dgFile.AddProject(spec);
                    }

                    // Restore only the first one
                    dgFile.AddRestore(spec1.RestoreMetadata.ProjectUniqueName);

                    dgFile.Save(Path.Combine(pathContext.WorkingDirectory, "out.dg"));

                    // Act
                    var summaries = await NETCoreRestoreTestUtility.RunRestore(pathContext, logger, sources, dgFile, cacheContext);

                    var success = summaries.All(s => s.Success);

                    // Assert
                    Assert.True(success, "Failed: " + string.Join(Environment.NewLine, logger.Messages));
                    Assert.Equal(0, projects[0].AssetsFile.Libraries.Count);
                }
        }
示例#5
0
        public async Task RestoreResult_Commit_WritesDependencyGraphSpec()
        {
            // Arrange
            using (var td = TestDirectory.Create())
            {
                var path       = Path.Combine(td, "project.assets.json");
                var cachePath  = Path.Combine(td, "project.csproj.nuget.cache");
                var dgSpecPath = Path.Combine(td, "project1.nuget.g.dgspec.json");
                var dgSpec     = new DependencyGraphSpec();
                var configJson = @"
                {
                    ""dependencies"": {
                    },
                     ""frameworks"": {
                        ""net45"": { }
                    }
                }";

                var spec = JsonPackageSpecReader.GetPackageSpec(configJson, "TestProject", Path.Combine(td, "project.csproj")).WithTestRestoreMetadata();
                dgSpec.AddProject(spec);
                dgSpec.AddRestore(spec.Name);

                var logger = new TestLogger();
                var result = new RestoreResult(
                    success: true,
                    restoreGraphs: null,
                    compatibilityCheckResults: null,
                    lockFile: new LockFile(),
                    previousLockFile: null, // different lock file
                    lockFilePath: path,
                    msbuildFiles: Enumerable.Empty <MSBuildOutputFile>(),
                    cacheFile: new CacheFile("NotSoRandomString"),
                    cacheFilePath: cachePath,
                    packagesLockFilePath: null,
                    packagesLockFile: null,
                    dependencyGraphSpecFilePath: dgSpecPath,
                    dependencyGraphSpec: dgSpec,
                    projectStyle: ProjectStyle.Unknown,
                    elapsedTime: TimeSpan.MinValue);

                // Act
                await result.CommitAsync(logger, CancellationToken.None);

                // Assert
                Assert.Empty(logger.MinimalMessages);
                Assert.Contains(
                    $"Persisting dg to {dgSpecPath}",
                    logger.VerboseMessages);
                Assert.True(File.Exists(dgSpecPath));
            }
        }
        public async Task DotnetCliTool_BasicToolRestore_WithDuplicates()
        {
            // Arrange
            using (var pathContext = new SimpleTestPathContext())
            {
                var logger = new TestLogger();
                var dgFile = new DependencyGraphSpec();

                for (int i = 0; i < 10; i++)
                {
                    var spec = ToolRestoreUtility.GetSpec(
                        Path.Combine(pathContext.SolutionRoot, "fake.csproj"),
                        "a",
                        VersionRange.Parse("1.0.0"),
                        NuGetFramework.Parse("netcoreapp1.0"),
                        pathContext.UserPackagesFolder,
                        new List <string>()
                    {
                        pathContext.FallbackFolder
                    },
                        new List <PackageSource>()
                    {
                        new PackageSource(pathContext.PackageSource)
                    },
                        projectWideWarningProperties: null);

                    dgFile.AddProject(spec);
                    dgFile.AddRestore(spec.Name);
                }

                var pathResolver = new ToolPathResolver(pathContext.UserPackagesFolder);
                var path         = pathResolver.GetLockFilePath(
                    "a",
                    NuGetVersion.Parse("1.0.0"),
                    NuGetFramework.Parse("netcoreapp1.0"));

                await SimpleTestPackageUtility.CreateFolderFeedV3Async(pathContext.PackageSource, new PackageIdentity("a", NuGetVersion.Parse("1.0.0")));

                // Act
                var results = await CommandsTestUtility.RunRestore(dgFile, pathContext, logger);

                // Assert
                // This should have been de-duplicated
                Assert.Equal(1, results.Count);
                var result = results.Single();

                Assert.True(result.Success, "Failed: " + string.Join(Environment.NewLine, logger.Messages));
                Assert.True(File.Exists(path));
            }
        }
示例#7
0
        private static DependencyGraphSpec CreateDependencyGraphSpecWithCentralDependencies(params TargetFrameworkInformation[] tfis)
        {
            var packageSpec = new PackageSpec(tfis);

            packageSpec.RestoreMetadata = new ProjectRestoreMetadata()
            {
                ProjectUniqueName = "a", CentralPackageVersionsEnabled = true
            };
            var dgSpec = new DependencyGraphSpec();

            dgSpec.AddRestore("a");
            dgSpec.AddProject(packageSpec);
            return(dgSpec);
        }
        private static DependencyGraphSpec ToDependencyGraphSpec(ProjectNames projectNames, IVsProjectRestoreInfo projectRestoreInfo)
        {
            var dgSpec = new DependencyGraphSpec();

            var packageSpec = ToPackageSpec(projectNames, projectRestoreInfo);

            dgSpec.AddRestore(packageSpec.RestoreMetadata.ProjectUniqueName);
            dgSpec.AddProject(packageSpec);

            if (projectRestoreInfo.ToolReferences != null)
            {
                // Infer tool's TFM version from the current project TFM
                var projectTfms = projectRestoreInfo
                                  .TargetFrameworks
                                  .Cast <IVsTargetFrameworkInfo>()
                                  .Select(tfi => NuGetFramework.Parse(tfi.TargetFrameworkMoniker))
                                  .ToList();

                var isNetCore20 = projectTfms
                                  .Where(tfm => tfm.Framework == FrameworkIdentifiers.NetCoreApp || tfm.Framework == FrameworkIdentifiers.NetStandard)
                                  .Any(tfm => tfm.Version >= Version20);
                var toolFramework = isNetCore20 ? CommonFrameworks.NetCoreApp20 : CommonFrameworks.NetCoreApp10;

                projectRestoreInfo
                .ToolReferences
                .Cast <IVsReferenceItem>()
                .Select(r => ToToolPackageSpec(projectNames, r, toolFramework))
                .ToList()
                .ForEach(ts =>
                {
                    dgSpec.AddRestore(ts.RestoreMetadata.ProjectUniqueName);
                    dgSpec.AddProject(ts);
                });
            }

            return(dgSpec);
        }
        /// <summary>
        /// Creates a dg specs with all PackageReference and project.json projects to be restored.
        /// </summary>
        /// <param name="projects"></param>
        /// <returns></returns>
        public static DependencyGraphSpec GetDGSpecFromPackageSpecs(params PackageSpec[] projects)
        {
            var dgSpec = new DependencyGraphSpec();

            foreach (var project in projects)
            {
                dgSpec.AddProject(project);
                if (project.RestoreMetadata.ProjectStyle == ProjectStyle.PackageReference ||
                    project.RestoreMetadata.ProjectStyle == ProjectStyle.ProjectJson)
                {
                    dgSpec.AddRestore(project.RestoreMetadata.ProjectUniqueName);
                }
            }
            return(dgSpec);
        }
        public async Task StandaloneProject_BasicRestore()
        {
            // Arrange
            using (var pathContext = new SimpleTestPathContext())
            {
                var logger = new TestLogger();
                var dgFile = new DependencyGraphSpec();

                var projectJson = @"
                {
                  ""frameworks"": {
                    ""netstandard1.6"": {
                      ""dependencies"": {
                        ""a"": ""1.0.0""
                      }
                    }
                  }
                }";

                var spec = JsonPackageSpecReader.GetPackageSpec(projectJson, "x", Path.Combine(pathContext.SolutionRoot, "project.json"));
                spec.RestoreMetadata = new ProjectRestoreMetadata();
                spec.RestoreMetadata.ProjectStyle      = ProjectStyle.Standalone;
                spec.RestoreMetadata.OutputPath        = Path.Combine(pathContext.SolutionRoot, "x");
                spec.RestoreMetadata.ProjectUniqueName = "x";
                spec.RestoreMetadata.ProjectName       = "x";
                spec.RestoreMetadata.ProjectPath       = Path.Combine(pathContext.SolutionRoot, "x.csproj");

                dgFile.AddProject(spec);
                dgFile.AddRestore("x");

                await SimpleTestPackageUtility.CreateFolderFeedV3Async(pathContext.PackageSource, new PackageIdentity("a", NuGetVersion.Parse("1.0.0")));

                // Act
                var result = await CommandsTestUtility.RunSingleRestore(dgFile, pathContext, logger);

                var path = Path.Combine(spec.RestoreMetadata.OutputPath, "project.assets.json");

                // Assert
                Assert.True(result.Success, "Failed: " + string.Join(Environment.NewLine, logger.Messages));
                Assert.True(File.Exists(path));

                var lockFormat = new LockFileFormat();
                var lockFile   = lockFormat.Read(path);

                Assert.Equal(NuGetFramework.Parse("netstandard1.6"), lockFile.Targets.Single().TargetFramework);
                Assert.Equal("a", lockFile.Targets.Single().Libraries.Single().Name);
            }
        }
示例#11
0
        internal static async Task <RestoreResult> RestoreAsync(RestoreParams restoreParameters, ILogger logger, CancellationToken cancellationToken = default)
        {
            var providerCache = new RestoreCommandProvidersCache();

            using (var cacheContext = new SourceCacheContext())
            {
                cacheContext.NoCache             = false;
                cacheContext.IgnoreFailedSources = true;

                var providers = new List <IPreLoadedRestoreRequestProvider>();

                var dgSpec = new DependencyGraphSpec();
                dgSpec.AddRestore(restoreParameters.ProjectName);
                var projectSpec = new PackageSpec
                {
                    Name             = restoreParameters.ProjectName,
                    FilePath         = restoreParameters.ProjectName,
                    RestoreMetadata  = CreateRestoreMetadata(restoreParameters),
                    TargetFrameworks = { CreateTargetFramework(restoreParameters) }
                };
                dgSpec.AddProject(projectSpec);

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

                var restoreContext = new RestoreArgs
                {
                    CacheContext              = cacheContext,
                    LockFileVersion           = LockFileFormat.Version,
                    DisableParallel           = false,
                    Log                       = logger,
                    MachineWideSettings       = new XPlatMachineWideSetting(),
                    PreLoadedRequestProviders = providers,
                    AllowNoOp                 = true,
                    HideWarningsAndErrors     = true
                };

                var restoreSummaries = await RestoreRunner.RunAsync(restoreContext, cancellationToken).ConfigureAwait(false);

                var result = new RestoreResult
                {
                    NoOp    = restoreSummaries.All(x => x.NoOpRestore),
                    Success = restoreSummaries.All(x => x.Success),
                    Errors  = restoreSummaries.SelectMany(x => x.Errors).Select(x => x.Message).ToImmutableArray()
                };

                return(result);
            }
        }
        /// <summary>
        /// Creates a restore request, with the only source being the source from the <paramref name="pathContext"/>.
        /// </summary>
        /// <param name="spec"></param>
        /// <param name="pathContext"></param>
        /// <param name="logger"></param>
        /// <returns></returns>
        public static TestRestoreRequest CreateRestoreRequest(PackageSpec spec, SimpleTestPathContext pathContext, ILogger logger)
        {
            var sources = new List <PackageSource> {
                new PackageSource(pathContext.PackageSource)
            };
            var dgSpec = new DependencyGraphSpec();

            dgSpec.AddProject(spec);
            dgSpec.AddRestore(spec.RestoreMetadata.ProjectUniqueName);

            return(new TestRestoreRequest(spec, sources, pathContext.UserPackagesFolder, logger)
            {
                LockFilePath = Path.Combine(spec.FilePath, LockFileFormat.AssetsFileName),
                DependencyGraphSpec = dgSpec,
            });
        }
示例#13
0
        private static DependencyGraphSpec CreateDependencyGraphSpecWithCentralDependencies(bool cpvmEnabled, bool tdpEnabled, params TargetFrameworkInformation[] tfis)
        {
            var packageSpec = new PackageSpec(tfis);

            packageSpec.RestoreMetadata = new ProjectRestoreMetadata
            {
                ProjectUniqueName                      = "a",
                CentralPackageVersionsEnabled          = cpvmEnabled,
                CentralPackageTransitivePinningEnabled = tdpEnabled,
            };
            var dgSpec = new DependencyGraphSpec();

            dgSpec.AddRestore("a");
            dgSpec.AddProject(packageSpec);
            return(dgSpec);
        }
        /// <summary>
        /// Create a dg file for the specs. Restore only the first one.
        /// </summary>
        public static DependencyGraphSpec GetDGSpec(params PackageSpec[] projects)
        {
            var dgSpec = new DependencyGraphSpec();

            var project = EnsureRestoreMetadata(projects.First());

            dgSpec.AddProject(project);
            dgSpec.AddRestore(project.RestoreMetadata.ProjectUniqueName);

            foreach (var child in projects.Skip(1))
            {
                dgSpec.AddProject(EnsureRestoreMetadata(child));
            }

            return(dgSpec);
        }
示例#15
0
        public async Task Cycle_ProjectWithSameNameAsProjectVerifyCycleDetected()
        {
            // Arrange
            using (var cacheContext = new SourceCacheContext())
                using (var pathContext = new SimpleTestPathContext())
                {
                    var logger  = new TestLogger();
                    var sources = new List <PackageSource>
                    {
                        new PackageSource(pathContext.PackageSource)
                    };

                    var spec1 = NETCoreRestoreTestUtility.GetProject(projectName: "projectA", framework: "netstandard1.6");
                    var spec2 = NETCoreRestoreTestUtility.GetProject(projectName: "projectA", framework: "netstandard1.6");

                    var specs = new[] { spec1, spec2 };

                    var projects = NETCoreRestoreTestUtility.CreateProjectsFromSpecs(pathContext, specs);

                    // Link projects
                    spec1.RestoreMetadata.TargetFrameworks.Single().ProjectReferences.Add(new ProjectRestoreReference()
                    {
                        ProjectPath       = projects[1].ProjectPath,
                        ProjectUniqueName = spec2.RestoreMetadata.ProjectUniqueName,
                    });

                    SimpleTestPackageUtility.CreateFolderFeedV2(pathContext.PackageSource, new PackageIdentity("projectA", NuGetVersion.Parse("1.0.0")));

                    // Create dg file
                    var dgFile = new DependencyGraphSpec();

                    // Only add projectA
                    dgFile.AddProject(spec1);
                    dgFile.AddRestore(spec1.RestoreMetadata.ProjectUniqueName);

                    dgFile.Save(Path.Combine(pathContext.WorkingDirectory, "out.dg"));

                    // Act
                    var summaries = await NETCoreRestoreTestUtility.RunRestore(pathContext, logger, sources, dgFile, cacheContext);

                    var success = summaries.All(s => s.Success);

                    // Assert
                    Assert.False(success, "Failed: " + string.Join(Environment.NewLine, logger.Messages));
                    Assert.Contains("Cycle detected", string.Join(Environment.NewLine, logger.ErrorMessages));
                }
        }
示例#16
0
        public async Task NETCoreProject2Project_ProjectMissing()
        {
            // Arrange
            using (var cacheContext = new SourceCacheContext())
                using (var pathContext = new SimpleTestPathContext())
                {
                    var logger  = new TestLogger();
                    var sources = new List <PackageSource>();
                    sources.Add(new PackageSource(pathContext.PackageSource));

                    var spec1 = NETCoreRestoreTestUtility.GetProject(projectName: "projectA", framework: "netstandard1.6");
                    var spec2 = NETCoreRestoreTestUtility.GetProject(projectName: "projectB", framework: "netstandard1.3");

                    var specs = new[] { spec1, spec2 };

                    // Create fake projects, the real data is in the specs
                    var projects = NETCoreRestoreTestUtility.CreateProjectsFromSpecs(pathContext, specs);

                    // Link projects
                    spec1.RestoreMetadata.TargetFrameworks.Single().ProjectReferences.Add(new ProjectRestoreReference()
                    {
                        ProjectPath       = projects[1].ProjectPath,
                        ProjectUniqueName = spec2.RestoreMetadata.ProjectUniqueName,
                    });

                    // Create dg file
                    var dgFile = new DependencyGraphSpec();

                    // Only add projectA
                    dgFile.AddProject(spec1);
                    dgFile.AddRestore(spec1.RestoreMetadata.ProjectUniqueName);

                    dgFile.Save(Path.Combine(pathContext.WorkingDirectory, "out.dg"));

                    // Act
                    var summaries = await NETCoreRestoreTestUtility.RunRestore(pathContext, logger, sources, dgFile, cacheContext);

                    var success = summaries.All(s => s.Success);

                    // Assert
                    Assert.False(success, "Failed: " + string.Join(Environment.NewLine, logger.Messages));
                    Assert.Contains("Unable to find project", string.Join(Environment.NewLine, logger.Messages));
                    Assert.Contains(projects[1].ProjectPath, string.Join(Environment.NewLine, logger.Messages));
                }
        }
示例#17
0
        public void AddProject_DoesNotClone(bool cpvmEnabled)
        {
            // Arrange
            var dependencyFoo = new LibraryDependency()
            {
                LibraryRange = new LibraryRange("foo", versionRange: cpvmEnabled ? null : VersionRange.Parse("1.0.0"), LibraryDependencyTarget.Package),
            };

            var centralVersions = cpvmEnabled
                ? new List <CentralPackageVersion>()
            {
                new CentralPackageVersion("foo", VersionRange.Parse("1.0.0"))
            }
                : new List <CentralPackageVersion>();

            var tfi = CreateTargetFrameworkInformation(
                new List <LibraryDependency>()
            {
                dependencyFoo
            },
                centralVersions);

            var packageSpec = new PackageSpec(new List <TargetFrameworkInformation>()
            {
                tfi
            });

            packageSpec.RestoreMetadata = new ProjectRestoreMetadata()
            {
                ProjectUniqueName             = "a",
                CentralPackageVersionsEnabled = cpvmEnabled
            };

            var dgSpec = new DependencyGraphSpec();

            dgSpec.AddRestore("a");
            dgSpec.AddProject(packageSpec);

            // Act
            var packageSpecFromDGSpec = dgSpec.GetProjectSpec("a");

            // Assert
            Assert.True(packageSpec.Equals(packageSpecFromDGSpec));
        }
        public void SpecValidationUtility_VerifyFrameworks_WithSameBase_DifferentAssetTargetFallback_Duplicates()
        {
            // Arrange
            var spec = new DependencyGraphSpec();

            spec.AddRestore("a");

            var targetFramework1 = new TargetFrameworkInformation()
            {
                FrameworkName = new AssetTargetFallbackFramework(CommonFrameworks.Net50, new List <NuGetFramework>()
                {
                    CommonFrameworks.Net463
                })
            };

            var targetFramework2 = new TargetFrameworkInformation()
            {
                FrameworkName = new AssetTargetFallbackFramework(CommonFrameworks.Net50, new List <NuGetFramework>()
                {
                    CommonFrameworks.Net462
                })
            };

            var info = new[] { targetFramework1, targetFramework2 };

            var project = new PackageSpec(info);

            project.RestoreMetadata = new ProjectRestoreMetadata();
            project.Name            = "a";
            project.FilePath        = Path.Combine(Directory.GetCurrentDirectory(), "a.csproj");
            project.RestoreMetadata.ProjectUniqueName = "a";
            project.RestoreMetadata.ProjectName       = "a";
            project.RestoreMetadata.ProjectPath       = Path.Combine(Directory.GetCurrentDirectory(), "a.csproj");
            project.RestoreMetadata.ProjectStyle      = ProjectStyle.ProjectJson;
            project.RestoreMetadata.ProjectJsonPath   = Path.Combine(Directory.GetCurrentDirectory(), "project.json");

            spec.AddProject(project);

            // Act && Assert
            AssertError(spec, "Duplicate frameworks found");
        }
示例#19
0
        private static DependencyGraphSpec ToDependencyGraphSpec(ProjectNames projectNames, IVsProjectRestoreInfo projectRestoreInfo, IVsProjectRestoreInfo2 projectRestoreInfo2)
        {
            var dgSpec = new DependencyGraphSpec();

            var packageSpec = projectRestoreInfo != null?
                              ToPackageSpec(projectNames, projectRestoreInfo.TargetFrameworks, projectRestoreInfo.OriginalTargetFrameworks, projectRestoreInfo.BaseIntermediatePath) :
                                  ToPackageSpec(projectNames, projectRestoreInfo2.TargetFrameworks, projectRestoreInfo2.OriginalTargetFrameworks, projectRestoreInfo2.BaseIntermediatePath);

            dgSpec.AddRestore(packageSpec.RestoreMetadata.ProjectUniqueName);
            dgSpec.AddProject(packageSpec);

            if (projectRestoreInfo != null && projectRestoreInfo.ToolReferences != null)
            {
                VSNominationUtilities.ProcessToolReferences(projectNames, projectRestoreInfo.TargetFrameworks, projectRestoreInfo.ToolReferences, dgSpec);
            }
            else if (projectRestoreInfo2 != null && projectRestoreInfo2.ToolReferences != null)
            {
                VSNominationUtilities.ProcessToolReferences(projectNames, projectRestoreInfo2.TargetFrameworks, projectRestoreInfo2.ToolReferences, dgSpec);
            }

            return(dgSpec);
        }
        public void SpecValidationUtility_VerifyFrameworks_Zero()
        {
            // Arrange
            var spec = new DependencyGraphSpec();

            spec.AddRestore("a");

            var project = new PackageSpec(new List <TargetFrameworkInformation>());

            project.RestoreMetadata = new ProjectRestoreMetadata();
            project.Name            = "a";
            project.FilePath        = Path.Combine(Directory.GetCurrentDirectory(), "a.csproj");
            project.RestoreMetadata.ProjectUniqueName = "a";
            project.RestoreMetadata.ProjectName       = "a";
            project.RestoreMetadata.ProjectPath       = Path.Combine(Directory.GetCurrentDirectory(), "a.csproj");
            project.RestoreMetadata.ProjectStyle      = ProjectStyle.ProjectJson;
            project.RestoreMetadata.ProjectJsonPath   = Path.Combine(Directory.GetCurrentDirectory(), "project.json");

            spec.AddProject(project);

            // Act && Assert
            AssertError(spec, "No target frameworks specified");
        }
        public void SpecValidationUtility_VerifyProjectMetadata_SameNameAsSpecName()
        {
            // Arrange
            var spec = new DependencyGraphSpec();

            spec.AddRestore("a");

            var targetFramework1 = new TargetFrameworkInformation()
            {
                FrameworkName = NuGetFramework.Parse("net45")
            };

            var info = new[] { targetFramework1 };

            var project = new PackageSpec(info)
            {
                RestoreMetadata = new ProjectRestoreMetadata(),
                Name            = "a",
                FilePath        = Path.Combine(Directory.GetCurrentDirectory(), "project.json")
            };

            project.RestoreMetadata.ProjectUniqueName = "some_other_path";
            project.RestoreMetadata.ProjectName       = "some_other_name";
            project.RestoreMetadata.ProjectPath       = Path.Combine(Directory.GetCurrentDirectory(), "a.csproj");
            project.RestoreMetadata.ProjectStyle      = ProjectStyle.Unknown;

            targetFramework1.Dependencies.Add(new LibraryDependency()
            {
                LibraryRange = new LibraryRange("x", VersionRange.Parse("1.0.0"), LibraryDependencyTarget.PackageProjectExternal)
            });

            spec.AddProject(project);

            // Act && Assert
            AssertError(spec, $"Properties '{nameof(project.Name)}':'{project.Name}' and '{nameof(project.RestoreMetadata.ProjectName)}':'{project.RestoreMetadata.ProjectName}' do not match.");
        }
        public static TestRestoreRequest CreateRestoreRequest(PackageSpec projectToRestore, IEnumerable <PackageSpec> packageSpecsClosure, SimpleTestPathContext pathContext, ILogger logger)
        {
            var sources = new List <PackageSource> {
                new PackageSource(pathContext.PackageSource)
            };
            var dgSpec = new DependencyGraphSpec();

            dgSpec.AddProject(projectToRestore);
            dgSpec.AddRestore(projectToRestore.RestoreMetadata.ProjectUniqueName);

            foreach (var spec in packageSpecsClosure)
            {
                dgSpec.AddProject(spec);
            }

            var externalClosure = DependencyGraphSpecRequestProvider.GetExternalClosure(dgSpec, projectToRestore.RestoreMetadata.ProjectUniqueName).ToList();

            return(new TestRestoreRequest(projectToRestore, sources, pathContext.UserPackagesFolder, logger)
            {
                LockFilePath = Path.Combine(projectToRestore.FilePath, LockFileFormat.AssetsFileName),
                DependencyGraphSpec = dgSpec,
                ExternalProjects = externalClosure,
            });
        }
        public void GetParents_WhenOnlyRootSpecsAreDirty_ReturnsOnlyTheSameDirtyProjects()
        {
            var projectA = GetPackageSpec("A");
            var projectB = GetPackageSpec("B");
            var projectC = GetPackageSpec("C");
            var projectD = GetPackageSpec("D");
            var projectE = GetPackageSpec("E");
            var projectF = GetPackageSpec("F");

            // A => B & C
            projectA = projectA.WithTestProjectReference(projectB).WithTestProjectReference(projectC);
            // B => D
            projectB = projectB.WithTestProjectReference(projectD);
            // C => E
            projectC = projectC.WithTestProjectReference(projectE);
            // F => D
            projectF = projectF.WithTestProjectReference(projectD);

            var dgSpec = new DependencyGraphSpec();

            dgSpec.AddProject(projectA);
            dgSpec.AddRestore(projectA.RestoreMetadata.ProjectUniqueName);
            dgSpec.AddProject(projectB);
            dgSpec.AddRestore(projectB.RestoreMetadata.ProjectUniqueName);
            dgSpec.AddProject(projectC);
            dgSpec.AddRestore(projectC.RestoreMetadata.ProjectUniqueName);
            dgSpec.AddProject(projectD);
            dgSpec.AddRestore(projectD.RestoreMetadata.ProjectUniqueName);
            dgSpec.AddProject(projectE);
            dgSpec.AddRestore(projectE.RestoreMetadata.ProjectUniqueName);
            dgSpec.AddProject(projectF);
            dgSpec.AddRestore(projectF.RestoreMetadata.ProjectUniqueName);

            var expected = GetUniqueNames(projectA, projectF);
            var actual   = SolutionUpToDateChecker.GetParents(GetUniqueNames(projectA, projectF), dgSpec);

            actual.Should().BeEquivalentTo(expected);
        }
示例#24
0
        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, false);
                    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();
                }
        }
示例#25
0
        public void IsLockFileStillValid_TransitiveDependencyNotCentrallyManaged_DoesNotInvalidateLockFile()
        {
            // Arrange
            var framework   = CommonFrameworks.NetStandard20;
            var projectName = "project";
            var cpvm1       = new CentralPackageVersion("cpvm1", VersionRange.Parse("1.0.0"));
            var cpvm2       = new CentralPackageVersion("cpvm2", VersionRange.Parse("1.0.0"));
            var dependency1 = new LibraryDependency(
                new LibraryRange("cpvm1", versionRange: null, LibraryDependencyTarget.Package),
                LibraryDependencyType.Default,
                LibraryIncludeFlags.All,
                LibraryIncludeFlags.All,
                new List <Common.NuGetLogCode>(),
                autoReferenced: false,
                generatePathProperty: true,
                versionCentrallyManaged: false,
                LibraryDependencyReferenceType.Direct,
                aliases: "stuff");

            var tfm = new TargetFrameworkInformation();

            tfm.FrameworkName = framework;
            tfm.CentralPackageVersions.Add("cpvm1", cpvm1);
            tfm.CentralPackageVersions.Add("cpvm2", cpvm2);
            tfm.Dependencies.Add(dependency1);
            LibraryDependency.ApplyCentralVersionInformation(tfm.Dependencies, tfm.CentralPackageVersions);

            var project = new PackageSpec(new List <TargetFrameworkInformation>()
            {
                tfm
            });

            project.RestoreMetadata = new ProjectRestoreMetadata()
            {
                ProjectUniqueName = projectName, CentralPackageVersionsEnabled = true
            };

            DependencyGraphSpec dgSpec = new DependencyGraphSpec();

            dgSpec.AddRestore(projectName);
            dgSpec.AddProject(project);

            var lockFile1 = new PackagesLockFileBuilder()
                            .WithTarget(target => target
                                        .WithFramework(CommonFrameworks.NetStandard20)
                                        .WithDependency(dep => dep
                                                        .WithId("cpvm1")
                                                        .WithRequestedVersion(VersionRange.Parse("1.0.0"))
                                                        .WithType(PackageDependencyType.Direct))
                                        .WithDependency(dep => dep
                                                        .WithId("otherDep")
                                                        .WithRequestedVersion(VersionRange.Parse("1.0.0"))
                                                        .WithType(PackageDependencyType.Transitive)))
                            .Build();

            var lockFile2 = new PackagesLockFileBuilder()
                            .WithVersion(PackagesLockFileFormat.PackagesLockFileVersion)
                            .WithTarget(target => target
                                        .WithFramework(CommonFrameworks.NetStandard20)
                                        .WithDependency(dep => dep
                                                        .WithId("cpvm1")
                                                        .WithRequestedVersion(VersionRange.Parse("1.0.0"))
                                                        .WithType(PackageDependencyType.Direct))
                                        .WithDependency(dep => dep
                                                        .WithId("otherDep")
                                                        .WithRequestedVersion(VersionRange.Parse("1.0.0"))
                                                        .WithType(PackageDependencyType.Transitive)))
                            .Build();

            // Nothing changed
            // different versions of lock file versions are handled
            Assert.True(PackagesLockFileUtilities.IsLockFileStillValid(dgSpec, lockFile1));
            Assert.True(PackagesLockFileUtilities.IsLockFileStillValid(dgSpec, lockFile2));
        }
        /// <summary>
        /// Gets a <see cref="DependencyGraphSpec" /> for the specified project.
        /// </summary>
        /// <param name="entryProjectPath">The full path to a project or Visual Studio Solution File.</param>
        /// <param name="globalProperties">An <see cref="IDictionary{String,String}" /> containing the global properties to use when evaluation MSBuild projects.</param>
        /// <returns>A <see cref="DependencyGraphSpec" /> for the specified project if they could be loaded, otherwise <code>null</code>.</returns>
        private DependencyGraphSpec GetDependencyGraphSpec(string entryProjectPath, IDictionary <string, string> globalProperties)
        {
            try
            {
                // TODO: Use a localized resource from https://github.com/NuGet/NuGet.Client/pull/3111
                MSBuildLogger.LogMinimal("Determining projects to restore...");

                var entryProjects = GetProjectGraphEntryPoints(entryProjectPath, globalProperties);

                // Load the projects via MSBuild and create an array of them since Parallel.ForEach is optimized for arrays
                var projects = LoadProjects(entryProjects)?.ToArray();

                // If no projects were loaded, return null indicating that the projects could not be loaded.
                if (projects == null || projects.Length == 0)
                {
                    return(null);
                }

                var sw = Stopwatch.StartNew();

                var dependencyGraphSpec = new DependencyGraphSpec(isReadOnly: true);

                // Unique names created by the MSBuild restore target are project paths, these
                // can be different on case-insensitive file systems for the same project file.
                // To workaround this unique names should be compared based on the OS.
                var uniqueNameComparer = PathUtility.GetStringComparerBasedOnOS();
                var projectPathLookup  = new ConcurrentDictionary <string, string>(uniqueNameComparer);

                try
                {
                    // Get the PackageSpecs in parallel because creating each one is relatively expensive so parallelism speeds things up
                    Parallel.ForEach(projects, new ParallelOptions {
                        MaxDegreeOfParallelism = Environment.ProcessorCount
                    }, project =>
                    {
                        var packageSpec = GetPackageSpec(project.OuterProject, project);

                        if (packageSpec != null)
                        {
                            // Keep track of all project path casings
                            var uniqueName = packageSpec.RestoreMetadata.ProjectUniqueName;
                            if (uniqueName != null && !projectPathLookup.ContainsKey(uniqueName))
                            {
                                projectPathLookup.TryAdd(uniqueName, uniqueName);
                            }

                            var projectPath = packageSpec.RestoreMetadata.ProjectPath;
                            if (projectPath != null && !projectPathLookup.ContainsKey(projectPath))
                            {
                                projectPathLookup.TryAdd(projectPath, projectPath);
                            }

                            // TODO: Remove this lock once https://github.com/NuGet/Home/issues/9002 is fixed
                            lock (dependencyGraphSpec)
                            {
                                dependencyGraphSpec.AddProject(packageSpec);
                            }
                        }
                    });
                }
                catch (AggregateException e)
                {
                    // Log exceptions thrown while creating PackageSpec objects
                    foreach (var exception in e.Flatten().InnerExceptions)
                    {
                        LoggingQueue.TaskLoggingHelper.LogErrorFromException(exception);
                    }

                    return(null);
                }

                // Fix project reference casings to match the original project on case insensitive file systems.
                MSBuildRestoreUtility.NormalizePathCasings(projectPathLookup, dependencyGraphSpec);

                // Add all entry projects if they support restore.  In most cases this is just a single project but if the entry
                // project is a solution, then all projects in the solution are added (if they support restore)
                foreach (var entryPoint in entryProjects)
                {
                    PackageSpec project = dependencyGraphSpec.GetProjectSpec(entryPoint.ProjectFile);

                    if (project != null && BuildTasksUtility.DoesProjectSupportRestore(project))
                    {
                        dependencyGraphSpec.AddRestore(entryPoint.ProjectFile);
                    }
                }

                sw.Stop();

                MSBuildLogger.LogDebug(string.Format(CultureInfo.CurrentCulture, Strings.CreatedDependencyGraphSpec, sw.ElapsedMilliseconds));

                return(dependencyGraphSpec);
            }
            catch (Exception e)
            {
                LoggingQueue.TaskLoggingHelper.LogErrorFromException(e, showStackTrace: true);
            }

            return(null);
        }
        public static async Task <(DependencyGraphSpec dgSpec, IReadOnlyList <IAssetsLogMessage> additionalMessages)> GetSolutionRestoreSpecAndAdditionalMessages(
            ISolutionManager solutionManager,
            DependencyGraphCacheContext context)
        {
            var dgSpec = new DependencyGraphSpec();
            List <IAssetsLogMessage> allAdditionalMessages = null;

            var projects      = (await solutionManager.GetNuGetProjectsAsync()).OfType <IDependencyGraphProject>().ToList();
            var knownProjects = projects.Select(e => e.MSBuildProjectPath).ToHashSet(PathUtility.GetStringComparerBasedOnOS());

            for (var i = 0; i < projects.Count; i++)
            {
                var(packageSpecs, projectAdditionalMessages) = await projects[i].GetPackageSpecsAndAdditionalMessagesAsync(context);

                if (projectAdditionalMessages != null && projectAdditionalMessages.Count > 0)
                {
                    if (allAdditionalMessages == null)
                    {
                        allAdditionalMessages = new List <IAssetsLogMessage>();
                    }

                    allAdditionalMessages.AddRange(projectAdditionalMessages);
                }

                foreach (var packageSpec in packageSpecs)
                {
                    dgSpec.AddProject(packageSpec);

                    if (packageSpec.RestoreMetadata.ProjectStyle == ProjectStyle.PackageReference ||
                        packageSpec.RestoreMetadata.ProjectStyle == ProjectStyle.ProjectJson ||
                        packageSpec.RestoreMetadata.ProjectStyle == ProjectStyle.DotnetCliTool ||
                        packageSpec.RestoreMetadata.ProjectStyle == ProjectStyle.Standalone) // Don't add global tools to restore specs for solutions
                    {
                        dgSpec.AddRestore(packageSpec.RestoreMetadata.ProjectUniqueName);

                        var projFileName = Path.GetFileName(packageSpec.RestoreMetadata.ProjectPath);
                        var dgFileName   = DependencyGraphSpec.GetDGSpecFileName(projFileName);
                        var outputPath   = packageSpec.RestoreMetadata.OutputPath;

                        if (!string.IsNullOrEmpty(outputPath))
                        {
                            for (int frameworkCount = 0; frameworkCount < packageSpec.RestoreMetadata.TargetFrameworks.Count; frameworkCount++)
                            {
                                for (var projectReferenceCount = 0; projectReferenceCount < packageSpec.RestoreMetadata.TargetFrameworks[frameworkCount].ProjectReferences.Count; projectReferenceCount++)
                                {
                                    if (!knownProjects.Contains(packageSpec.RestoreMetadata.TargetFrameworks[frameworkCount].ProjectReferences[projectReferenceCount].ProjectPath))
                                    {
                                        var persistedDGSpecPath = Path.Combine(outputPath, dgFileName);
                                        if (File.Exists(persistedDGSpecPath))
                                        {
                                            var persistedDGSpec = DependencyGraphSpec.Load(persistedDGSpecPath);
                                            foreach (var dependentPackageSpec in persistedDGSpec.Projects.Where(e => !knownProjects.Contains(e.RestoreMetadata.ProjectPath)))
                                            {
                                                // Include all the missing projects from the closure.
                                                // Figuring out exactly what we need would be too and an overkill. That will happen later in the DependencyGraphSpecRequestProvider
                                                knownProjects.Add(dependentPackageSpec.RestoreMetadata.ProjectPath);
                                                dgSpec.AddProject(dependentPackageSpec);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            // Return dg file
            return(dgSpec, allAdditionalMessages);
        }
示例#28
0
        /// <summary>
        /// Fetch, if not already downloaded, and install the package represented by
        /// (<paramref name="packageId"/>, <paramref name="version"/>).
        /// </summary>
        /// <remarks>It is safe to call it concurrently be cause we operations are done using the FileLock.</remarks>
        /// <param name="packageId">Name of package to install.</param>
        /// <param name="version">Version of package to install.</param>
        public async Task <NugetLocalPackage> InstallPackage(string packageId, PackageVersion version, IEnumerable <string> targetFrameworks, ProgressReport progress)
        {
            using (GetLocalRepositoryLock())
            {
                currentProgressReport = progress;
                try
                {
                    var identity = new PackageIdentity(packageId, version.ToNuGetVersion());

                    var resolutionContext = new ResolutionContext(
                        DependencyBehavior.Lowest,
                        true,
                        true,
                        VersionConstraints.None);

                    var repositories = PackageSources.Select(sourceRepositoryProvider.CreateRepository).ToArray();

                    var projectContext = new EmptyNuGetProjectContext()
                    {
                        ActionType = NuGetActionType.Install,
                        PackageExtractionContext = new PackageExtractionContext(PackageSaveMode.Defaultv3, XmlDocFileSaveMode.Skip, null, NativeLogger),
                    };

                    ActivityCorrelationId.StartNew();

                    {
                        var installPath = SettingsUtility.GetGlobalPackagesFolder(settings);

                        // In case it's a package without any TFM (i.e. Visual Studio plugin), we still need to specify one
                        if (!targetFrameworks.Any())
                        {
                            targetFrameworks = new string[] { "net6.0" }
                        }
                        ;

                        // Old version expects to be installed in GamePackages
                        if (packageId == "Xenko" && version < new PackageVersion(3, 0, 0, 0) && oldRootDirectory != null)
                        {
                            installPath = oldRootDirectory;
                        }

                        var projectPath = Path.Combine("StrideLauncher.json");
                        var spec        = new PackageSpec()
                        {
                            Name         = Path.GetFileNameWithoutExtension(projectPath), // make sure this package never collides with a dependency
                            FilePath     = projectPath,
                            Dependencies = new List <LibraryDependency>()
                            {
                                new LibraryDependency
                                {
                                    LibraryRange = new LibraryRange(packageId, new VersionRange(version.ToNuGetVersion()), LibraryDependencyTarget.Package),
                                }
                            },
                            RestoreMetadata = new ProjectRestoreMetadata
                            {
                                ProjectPath              = projectPath,
                                ProjectName              = Path.GetFileNameWithoutExtension(projectPath),
                                ProjectStyle             = ProjectStyle.PackageReference,
                                ProjectUniqueName        = projectPath,
                                OutputPath               = Path.Combine(Path.GetTempPath(), $"StrideLauncher-{packageId}-{version.ToString()}"),
                                OriginalTargetFrameworks = targetFrameworks.ToList(),
                                ConfigFilePaths          = settings.GetConfigFilePaths(),
                                PackagesPath             = installPath,
                                Sources         = SettingsUtility.GetEnabledSources(settings).ToList(),
                                FallbackFolders = SettingsUtility.GetFallbackPackageFolders(settings).ToList()
                            },
                        };
                        foreach (var targetFramework in targetFrameworks)
                        {
                            spec.TargetFrameworks.Add(new TargetFrameworkInformation {
                                FrameworkName = NuGetFramework.Parse(targetFramework)
                            });
                        }

                        using (var context = new SourceCacheContext {
                            MaxAge = DateTimeOffset.UtcNow
                        })
                        {
                            context.IgnoreFailedSources = true;

                            var dependencyGraphSpec = new DependencyGraphSpec();

                            dependencyGraphSpec.AddProject(spec);

                            dependencyGraphSpec.AddRestore(spec.RestoreMetadata.ProjectUniqueName);

                            IPreLoadedRestoreRequestProvider requestProvider = new DependencyGraphSpecRequestProvider(new RestoreCommandProvidersCache(), dependencyGraphSpec);

                            var restoreArgs = new RestoreArgs
                            {
                                AllowNoOp             = true,
                                CacheContext          = context,
                                CachingSourceProvider = new CachingSourceProvider(new PackageSourceProvider(settings)),
                                Log = NativeLogger,
                            };

                            // Create requests from the arguments
                            var requests = requestProvider.CreateRequests(restoreArgs).Result;

                            foreach (var request in requests)
                            {
                                // Limit concurrency to avoid timeout
                                request.Request.MaxDegreeOfConcurrency = 4;

                                var command = new RestoreCommand(request.Request);

                                // Act
                                var result = await command.ExecuteAsync();

                                if (!result.Success)
                                {
                                    throw new InvalidOperationException($"Could not restore package {packageId}");
                                }
                                foreach (var install in result.RestoreGraphs.Last().Install)
                                {
                                    var package = result.LockFile.Libraries.FirstOrDefault(x => x.Name == install.Library.Name && x.Version == install.Library.Version);
                                    if (package != null)
                                    {
                                        var packagePath = Path.Combine(installPath, package.Path);
                                        OnPackageInstalled(this, new PackageOperationEventArgs(new PackageName(install.Library.Name, install.Library.Version.ToPackageVersion()), packagePath));
                                    }
                                }
                            }
                        }

                        if (packageId == "Xenko" && version < new PackageVersion(3, 0, 0, 0))
                        {
                            UpdateTargetsHelper();
                        }
                    }

                    // Load the recently installed package
                    var installedPackages = GetPackagesInstalled(new[] { packageId });
                    return(installedPackages.FirstOrDefault(p => p.Version == version));
                }
                finally
                {
                    currentProgressReport = null;
                }
            }
        }
        /// <summary>
        /// Convert MSBuild items to a DependencyGraphSpec.
        /// </summary>
        public static DependencyGraphSpec GetDependencySpec(IEnumerable <IMSBuildItem> items)
        {
            if (items == null)
            {
                throw new ArgumentNullException(nameof(items));
            }

            // Unique names created by the MSBuild restore target are project paths, these
            // can be different on case-insensitive file systems for the same project file.
            // To workaround this unique names should be compared based on the OS.
            var uniqueNameComparer = PathUtility.GetStringComparerBasedOnOS();

            var graphSpec         = new DependencyGraphSpec();
            var itemsById         = new Dictionary <string, List <IMSBuildItem> >(uniqueNameComparer);
            var restoreSpecs      = new HashSet <string>(uniqueNameComparer);
            var validForRestore   = new HashSet <string>(uniqueNameComparer);
            var projectPathLookup = new Dictionary <string, string>(uniqueNameComparer);
            var toolItems         = new List <IMSBuildItem>();

            // Sort items and add restore specs
            foreach (var item in items)
            {
                var projectUniqueName = item.GetProperty("ProjectUniqueName");

                if (item.IsType("restorespec"))
                {
                    restoreSpecs.Add(projectUniqueName);
                }
                else if (!string.IsNullOrEmpty(projectUniqueName))
                {
                    List <IMSBuildItem> idItems;
                    if (!itemsById.TryGetValue(projectUniqueName, out idItems))
                    {
                        idItems = new List <IMSBuildItem>(1);
                        itemsById.Add(projectUniqueName, idItems);
                    }

                    idItems.Add(item);
                }
            }

            // Add projects
            var validProjectSpecs = itemsById.Values.Select(GetPackageSpec).Where(e => e != null);

            foreach (var spec in validProjectSpecs)
            {
                // Keep track of all project path casings
                var uniqueName = spec.RestoreMetadata.ProjectUniqueName;
                if (uniqueName != null && !projectPathLookup.ContainsKey(uniqueName))
                {
                    projectPathLookup.Add(uniqueName, uniqueName);
                }

                var projectPath = spec.RestoreMetadata.ProjectPath;
                if (projectPath != null && !projectPathLookup.ContainsKey(projectPath))
                {
                    projectPathLookup.Add(projectPath, projectPath);
                }

                if (spec.RestoreMetadata.ProjectStyle == ProjectStyle.PackageReference ||
                    spec.RestoreMetadata.ProjectStyle == ProjectStyle.ProjectJson ||
                    spec.RestoreMetadata.ProjectStyle == ProjectStyle.DotnetCliTool ||
                    spec.RestoreMetadata.ProjectStyle == ProjectStyle.Standalone ||
                    spec.RestoreMetadata.ProjectStyle == ProjectStyle.DotnetToolReference)
                {
                    validForRestore.Add(spec.RestoreMetadata.ProjectUniqueName);
                }

                graphSpec.AddProject(spec);
            }

            // Fix project reference casings to match the original project on case insensitive file systems.
            NormalizePathCasings(projectPathLookup, graphSpec);

            // Remove references to projects that could not be read by restore.
            RemoveMissingProjects(graphSpec);

            // Add valid projects to restore section
            foreach (var projectUniqueName in restoreSpecs.Intersect(validForRestore))
            {
                graphSpec.AddRestore(projectUniqueName);
            }

            return(graphSpec);
        }
示例#30
0
        public static async Task <(RestoreRequest, RestoreResult)> Restore(ILogger logger, string packageName, VersionRange versionRange)
        {
            var settings = NuGet.Configuration.Settings.LoadDefaultSettings(null);
            var packageSourceProvider = new PackageSourceProvider(settings);
            var installPath           = SettingsUtility.GetGlobalPackagesFolder(settings);
            var assemblies            = new List <string>();

            var projectPath = Path.Combine("XenkoNugetResolver.json");
            var spec        = new PackageSpec()
            {
                Name         = Path.GetFileNameWithoutExtension(projectPath), // make sure this package never collides with a dependency
                FilePath     = projectPath,
                Dependencies = new List <LibraryDependency>()
                {
                    new LibraryDependency
                    {
                        LibraryRange = new LibraryRange(packageName, versionRange, LibraryDependencyTarget.Package),
                    }
                },
                TargetFrameworks =
                {
                    new TargetFrameworkInformation
                    {
                        FrameworkName = NuGetFramework.Parse("net48"),
                    }
                },
                RestoreMetadata = new ProjectRestoreMetadata
                {
                    ProjectPath              = projectPath,
                    ProjectName              = Path.GetFileNameWithoutExtension(projectPath),
                    ProjectStyle             = ProjectStyle.PackageReference,
                    ProjectUniqueName        = projectPath,
                    OutputPath               = Path.Combine(Path.GetTempPath(), $"XenkoNugetResolver-{packageName}-{versionRange.MinVersion.ToString()}"),
                    OriginalTargetFrameworks = new[] { "net48" },
                    ConfigFilePaths          = settings.GetConfigFilePaths(),
                    PackagesPath             = SettingsUtility.GetGlobalPackagesFolder(settings),
                    Sources         = SettingsUtility.GetEnabledSources(settings).ToList(),
                    FallbackFolders = SettingsUtility.GetFallbackPackageFolders(settings).ToList()
                },
            };

            // remove all remote sources, so we don't have to worry about connectivity issues
            // we are only restoring local dev packages anyway
            for (int i = 0; i < spec.RestoreMetadata.Sources.Count; i++)
            {
                var s = spec.RestoreMetadata.Sources[i];
                if (s.IsLocal == false)
                {
                    spec.RestoreMetadata.Sources.RemoveAt(i);
                    i--;
                }
            }

            using (var context = new SourceCacheContext())
            {
                context.IgnoreFailedSources = true;

                var dependencyGraphSpec = new DependencyGraphSpec();

                dependencyGraphSpec.AddProject(spec);

                dependencyGraphSpec.AddRestore(spec.RestoreMetadata.ProjectUniqueName);

                IPreLoadedRestoreRequestProvider requestProvider = new DependencyGraphSpecRequestProvider(new RestoreCommandProvidersCache(), dependencyGraphSpec);

                var restoreArgs = new RestoreArgs
                {
                    AllowNoOp             = true,
                    CacheContext          = context,
                    CachingSourceProvider = new CachingSourceProvider(new PackageSourceProvider(settings)),
                    Log = logger,
                };

                // Create requests from the arguments
                var requests = requestProvider.CreateRequests(restoreArgs).Result;

                // Restore the packages
                for (int tryCount = 0; tryCount < 2; ++tryCount)
                {
                    try
                    {
                        var results = await RestoreRunner.RunWithoutCommit(requests, restoreArgs);

                        // Commit results so that noop cache works next time
                        foreach (var result in results)
                        {
                            await result.Result.CommitAsync(logger, CancellationToken.None);
                        }
                        var mainResult = results.First();
                        return(mainResult.SummaryRequest.Request, mainResult.Result);
                    }
                    catch (Exception e) when(e is UnauthorizedAccessException || e is IOException)
                    {
                        // If we have an unauthorized access exception, it means assemblies are locked by running Xenko process
                        // During first try, kill some known harmless processes, and try again
                        if (tryCount == 1)
                        {
                            throw;
                        }

                        foreach (var process in new[] { "Xenko.ConnectionRouter" }.SelectMany(Process.GetProcessesByName))
                        {
                            try
                            {
                                if (process.Id != Process.GetCurrentProcess().Id)
                                {
                                    process.Kill();
                                    process.WaitForExit();
                                }
                            }
                            catch (Exception)
                            {
                            }
                        }
                    }
                }

                throw new InvalidOperationException("Unreachable code");
            }
        }