Пример #1
0
        private static JProperty WriteTargetDependency(LockFileDependency dependency)
        {
            var json = new JObject
            {
                [TypeProperty] = dependency.Type.ToString()
            };

            if (dependency.RequestedVersion != null)
            {
                json[RequestedProperty] = dependency.RequestedVersion.ToNormalizedString();
            }

            if (dependency.ResolvedVersion != null)
            {
                json[ResolvedProperty] = dependency.ResolvedVersion.ToNormalizedString();
            }

            if (dependency.ContentHash != null)
            {
                json[ContentHashProperty] = dependency.ContentHash;
            }

            if (dependency.Dependencies?.Count > 0)
            {
                var ordered = dependency.Dependencies.OrderBy(dep => dep.Id, StringComparer.Ordinal);

                json[DependenciesProperty] = JsonUtility.WriteObject(ordered, JsonUtility.WritePackageDependency);
            }

            return(new JProperty(dependency.Id, json));
        }
        /// <summary>
        /// The method will return true if:
        /// 1. If a transitive dependency from the lock file is now added to the central file.
        ///     or
        /// 1. If there is a mistmatch between the RequestedVersion of a lock file dependency marked as CentralTransitive and the the version specified in the central package management file.
        ///     or
        /// 2. If a central version that is a transitive dependency is removed from CPVM the lock file is invalidated.
        /// </summary>
        private static (bool, string) HasProjectTransitiveDependencyChanged(
            IDictionary <string, CentralPackageVersion> centralPackageVersions,
            IList <LockFileDependency> lockFileCentralTransitiveDependencies,
            IList <LockFileDependency> lockTransitiveDependencies)
        {
            // Transitive dependencies moved to be centraly managed will invalidate the lock file
            LockFileDependency dependency = lockTransitiveDependencies.FirstOrDefault(dep => centralPackageVersions.ContainsKey(dep.Id));

            if (dependency != null)
            {
                return(true,
                       string.Format(
                           CultureInfo.CurrentCulture,
                           Strings.PackagesLockFile_ProjectTransitiveDependencyChanged,
                           dependency.Id
                           )
                       );
            }

            foreach (var lockFileDependencyEnforcedByCPV in lockFileCentralTransitiveDependencies)
            {
                if (centralPackageVersions.TryGetValue(lockFileDependencyEnforcedByCPV.Id, out var centralPackageVersion))
                {
                    if (centralPackageVersion != null && !EqualityUtility.EqualsWithNullCheck(lockFileDependencyEnforcedByCPV.RequestedVersion, centralPackageVersion.VersionRange))
                    {
                        return(true,
                               string.Format(
                                   CultureInfo.CurrentCulture,
                                   Strings.PackagesLockFile_ProjectTransitiveDependencyVersionChanged,
                                   lockFileDependencyEnforcedByCPV.RequestedVersion.ToNormalizedString(),
                                   centralPackageVersion.VersionRange.ToNormalizedString()
                                   )
                               );
                    }
                    continue;
                }

                // The central version was removed
                return(true,
                       string.Format(
                           CultureInfo.CurrentCulture,
                           Strings.PackagesLockFile_CentralPackageVersionRemoved,
                           lockFileDependencyEnforcedByCPV.Id
                           )
                       );
            }

            return(false, string.Empty);
        }
