internal static void ApplyChanges(
     PackagesLockFile lockFile,
     List <NuGetProjectAction> actionsList,
     IPackagesConfigContentHashProvider contentHashUtil,
     CancellationToken token)
 {
     RemoveUninstalledPackages(lockFile,
                               actionsList.Where(a => a.NuGetProjectActionType == NuGetProjectActionType.Uninstall));
     AddInstalledPackages(lockFile,
                          actionsList.Where(a => a.NuGetProjectActionType == NuGetProjectActionType.Install),
                          contentHashUtil,
                          token);
     ArrayList.Adapter((IList)lockFile.Targets[0].Dependencies).Sort(_dependencyComparer);
 }
Example #2
0
        public void ApplyChanges_SortPackages_LastPackage()
        {
            // Arrange
            var lockFile = new PackagesLockFile
            {
                Targets = new List <PackagesLockFileTarget>
                {
                    new PackagesLockFileTarget
                    {
                        Dependencies = new List <LockFileDependency>
                        {
                            new LockFileDependency
                            {
                                Id = "packageB",
                                ResolvedVersion = NuGetVersion.Parse("1.0.0")
                            },
                            new LockFileDependency
                            {
                                Id = "packageD",
                                ResolvedVersion = NuGetVersion.Parse("1.0.0")
                            }
                        }
                    }
                }
            };

            var actionList = new List <NuGetProjectAction>
            {
                NuGetProjectAction.CreateInstallProjectAction(new PackageIdentity("packageE", NuGetVersion.Parse("1.0.0")), null, null)
            };

            var contentHashUtility = new Mock <IPackagesConfigContentHashProvider>();

            // Act
            PackagesConfigLockFileUtility.ApplyChanges(lockFile, actionList, contentHashUtility.Object, CancellationToken.None);

            // Assert
            Assert.Equal(3, lockFile.Targets[0].Dependencies.Count);
            Assert.Equal("packageB", lockFile.Targets[0].Dependencies[0].Id);
            Assert.Equal("packageD", lockFile.Targets[0].Dependencies[1].Id);
            Assert.Equal("packageE", lockFile.Targets[0].Dependencies[2].Id);
        }
        private static void RemoveUninstalledPackages(PackagesLockFile lockFile, IEnumerable <NuGetProjectAction> actionsList)
        {
            var dependencies = lockFile.Targets[0].Dependencies;

            foreach (var toUninstall in actionsList)
            {
                Debug.Assert(toUninstall.NuGetProjectActionType == NuGetProjectActionType.Uninstall);

                var toUninstallId = toUninstall.PackageIdentity.Id;

                for (var i = 0; i < dependencies.Count; i++)
                {
                    if (string.Equals(toUninstallId, dependencies[i].Id, StringComparison.InvariantCultureIgnoreCase))
                    {
                        dependencies.RemoveAt(i);
                        break;
                    }
                }
            }
        }
        private static void AddInstalledPackages(
            PackagesLockFile lockFile,
            IEnumerable <NuGetProjectAction> actionsList,
            IPackagesConfigContentHashProvider contentHashUtil,
            CancellationToken token)
        {
            foreach (var toInstall in actionsList)
            {
                Debug.Assert(toInstall.NuGetProjectActionType == NuGetProjectActionType.Install);

                var newDependency = new LockFileDependency
                {
                    Id               = toInstall.PackageIdentity.Id,
                    ContentHash      = contentHashUtil.GetContentHash(toInstall.PackageIdentity, token),
                    RequestedVersion = new VersionRange(toInstall.PackageIdentity.Version, includeMinVersion: true, toInstall.PackageIdentity.Version, includeMaxVersion: true),
                    ResolvedVersion  = toInstall.PackageIdentity.Version,
                    Type             = PackageDependencyType.Direct
                };

                lockFile.Targets[0].Dependencies.Add(newDependency);
            }
        }
        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 PackagesLockFile CreateNuGetLockFile(LockFile assetsFile)
        {
            var lockFile = new PackagesLockFile();

            var libraryLookup = assetsFile.Libraries.Where(e => e.Type == LibraryType.Package)
                                .ToDictionary(e => new PackageIdentity(e.Name, e.Version));

            foreach (var target in assetsFile.Targets)
            {
                var nuGettarget = new PackagesLockFileTarget()
                {
                    TargetFramework   = target.TargetFramework,
                    RuntimeIdentifier = target.RuntimeIdentifier
                };

                var framework = assetsFile.PackageSpec.TargetFrameworks.FirstOrDefault(
                    f => EqualityUtility.EqualsWithNullCheck(f.FrameworkName, target.TargetFramework));

                var libraries = target.Libraries;

                // check if this is RID-based graph then only add those libraries which differ from original TFM.
                if (!string.IsNullOrEmpty(target.RuntimeIdentifier))
                {
                    var onlyTFM = assetsFile.Targets.First(t => EqualityUtility.EqualsWithNullCheck(t.TargetFramework, target.TargetFramework));

                    libraries = target.Libraries.Where(lib => !onlyTFM.Libraries.Any(tfmLib => tfmLib.Equals(lib))).ToList();
                }

                foreach (var library in libraries.Where(e => e.Type == LibraryType.Package))
                {
                    var identity = new PackageIdentity(library.Name, library.Version);

                    var dependency = new LockFileDependency()
                    {
                        Id = library.Name,
                        ResolvedVersion = library.Version,
                        Sha512          = libraryLookup[identity].Sha512,
                        Dependencies    = library.Dependencies
                    };

                    var framework_dep = framework?.Dependencies.FirstOrDefault(
                        dep => StringComparer.OrdinalIgnoreCase.Equals(dep.Name, library.Name));

                    if (framework_dep != null)
                    {
                        dependency.Type             = PackageDependencyType.Direct;
                        dependency.RequestedVersion = framework_dep.LibraryRange.VersionRange;
                    }
                    else
                    {
                        dependency.Type = PackageDependencyType.Transitive;
                    }

                    nuGettarget.Dependencies.Add(dependency);
                }

                foreach (var projectReference in libraries.Where(e => e.Type == LibraryType.Project || e.Type == LibraryType.ExternalProject))
                {
                    var dependency = new LockFileDependency()
                    {
                        Id           = projectReference.Name,
                        Dependencies = projectReference.Dependencies,
                        Type         = PackageDependencyType.Project
                    };

                    nuGettarget.Dependencies.Add(dependency);
                }

                nuGettarget.Dependencies = nuGettarget.Dependencies.OrderBy(d => d.Type).ToList();

                lockFile.Targets.Add(nuGettarget);
            }

            return(lockFile);
        }
        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);
            }
        }
        public PackagesLockFile CreateNuGetLockFile(LockFile assetsFile)
        {
            var lockFile = new PackagesLockFile(GetPackagesLockFileVersion(assetsFile));

            var libraryLookup = assetsFile.Libraries.Where(e => e.Type == LibraryType.Package)
                                .ToDictionary(e => new PackageIdentity(e.Name, e.Version));

            foreach (var target in assetsFile.Targets)
            {
                var nuGettarget = new PackagesLockFileTarget()
                {
                    TargetFramework   = target.TargetFramework,
                    RuntimeIdentifier = target.RuntimeIdentifier
                };

                var framework = assetsFile.PackageSpec.TargetFrameworks.FirstOrDefault(
                    f => EqualityUtility.EqualsWithNullCheck(f.FrameworkName, target.TargetFramework));

                IEnumerable <LockFileTargetLibrary> libraries = target.Libraries;

                // check if this is RID-based graph then only add those libraries which differ from original TFM.
                if (!string.IsNullOrEmpty(target.RuntimeIdentifier))
                {
                    var onlyTFM = assetsFile.Targets.First(t => EqualityUtility.EqualsWithNullCheck(t.TargetFramework, target.TargetFramework));

                    libraries = target.Libraries.Where(lib => !onlyTFM.Libraries.Any(tfmLib => tfmLib.Equals(lib)));
                }

                foreach (var library in libraries.Where(e => e.Type == LibraryType.Package))
                {
                    var identity = new PackageIdentity(library.Name, library.Version);

                    var dependency = new LockFileDependency()
                    {
                        Id = library.Name,
                        ResolvedVersion = library.Version,
                        ContentHash     = libraryLookup[identity].Sha512,
                        Dependencies    = library.Dependencies
                    };

                    var framework_dep = framework?.Dependencies.FirstOrDefault(
                        dep => StringComparer.OrdinalIgnoreCase.Equals(dep.Name, library.Name));

                    CentralPackageVersion centralPackageVersion = null;
                    framework?.CentralPackageVersions.TryGetValue(library.Name, out centralPackageVersion);

                    if (framework_dep != null)
                    {
                        dependency.Type             = PackageDependencyType.Direct;
                        dependency.RequestedVersion = framework_dep.LibraryRange.VersionRange;
                    }

                    // The dgspec has a list of the direct dependencies and changes in the direct dependencies will invalidate the lock file
                    // A dgspec does not have information about transitive dependencies
                    // At the restore time the transitive dependencies could be pinned from central package version management file
                    // By marking them will allow to evaluate when to invalidate the packages.lock.json
                    // in cases that a central transitive version is updated, removed or added the lock file will be invalidated
                    else if (centralPackageVersion != null)
                    {
                        // This is a transitive dependency that is in the list of central dependencies.
                        dependency.Type             = PackageDependencyType.CentralTransitive;
                        dependency.RequestedVersion = centralPackageVersion.VersionRange;
                    }
                    else
                    {
                        dependency.Type = PackageDependencyType.Transitive;
                    }

                    nuGettarget.Dependencies.Add(dependency);
                }

                var projectFullPaths = assetsFile.Libraries
                                       .Where(l => l.Type == LibraryType.Project || l.Type == LibraryType.ExternalProject)
                                       .ToDictionary(l => new PackageIdentity(l.Name, l.Version), l => l.MSBuildProject);

                foreach (var projectReference in libraries.Where(e => e.Type == LibraryType.Project || e.Type == LibraryType.ExternalProject))
                {
                    var projectIdentity = new PackageIdentity(projectReference.Name, projectReference.Version);
                    var projectFullPath = projectFullPaths[projectIdentity];
                    var id = PathUtility.GetStringComparerBasedOnOS().Equals(Path.GetFileNameWithoutExtension(projectFullPath), projectReference.Name)
                        ? projectReference.Name.ToLowerInvariant()
                        : projectReference.Name;

                    var dependency = new LockFileDependency()
                    {
                        Id           = id,
                        Dependencies = projectReference.Dependencies,
                        Type         = PackageDependencyType.Project
                    };

                    nuGettarget.Dependencies.Add(dependency);
                }

                nuGettarget.Dependencies = nuGettarget.Dependencies.OrderBy(d => d.Type).ToList();

                lockFile.Targets.Add(nuGettarget);
            }

            return(lockFile);
        }
