Esempio n. 1
0
        private static JProperty WriteTarget(PackagesLockFileTarget target)
        {
            var json = JsonUtility.WriteObject(target.Dependencies, WriteTargetDependency);

            var key = target.Name;

            return(new JProperty(key, json));
        }
Esempio n. 2
0
        private static PackagesLockFileTarget ReadDependency(string property, JToken json)
        {
            var parts = property.Split(JsonUtility.PathSplitChars, 2);

            var target = new PackagesLockFileTarget
            {
                TargetFramework = NuGetFramework.Parse(parts[0]),
                Dependencies    = JsonUtility.ReadObject(json as JObject, ReadTargetDependency)
            };

            if (parts.Length == 2)
            {
                target.RuntimeIdentifier = parts[1];
            }

            return(target);
        }
        /// <summary>Compares two lock files to check if the structure is the same (all values are the same, other
        /// than SHA hash), and matches dependencies so the caller can easily compare SHA hashes.</summary>
        /// <param name="expected">The expected lock file structure. Usuaully generated from the project.</param>
        /// <param name="actual">The lock file that was loaded from the file on disk.</param>
        /// <returns>A <see cref="LockFileValidityWithMatchedResults"/>.</returns>
        public static LockFileValidityWithMatchedResults IsLockFileStillValid(PackagesLockFile expected, PackagesLockFile actual)
        {
            if (expected == null)
            {
                throw new ArgumentNullException(nameof(expected));
            }
            if (actual == null)
            {
                throw new ArgumentNullException(nameof(actual));
            }

            // do quick checks for obvious structure differences
            if (expected.Version != actual.Version)
            {
                return(LockFileValidityWithMatchedResults.Invalid);
            }

            if (expected.Targets.Count != actual.Targets.Count)
            {
                return(LockFileValidityWithMatchedResults.Invalid);
            }

            foreach (var expectedTarget in expected.Targets)
            {
                PackagesLockFileTarget actualTarget = null;

                for (var i = 0; i < actual.Targets.Count; i++)
                {
                    if (actual.Targets[i].TargetFramework == expectedTarget.TargetFramework)
                    {
                        if (actualTarget == null)
                        {
                            actualTarget = actual.Targets[i];
                        }
                        else
                        {
                            // more than 1? possible bug or bad hand edited lock file.
                            return(LockFileValidityWithMatchedResults.Invalid);
                        }
                    }

                    if (actualTarget == null)
                    {
                        return(LockFileValidityWithMatchedResults.Invalid);
                    }

                    if (actualTarget.Dependencies.Count != expectedTarget.Dependencies.Count)
                    {
                        return(LockFileValidityWithMatchedResults.Invalid);
                    }
                }
            }

            // no obvious structure difference, so start trying to match individual dependencies
            var matchedDependencies  = new List <KeyValuePair <LockFileDependency, LockFileDependency> >();
            var isLockFileStillValid = true;
            var dependencyComparer   = LockFileDependencyComparerWithoutContentHash.Default;

            foreach (PackagesLockFileTarget expectedTarget in expected.Targets)
            {
                PackagesLockFileTarget actualTarget = actual.Targets.Single(t => t.TargetFramework == expectedTarget.TargetFramework);

                // Duplicate dependencies list so we can remove matches to validate that all dependencies were matched
                var actualDependencies = new Dictionary <LockFileDependency, LockFileDependency>(
                    actualTarget.Dependencies.Count,
                    dependencyComparer);
                foreach (LockFileDependency actualDependency in actualTarget.Dependencies)
                {
                    actualDependencies.Add(actualDependency, actualDependency);
                }

                foreach (LockFileDependency expectedDependency in expectedTarget.Dependencies)
                {
                    if (actualDependencies.TryGetValue(expectedDependency, out var actualDependency))
                    {
                        matchedDependencies.Add(new KeyValuePair <LockFileDependency, LockFileDependency>(expectedDependency, actualDependency));
                        actualDependencies.Remove(actualDependency);
                    }
                    else
                    {
                        return(LockFileValidityWithMatchedResults.Invalid);
                    }
                }

                if (actualDependencies.Count != 0)
                {
                    return(LockFileValidityWithMatchedResults.Invalid);
                }
            }

            return(new LockFileValidityWithMatchedResults(isLockFileStillValid, matchedDependencies));
        }