Пример #3
0
        private static LockFileDependency ReadTargetDependency(string property, JToken json)
        {
            var dependency = new LockFileDependency
            {
                Id           = property,
                Dependencies = JsonUtility.ReadObject(json[DependenciesProperty] as JObject, JsonUtility.ReadPackageDependency)
            };

            var jObject = json as JObject;

            var typeString = JsonUtility.ReadProperty <string>(jObject, TypeProperty);

            if (!string.IsNullOrEmpty(typeString) &&
                Enum.TryParse <PackageDependencyType>(typeString, ignoreCase: true, result: out var installationType))
            {
                dependency.Type = installationType;
            }

            var resolvedString = JsonUtility.ReadProperty <string>(jObject, ResolvedProperty);

            if (!string.IsNullOrEmpty(resolvedString))
            {
                dependency.ResolvedVersion = NuGetVersion.Parse(resolvedString);
            }

            var requestedString = JsonUtility.ReadProperty <string>(jObject, RequestedProperty);

            if (!string.IsNullOrEmpty(requestedString))
            {
                dependency.RequestedVersion = VersionRange.Parse(requestedString);
            }

            dependency.ContentHash = JsonUtility.ReadProperty <string>(jObject, ContentHashProperty);

            return(dependency);
        }
        private static bool HasP2PDependencyChanged(IEnumerable <LibraryDependency> newDependencies, IEnumerable <ProjectRestoreReference> projectRestoreReferences, LockFileDependency projectDependency, DependencyGraphSpec dgSpec)
        {
            if (projectDependency == null)
            {
                // project dependency doesn't exists in lock file so it's out of sync.
                return(true);
            }

            // If the count is not the same, something has changed.
            // Otherwise we N^2 walk below determines whether anything has changed.
            var transitivelyFlowingDependencies = newDependencies.Where(
                dep => (dep.LibraryRange.TypeConstraint == LibraryDependencyTarget.Package && dep.SuppressParent != LibraryIncludeFlags.All));

            if (transitivelyFlowingDependencies.Count() + projectRestoreReferences.Count() != projectDependency.Dependencies.Count)
            {
                return(true);
            }

            foreach (var dependency in transitivelyFlowingDependencies)
            {
                var matchedP2PLibrary = projectDependency.Dependencies.FirstOrDefault(dep => StringComparer.OrdinalIgnoreCase.Equals(dep.Id, dependency.Name));

                if (matchedP2PLibrary == null || !EqualityUtility.EqualsWithNullCheck(matchedP2PLibrary.VersionRange, dependency.LibraryRange.VersionRange))
                {
                    // P2P dependency has changed and lock file is out of sync.
                    return(true);
                }
            }

            foreach (var dependency in projectRestoreReferences)
            {
                var referenceSpec     = dgSpec.GetProjectSpec(dependency.ProjectUniqueName);
                var matchedP2PLibrary = projectDependency.Dependencies.FirstOrDefault(dep => StringComparer.OrdinalIgnoreCase.Equals(dep.Id, referenceSpec.Name));

                if (matchedP2PLibrary == null) // Do not check the version for the projects, or else https://github.com/nuget/home/issues/7935
                {
                    // P2P dependency has changed and lock file is out of sync.
                    return(true);
                }
            }

            // no dependency changed. Lock file is still valid.
            return(false);
        }
        private static bool HasP2PDependencyChanged(IEnumerable <LibraryDependency> newDependencies, LockFileDependency projectDependency)
        {
            if (projectDependency == null)
            {
                // project dependency doesn't exists in lock file so it's out of sync.
                return(true);
            }

            foreach (var dependency in newDependencies.Where(dep => dep.LibraryRange.TypeConstraint == LibraryDependencyTarget.Package))
            {
                var matchedP2PLibrary = projectDependency.Dependencies.FirstOrDefault(dep => StringComparer.OrdinalIgnoreCase.Equals(dep.Id, dependency.Name));

                if (matchedP2PLibrary == null || !EqualityUtility.EqualsWithNullCheck(matchedP2PLibrary.VersionRange, dependency.LibraryRange.VersionRange))
                {
                    // P2P dependency has changed and lock file is out of sync.
                    return(true);
                }
            }

            // no dependency changed. Lock file is still valid.
            return(false);
        }
        private static (bool, string) HasP2PDependencyChanged(IEnumerable <LibraryDependency> newDependencies, IEnumerable <ProjectRestoreReference> projectRestoreReferences, LockFileDependency projectDependency, DependencyGraphSpec dgSpec)
        {
            // If the count is not the same, something has changed.
            // Otherwise we N^2 walk below determines whether anything has changed.
            var transitivelyFlowingDependencies = newDependencies.Where(
                dep => dep.LibraryRange.TypeConstraint == LibraryDependencyTarget.Package && dep.SuppressParent != LibraryIncludeFlags.All);

            var transitivelyFlowingProjectReferences = projectRestoreReferences.Where(e => e.PrivateAssets != LibraryIncludeFlags.All);

            var transitiveDependencies = transitivelyFlowingDependencies.Count() + transitivelyFlowingProjectReferences.Count();

            if (transitiveDependencies != projectDependency.Dependencies.Count)
            {
                return(true,
                       string.Format(
                           CultureInfo.CurrentCulture,
                           Strings.PackagesLockFile_ProjectReferencesHasChange,
                           projectDependency.Id,
                           transitiveDependencies > 0 ? string.Join(",", transitivelyFlowingDependencies.Select(dep => dep.Name).Concat(projectRestoreReferences.Select(dep => dep.ProjectUniqueName)).OrderBy(dep => dep)) : Strings.None,
                           projectDependency.Dependencies.Count > 0 ? string.Join(",", projectDependency.Dependencies.Select(dep => dep.Id).OrderBy(dep => dep)) : Strings.None
                           )
                       );
            }

            foreach (var dependency in transitivelyFlowingDependencies)
            {
                var matchedP2PLibrary = projectDependency.Dependencies.FirstOrDefault(dep => StringComparer.OrdinalIgnoreCase.Equals(dep.Id, dependency.Name));

                if (matchedP2PLibrary == null || !EqualityUtility.EqualsWithNullCheck(matchedP2PLibrary.VersionRange, dependency.LibraryRange.VersionRange))
                {
                    // P2P dependency has changed and lock file is out of sync.
                    return(true,
                           string.Format(
                               CultureInfo.CurrentCulture,
                               Strings.PackagesLockFile_ProjectReferenceDependenciesHasChanged,
                               projectDependency.Id
                               )
                           );
                }
            }

            foreach (var dependency in transitivelyFlowingProjectReferences)
            {
                var referenceSpec     = dgSpec.GetProjectSpec(dependency.ProjectUniqueName);
                var matchedP2PLibrary = projectDependency.Dependencies.FirstOrDefault(dep => StringComparer.OrdinalIgnoreCase.Equals(dep.Id, referenceSpec.Name));

                if (matchedP2PLibrary == null) // Do not check the version for the projects, or else https://github.com/nuget/home/issues/7935
                {
                    // P2P dependency has changed and lock file is out of sync.
                    return(true,
                           string.Format(
                               CultureInfo.CurrentCulture,
                               Strings.PackagesLockFile_ProjectReferenceDependenciesHasChanged,
                               projectDependency.Id
                               )
                           );
                }
            }

            // no dependency changed. Lock file is still valid.
            return(false, string.Empty);
        }