Example #9
0
        public void PackagesLockFile_Equals()
        {
            Func <PackagesLockFile> getLockFile = () =>
            {
                var lockFile = new PackagesLockFile()
                {
                    Version = 1,

                    Targets = new List <PackagesLockFileTarget>()
                    {
                        new PackagesLockFileTarget()
                        {
                            TargetFramework = FrameworkConstants.CommonFrameworks.Net45,

                            Dependencies = new List <LockFileDependency>()
                            {
                                new LockFileDependency()
                                {
                                    Id               = "PackageA",
                                    Type             = PackageDependencyType.Direct,
                                    RequestedVersion = VersionRange.Parse("1.0.0"),
                                    ResolvedVersion  = NuGetVersion.Parse("1.0.0"),
                                    Sha512           = "sha1",
                                    Dependencies     = new List <PackageDependency>()
                                    {
                                        new PackageDependency("PackageB", VersionRange.Parse("1.0.0"))
                                    }
                                },
                                new LockFileDependency()
                                {
                                    Id              = "PackageB",
                                    Type            = PackageDependencyType.Transitive,
                                    ResolvedVersion = NuGetVersion.Parse("1.0.0"),
                                    Sha512          = "sha2"
                                }
                            }
                        },
                        new PackagesLockFileTarget()
                        {
                            TargetFramework = FrameworkConstants.CommonFrameworks.Net45,

                            RuntimeIdentifier = "win10-arm",

                            Dependencies = new List <LockFileDependency>()
                            {
                                new LockFileDependency()
                                {
                                    Id               = "PackageA",
                                    Type             = PackageDependencyType.Direct,
                                    RequestedVersion = VersionRange.Parse("1.0.0"),
                                    ResolvedVersion  = NuGetVersion.Parse("1.0.0"),
                                    Sha512           = "sha3",
                                    Dependencies     = new List <PackageDependency>()
                                    {
                                        new PackageDependency("runtime.win10-arm.PackageA", VersionRange.Parse("1.0.0"))
                                    }
                                },
                                new LockFileDependency()
                                {
                                    Id              = "runtime.win10-arm.PackageA",
                                    Type            = PackageDependencyType.Transitive,
                                    ResolvedVersion = NuGetVersion.Parse("1.0.0"),
                                    Sha512          = "sha4"
                                }
                            }
                        }
                    }
                };

                return(lockFile);
            };

            var self  = getLockFile();
            var other = getLockFile();

            Assert.NotSame(self, other);
            Assert.Equal(self, other);
        }