public async Task InstallingPackageShouldCreateLockFile_CustomLockFileName()
        {
            // Arrange
            using (var packageSource = TestDirectory.Create())
                using (var testSolutionManager = new TestSolutionManager())
                {
                    var sourceRepositoryProvider = TestSourceRepositoryUtility.CreateSourceRepositoryProvider(
                        new List <PackageSource>()
                    {
                        new PackageSource(packageSource.Path)
                    });

                    var testSettings           = NullSettings.Instance;
                    var token                  = CancellationToken.None;
                    var deleteOnRestartManager = new TestDeleteOnRestartManager();
                    var nuGetPackageManager    = new NuGetPackageManager(
                        sourceRepositoryProvider,
                        testSettings,
                        testSolutionManager,
                        deleteOnRestartManager);
                    var packagesFolderPath = PackagesFolderPathUtility.GetPackagesFolderPath(testSolutionManager, testSettings);

                    var packageContext = new SimpleTestPackageContext("packageA");
                    packageContext.AddFile("lib/net45/a.dll");
                    SimpleTestPackageUtility.CreateOPCPackage(packageContext, packageSource);

                    var msBuildNuGetProject       = testSolutionManager.AddNewMSBuildProject();
                    var msBuildNuGetProjectSystem = msBuildNuGetProject.ProjectSystem as TestMSBuildNuGetProjectSystem;
                    msBuildNuGetProjectSystem.SetPropertyValue("RestorePackagesWithLockFile", "true");
                    msBuildNuGetProjectSystem.SetPropertyValue("NuGetLockFilePath", "my.lock.json");
                    var packagesConfigPath = msBuildNuGetProject.PackagesConfigNuGetProject.FullPath;
                    var packagesLockPath   = packagesConfigPath.Replace("packages.config", "my.lock.json");
                    var packageIdentity    = packageContext.Identity;

                    // Pre-Assert
                    // Check that the packages.lock.json file does not exist
                    Assert.False(File.Exists(packagesLockPath));

                    // Act
                    await nuGetPackageManager.InstallPackageAsync(msBuildNuGetProject, packageIdentity,
                                                                  new ResolutionContext(), new TestNuGetProjectContext(), sourceRepositoryProvider.GetRepositories().First(), null, token);

                    // Assert
                    // Check that the packages.lock.json file exists after the installation
                    Assert.True(File.Exists(packagesLockPath));
                    Assert.True(msBuildNuGetProjectSystem.FileExistsInProject("my.lock.json"));
                    // Check the number of target frameworks and dependencies in the lock file
                    var lockFile = PackagesLockFileFormat.Read(packagesLockPath);
                    Assert.Equal(1, lockFile.Targets.Count);
                    Assert.Equal(1, lockFile.Targets[0].Dependencies.Count);
                }
        }
        public async Task Restore_LegacyPackageReference_WithNuGetLockFile()
        {
            // Arrange
            using (var pathContext = new SimpleTestPathContext())
            {
                // Set up solution, project, and packages
                var solution = new SimpleTestSolutionContext(pathContext.SolutionRoot);

                var net461 = NuGetFramework.Parse("net461");

                var projectA = SimpleTestProjectContext.CreateLegacyPackageReference(
                    "a",
                    pathContext.SolutionRoot,
                    net461);

                projectA.Properties.Add("RestorePackagesWithLockFile", "true");

                var packageX = new SimpleTestPackageContext()
                {
                    Id      = "x",
                    Version = "1.0.0"
                };
                packageX.Files.Clear();
                packageX.AddFile("lib/net461/a.dll");

                projectA.AddPackageToAllFrameworks(packageX);
                solution.Projects.Add(projectA);
                solution.Create(pathContext.SolutionRoot);

                await SimpleTestPackageUtility.CreateFolderFeedV3Async(
                    pathContext.PackageSource,
                    PackageSaveMode.Defaultv3,
                    packageX);

                // Act
                var result = RunRestore(pathContext);

                // Assert
                Assert.True(File.Exists(projectA.NuGetLockFileOutputPath));

                var lockFile = PackagesLockFileFormat.Read(projectA.NuGetLockFileOutputPath);
                Assert.Equal(4, lockFile.Targets.Count);

                var targets = lockFile.Targets.Where(t => t.Dependencies.Count > 0).ToList();
                Assert.Equal(1, targets.Count);
                Assert.Equal(".NETFramework,Version=v4.6.1", targets[0].Name);
                Assert.Equal(1, targets[0].Dependencies.Count);
                Assert.Equal("x", targets[0].Dependencies[0].Id);
            }
        }
        internal static PackagesLockFile GetLockFile(bool lockFileExists, string lockFileName)
        {
            PackagesLockFile lockFile;

            if (lockFileExists)
            {
                lockFile         = PackagesLockFileFormat.Read(lockFileName);
                lockFile.Version = PackagesLockFileFormat.Version;
                if (lockFile.Targets.Count == 0)
                {
                    lockFile.Targets.Add(new PackagesLockFileTarget());
                }
                else if (lockFile.Targets.Count > 1)
                {
                    // merge lists
                    while (lockFile.Targets.Count > 1)
                    {
                        var target = lockFile.Targets[1];

                        for (var i = 0; i < target.Dependencies.Count; i++)
                        {
                            lockFile.Targets[0].Dependencies.Add(target.Dependencies[i]);
                        }

                        lockFile.Targets.RemoveAt(1);
                    }
                }
            }
            else
            {
                lockFile = new PackagesLockFile();
                lockFile.Targets.Add(new PackagesLockFileTarget());
            }

            return(lockFile);
        }
        public async void DependencyGraphRestoreUtility_LegacyPackageRef_Restore_UpdateLockFile()
        {
            using (var packageSource = TestDirectory.Create())
            {
                // Arrange
                var sourceRepositoryProvider = TestSourceRepositoryUtility.CreateSourceRepositoryProvider(
                    new List <Configuration.PackageSource>()
                {
                    new Configuration.PackageSource(packageSource.Path)
                });

                using (var testSolutionManager = new TestSolutionManager(true))
                    using (var randomProjectFolderPath = TestDirectory.Create())
                    {
                        var testSettings            = PopulateSettingsWithSources(sourceRepositoryProvider, randomProjectFolderPath);
                        var testNuGetProjectContext = new TestNuGetProjectContext();
                        var deleteOnRestartManager  = new TestDeleteOnRestartManager();
                        var nuGetPackageManager     = new NuGetPackageManager(
                            sourceRepositoryProvider,
                            testSettings,
                            testSolutionManager,
                            deleteOnRestartManager);

                        var projectTargetFrameworkStr = "net45";
                        var fullProjectPath           = Path.Combine(randomProjectFolderPath, "project1.csproj");
                        var projectLockFilePath       = Path.Combine(randomProjectFolderPath, "packages.custom.lock.json");
                        File.Create(projectLockFilePath).Close();

                        var projectNames = new ProjectNames(
                            fullName: fullProjectPath,
                            uniqueName: Path.GetFileName(fullProjectPath),
                            shortName: Path.GetFileNameWithoutExtension(fullProjectPath),
                            customUniqueName: Path.GetFileName(fullProjectPath));
                        var vsProjectAdapter = new TestVSProjectAdapter(
                            fullProjectPath,
                            projectNames,
                            projectTargetFrameworkStr,
                            restorePackagesWithLockFile: null,
                            nuGetLockFilePath: projectLockFilePath);

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

                        var legacyPRProject = new LegacyPackageReferenceProject(
                            vsProjectAdapter,
                            Guid.NewGuid().ToString(),
                            projectServices,
                            _threadingService);
                        testSolutionManager.NuGetProjects.Add(legacyPRProject);

                        var testLogger     = new TestLogger();
                        var restoreContext = new DependencyGraphCacheContext(testLogger, testSettings);

                        var packageContextA = new SimpleTestPackageContext("packageA", "1.0.0");
                        packageContextA.AddFile("lib/net45/a.dll");
                        SimpleTestPackageUtility.CreateOPCPackage(packageContextA, packageSource);
                        var packageContextB = new SimpleTestPackageContext("packageB", "1.0.0");
                        packageContextB.AddFile("lib/net45/b.dll");
                        SimpleTestPackageUtility.CreateOPCPackage(packageContextB, packageSource);

                        var dgSpec = await DependencyGraphRestoreUtility.GetSolutionRestoreSpec(testSolutionManager, restoreContext);

                        var restoreSummaries = await DependencyGraphRestoreUtility.RestoreAsync(
                            testSolutionManager,
                            dgSpec,
                            restoreContext,
                            new RestoreCommandProvidersCache(),
                            (c) => { },
                            sourceRepositoryProvider.GetRepositories(),
                            Guid.Empty,
                            false,
                            true,
                            testLogger,
                            CancellationToken.None);

                        foreach (var restoreSummary in restoreSummaries)
                        {
                            Assert.True(restoreSummary.Success);
                            Assert.False(restoreSummary.NoOpRestore);
                        }

                        Assert.True(File.Exists(projectLockFilePath));
                        Assert.True(File.Exists(Path.Combine(vsProjectAdapter.MSBuildProjectExtensionsPath, "project.assets.json")));

                        // delete existing restore output files
                        File.Delete(Path.Combine(vsProjectAdapter.MSBuildProjectExtensionsPath, "project.assets.json"));

                        // install a new package
                        projectServices.SetupInstalledPackages(
                            NuGetFramework.Parse(projectTargetFrameworkStr),
                            new LibraryDependency
                        {
                            LibraryRange = new LibraryRange(
                                "packageA",
                                VersionRange.Parse("1.*"),
                                LibraryDependencyTarget.Package)
                        },
                            new LibraryDependency
                        {
                            LibraryRange = new LibraryRange(
                                "packageB",
                                VersionRange.Parse("1.0.0"),
                                LibraryDependencyTarget.Package)
                        });

                        // update the proeject with new ProjectService instance
                        restoreContext.PackageSpecCache.Clear();
                        dgSpec = await DependencyGraphRestoreUtility.GetSolutionRestoreSpec(testSolutionManager, restoreContext);

                        // Act
                        restoreSummaries = await DependencyGraphRestoreUtility.RestoreAsync(
                            testSolutionManager,
                            dgSpec,
                            restoreContext,
                            new RestoreCommandProvidersCache(),
                            (c) => { },
                            sourceRepositoryProvider.GetRepositories(),
                            Guid.Empty,
                            false,
                            true,
                            testLogger,
                            CancellationToken.None);

                        // Assert
                        foreach (var restoreSummary in restoreSummaries)
                        {
                            Assert.True(restoreSummary.Success);
                            Assert.False(restoreSummary.NoOpRestore);
                        }

                        Assert.True(File.Exists(projectLockFilePath));

                        var lockFile = PackagesLockFileFormat.Read(projectLockFilePath);
                        Assert.Equal(2, lockFile.Targets.First().Dependencies.Count);
                    }
            }
        }
        public async void DependencyGraphRestoreUtility_LegacyPackageRef_Restore_GenerateLockFile()
        {
            using (var packageSource = TestDirectory.Create())
            {
                // Arrange
                var sourceRepositoryProvider = TestSourceRepositoryUtility.CreateSourceRepositoryProvider(
                    new List <Configuration.PackageSource>()
                {
                    new Configuration.PackageSource(packageSource.Path)
                });

                using (var testSolutionManager = new TestSolutionManager(true))
                    using (var randomProjectFolderPath = TestDirectory.Create())
                    {
                        var testSettings            = PopulateSettingsWithSources(sourceRepositoryProvider, randomProjectFolderPath);
                        var testNuGetProjectContext = new TestNuGetProjectContext();
                        var deleteOnRestartManager  = new TestDeleteOnRestartManager();
                        var nuGetPackageManager     = new NuGetPackageManager(
                            sourceRepositoryProvider,
                            testSettings,
                            testSolutionManager,
                            deleteOnRestartManager);

                        // set up projects
                        var projectTargetFrameworkStr = "net45";
                        var fullProjectPathB          = Path.Combine(randomProjectFolderPath, "ProjectB", "project2.csproj");
                        var projectNamesB             = new ProjectNames(
                            fullName: fullProjectPathB,
                            uniqueName: Path.GetFileName(fullProjectPathB),
                            shortName: Path.GetFileNameWithoutExtension(fullProjectPathB),
                            customUniqueName: Path.GetFileName(fullProjectPathB));
                        var vsProjectAdapterB = new TestVSProjectAdapter(
                            fullProjectPathB,
                            projectNamesB,
                            projectTargetFrameworkStr);

                        var projectServicesB = new TestProjectSystemServices();
                        projectServicesB.SetupInstalledPackages(
                            NuGetFramework.Parse(projectTargetFrameworkStr),
                            new LibraryDependency
                        {
                            LibraryRange = new LibraryRange(
                                "packageB",
                                VersionRange.Parse("1.*"),
                                LibraryDependencyTarget.Package)
                        });

                        var legacyPRProjectB = new LegacyPackageReferenceProject(
                            vsProjectAdapterB,
                            Guid.NewGuid().ToString(),
                            projectServicesB,
                            _threadingService);

                        var projectPathA     = Path.Combine(randomProjectFolderPath, "ProjectA");
                        var fullProjectPathA = Path.Combine(projectPathA, "project1.csproj");
                        var projectNamesA    = new ProjectNames(
                            fullName: fullProjectPathA,
                            uniqueName: Path.GetFileName(fullProjectPathA),
                            shortName: Path.GetFileNameWithoutExtension(fullProjectPathA),
                            customUniqueName: Path.GetFileName(fullProjectPathA));
                        var vsProjectAdapterA = new TestVSProjectAdapter(
                            fullProjectPathA,
                            projectNamesA,
                            projectTargetFrameworkStr,
                            restorePackagesWithLockFile: "true");

                        var projectServicesA = new TestProjectSystemServices();
                        projectServicesA.SetupInstalledPackages(
                            NuGetFramework.Parse(projectTargetFrameworkStr),
                            new LibraryDependency
                        {
                            LibraryRange = new LibraryRange(
                                "packageA",
                                VersionRange.Parse("1.*"),
                                LibraryDependencyTarget.Package)
                        });
                        projectServicesA.SetupProjectDependencies(
                            new ProjectRestoreReference
                        {
                            ProjectUniqueName = fullProjectPathB,
                            ProjectPath       = fullProjectPathB
                        });

                        var legacyPRProjectA = new LegacyPackageReferenceProject(
                            vsProjectAdapterA,
                            Guid.NewGuid().ToString(),
                            projectServicesA,
                            _threadingService);
                        testSolutionManager.NuGetProjects.Add(legacyPRProjectB);
                        testSolutionManager.NuGetProjects.Add(legacyPRProjectA);

                        var testLogger     = new TestLogger();
                        var restoreContext = new DependencyGraphCacheContext(testLogger, testSettings);
                        var providersCache = new RestoreCommandProvidersCache();

                        var packageContextA = new SimpleTestPackageContext("packageA", "1.0.0");
                        packageContextA.AddFile("lib/net45/a.dll");
                        var packageContextB = new SimpleTestPackageContext("packageB", "1.0.0");
                        packageContextB.AddFile("lib/net45/b.dll");
                        var packages = new List <SimpleTestPackageContext>()
                        {
                            packageContextA, packageContextB
                        };
                        SimpleTestPackageUtility.CreateOPCPackages(packages, packageSource);

                        var dgSpec = await DependencyGraphRestoreUtility.GetSolutionRestoreSpec(testSolutionManager, restoreContext);

                        // Act
                        var restoreSummaries = await DependencyGraphRestoreUtility.RestoreAsync(
                            testSolutionManager,
                            dgSpec,
                            restoreContext,
                            providersCache,
                            (c) => { },
                            sourceRepositoryProvider.GetRepositories(),
                            Guid.Empty,
                            false,
                            true,
                            testLogger,
                            CancellationToken.None);

                        // Assert
                        foreach (var restoreSummary in restoreSummaries)
                        {
                            Assert.True(restoreSummary.Success);
                            Assert.False(restoreSummary.NoOpRestore);
                        }

                        Assert.True(File.Exists(Path.Combine(projectPathA, "packages.lock.json")));
                        var lockFile = PackagesLockFileFormat.Read(Path.Combine(projectPathA, "packages.lock.json"));
                        Assert.Equal(1, lockFile.Targets.Count);

                        Assert.Equal(".NETFramework,Version=v4.5", lockFile.Targets[0].Name);
                        Assert.Equal(3, lockFile.Targets[0].Dependencies.Count);
                        Assert.Equal("packageA", lockFile.Targets[0].Dependencies[0].Id);
                        Assert.Equal(PackageDependencyType.Direct, lockFile.Targets[0].Dependencies[0].Type);
                        Assert.Equal("packageB", lockFile.Targets[0].Dependencies[1].Id);
                        Assert.Equal(PackageDependencyType.Transitive, lockFile.Targets[0].Dependencies[1].Type);
                        Assert.Equal("project2", lockFile.Targets[0].Dependencies[2].Id);
                        Assert.Equal(PackageDependencyType.Project, lockFile.Targets[0].Dependencies[2].Type);
                    }
            }
        }
        public async Task Restore_LegacyPackageReference_WithNuGetLockFilePath()
        {
            // Arrange
            using (var pathContext = new SimpleTestPathContext())
            {
                // Set up solution, project, and packages
                var solution = new SimpleTestSolutionContext(pathContext.SolutionRoot);

                var net461 = "net461";

                var projectA = SimpleTestProjectContext.CreateLegacyPackageReference(
                    "a",
                    pathContext.SolutionRoot,
                    NuGetFramework.Parse(net461));

                var projectB = SimpleTestProjectContext.CreateLegacyPackageReference(
                    "b",
                    pathContext.SolutionRoot,
                    NuGetFramework.Parse(net461));

                // set up packages
                var packageX = new SimpleTestPackageContext()
                {
                    Id      = "x",
                    Version = "1.0.0"
                };
                packageX.Files.Clear();
                packageX.AddFile($"lib/{0}/x.dll", net461);

                var packageY = new SimpleTestPackageContext()
                {
                    Id      = "y",
                    Version = "1.0.0"
                };
                packageY.Files.Clear();
                packageY.AddFile($"lib/{0}/y.dll", net461);

                await SimpleTestPackageUtility.CreateFolderFeedV3Async(
                    pathContext.PackageSource,
                    PackageSaveMode.Defaultv3,
                    packageX,
                    packageY);

                // set up projects and solution
                projectB.AddPackageToAllFrameworks(packageY);
                projectA.Properties.Add("RestorePackagesWithLockFile", "true");
                var packagesLockFilePath = Path.Combine(Path.GetDirectoryName(projectA.ProjectPath), "packages.custom.lock.json");
                projectA.Properties.Add("NuGetLockFilePath", packagesLockFilePath);
                projectA.AddProjectToAllFrameworks(projectB);
                projectA.AddPackageToAllFrameworks(packageX);
                solution.Projects.Add(projectA);
                solution.Projects.Add(projectB);
                solution.Create(pathContext.SolutionRoot);

                // Act
                var result = RunRestore(pathContext);

                // Assert
                Assert.True(File.Exists(projectA.NuGetLockFileOutputPath));
                Assert.Equal(packagesLockFilePath, projectA.NuGetLockFileOutputPath);

                var lockFile = PackagesLockFileFormat.Read(projectA.NuGetLockFileOutputPath);
                Assert.Equal(4, lockFile.Targets.Count);

                var targets = lockFile.Targets.Where(t => t.Dependencies.Count > 0).ToList();
                Assert.Equal(1, targets.Count);
                Assert.Equal(".NETFramework,Version=v4.6.1", targets[0].Name);
                Assert.Equal(3, targets[0].Dependencies.Count);
                Assert.Equal("x", targets[0].Dependencies[0].Id);
                Assert.Equal(PackageDependencyType.Direct, targets[0].Dependencies[0].Type);
                Assert.Equal("y", targets[0].Dependencies[1].Id);
                Assert.Equal(PackageDependencyType.Transitive, targets[0].Dependencies[1].Type);
                Assert.Equal("b", targets[0].Dependencies[2].Id);
                Assert.Equal(PackageDependencyType.Project, targets[0].Dependencies[2].Type);
            }
        }
        public static IReadOnlyList <IRestoreLogMessage> ValidatePackagesConfigLockFiles(
            string projectFile,
            string packagesConfigFile,
            string projectName,
            string nuGetLockFilePath,
            string restorePackagesWithLockFile,
            NuGetFramework projectTfm,
            string packagesFolderPath,
            bool restoreLockedMode,
            CancellationToken token)
        {
            var lockFilePath   = GetPackagesLockFilePath(Path.GetDirectoryName(packagesConfigFile), nuGetLockFilePath, projectName);
            var lockFileExists = File.Exists(lockFilePath);
            var lockFileOptIn  = MSBuildStringUtility.GetBooleanOrNull(restorePackagesWithLockFile);
            var useLockFile    = lockFileOptIn == true || lockFileExists;

            if (lockFileOptIn == false && lockFileExists)
            {
                var message = string.Format(CultureInfo.CurrentCulture, Strings.Error_InvalidLockFileInput, lockFilePath);
                var errors  = new List <IRestoreLogMessage>();
                var log     = RestoreLogMessage.CreateError(NuGetLogCode.NU1005, message, packagesConfigFile);
                log.ProjectPath = projectFile ?? packagesConfigFile;
                errors.Add(log);
                return(errors);
            }

            if (useLockFile)
            {
                PackagesLockFile projectLockFileEquivalent = PackagesConfigLockFileUtility.FromPackagesConfigFile(packagesConfigFile,
                                                                                                                  projectTfm,
                                                                                                                  packagesFolderPath,
                                                                                                                  token);

                if (!lockFileExists)
                {
                    PackagesLockFileFormat.Write(lockFilePath, projectLockFileEquivalent);
                    return(null);
                }
                else
                {
                    PackagesLockFile lockFile = PackagesLockFileFormat.Read(lockFilePath);
                    PackagesLockFileUtilities.LockFileValidityWithMatchedResults comparisonResult = PackagesLockFileUtilities.IsLockFileStillValid(projectLockFileEquivalent, lockFile);
                    if (comparisonResult.IsValid)
                    {
                        // check sha hashes
                        bool allContentHashesMatch = comparisonResult.MatchedDependencies.All(pair => pair.Key.ContentHash == pair.Value.ContentHash);
                        if (allContentHashesMatch)
                        {
                            return(null);
                        }
                        else
                        {
                            var errors = new List <IRestoreLogMessage>();
                            foreach (var difference in comparisonResult.MatchedDependencies.Where(kvp => kvp.Key.ContentHash != kvp.Value.ContentHash))
                            {
                                var message = string.Format(CultureInfo.CurrentCulture, Strings.Error_PackageValidationFailed, difference.Key.Id + "." + difference.Key.ResolvedVersion);
                                var log     = RestoreLogMessage.CreateError(NuGetLogCode.NU1403, message, packagesConfigFile);
                                log.ProjectPath = projectFile ?? packagesConfigFile;
                                errors.Add(log);
                            }
                            return(errors);
                        }
                    }
                    else
                    {
                        if (restoreLockedMode)
                        {
                            var errors = new List <IRestoreLogMessage>();
                            var log    = RestoreLogMessage.CreateError(NuGetLogCode.NU1004, Strings.Error_RestoreInLockedModePackagesConfig, packagesConfigFile);
                            log.ProjectPath = projectFile ?? packagesConfigFile;
                            errors.Add(log);
                            return(errors);
                        }
                        else
                        {
                            PackagesLockFileFormat.Write(lockFilePath, projectLockFileEquivalent);
                            return(null);
                        }
                    }
                }
            }
            else
            {
                return(null);
            }
        }