public static DependencyInfo FromLibraryDependency(LibraryDependency lib) { return new DependencyInfo { Name = lib.Name, Range = lib.LibraryRange.ToString(), Identity = lib.Library?.ToString() }; }
public static IList<LibraryDependency> Flatten(LibraryDependency root) { var flattened = new List<LibraryDependency> { root }; var children = root.Library.Dependencies; if (children != null) { foreach (var child in children) { flattened.AddRange(Flatten(child)); } } return flattened; }
public async Task<GraphNode> CreateGraphNode(RestoreContext context, LibraryRange libraryRange, Func<string, bool> predicate) { var dependencies = new List<LibraryDependency>(); if (context.RuntimeDependencies != null) { DependencySpec dependencyMapping; if (context.RuntimeDependencies.TryGetValue(libraryRange.Name, out dependencyMapping)) { foreach (var runtimeDependency in dependencyMapping.Implementations.Values) { var libraryDependency = new LibraryDependency { LibraryRange = new LibraryRange(runtimeDependency.Name, frameworkReference: false) { VersionRange = VersionUtility.ParseVersionRange(runtimeDependency.Version) } }; // HACK(davidfowl): This is making runtime.json support package redirects if (libraryDependency.LibraryRange.Name == libraryRange.Name) { // It's replacing the current version, we need to override rather than adding a (potentially circular) dependency if (libraryRange.VersionRange != null && libraryDependency.LibraryRange.VersionRange != null && libraryRange.VersionRange.MinVersion < libraryDependency.LibraryRange.VersionRange.MinVersion) { libraryRange = libraryDependency.LibraryRange; } } else { // Otherwise it's a dependency of this node dependencies.Add(libraryDependency); } } } } var node = new GraphNode { LibraryRange = libraryRange, Item = await FindLibraryCached(context, libraryRange), }; if (node.Item != null) { if (node.LibraryRange.VersionRange != null && node.LibraryRange.VersionRange.VersionFloatBehavior != SemanticVersionFloatBehavior.None) { lock (context.GraphItemCache) { if (!context.GraphItemCache.ContainsKey(node.LibraryRange)) { context.GraphItemCache[node.LibraryRange] = Task.FromResult(node.Item); } } } dependencies.AddRange(node.Item.Dependencies); var tasks = new List<Task<GraphNode>>(); foreach (var dependency in dependencies) { if (predicate(dependency.Name)) { tasks.Add(CreateGraphNode(context, dependency.LibraryRange, ChainPredicate(predicate, node.Item, dependency))); } } while (tasks.Any()) { var task = await Task.WhenAny(tasks); tasks.Remove(task); var dependency = await task; node.Dependencies.Add(dependency); } } return node; }
private Func<string, bool> ChainPredicate(Func<string, bool> predicate, GraphItem item, LibraryDependency dependency) { return name => { if (item.Match.Library.Name == name) { throw new InvalidOperationException($"A circular reference to '{name}' was detected."); } if (item.Dependencies.Any(d => d != dependency && d.Name == name)) { return false; } return predicate(name); }; }
private Func<string, bool> ChainPredicate(Func<string, bool> predicate, GraphItem item, LibraryDependency dependency) { return name => { if (item.Match.Library.Name == name) { throw new Exception(string.Format("TODO: Circular dependency references not supported. Package '{0}'.", name)); } if (item.Dependencies.Any(d => d != dependency && d.Name == name)) { return false; } return predicate(name); }; }
private static bool IsLibraryMismatch(LibraryDependency dependency) { if (dependency.LibraryRange?.VersionRange != null) { // If we ended up with a declared version that isn't what was asked for directly // then report a warning // Case 1: Non floating version and the minimum doesn't match what was specified // Case 2: Floating version that fell outside of the range if ((dependency.LibraryRange.VersionRange.VersionFloatBehavior == SemanticVersionFloatBehavior.None && dependency.LibraryRange.VersionRange.MinVersion != dependency.Library.Identity.Version) || (dependency.LibraryRange.VersionRange.VersionFloatBehavior != SemanticVersionFloatBehavior.None && !dependency.LibraryRange.VersionRange.EqualsFloating(dependency.Library.Identity.Version))) { return true; } } return false; }