private static JProperty WriteTarget(PackagesLockFileTarget target) { var json = JsonUtility.WriteObject(target.Dependencies, WriteTargetDependency); var key = target.Name; return(new JProperty(key, json)); }
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)); }