public void MergingCombinesDependencySetsInRuntimesDefinedInBoth() { var leftGraph = new RuntimeGraph(new[] { new RuntimeDescription("any"), new RuntimeDescription("win8", new[] { "any", "win7" }, new[] { new RuntimeDependencySet("Foo"), }) }); var rightGraph = new RuntimeGraph(new[] { new RuntimeDescription("win8", new[] { new RuntimeDependencySet("Bar") }) }); var graph = RuntimeGraph.Merge(leftGraph, rightGraph); Assert.Equal(new RuntimeGraph(new[] { new RuntimeDescription("any"), new RuntimeDescription("win8", new[] { "any", "win7" }, new[] { new RuntimeDependencySet("Foo"), new RuntimeDependencySet("Bar") }), }), leftGraph); }
private static void WriteRuntimeGraph(JObject jObject, RuntimeGraph runtimeGraph) { var runtimes = new JObject(); jObject["runtimes"] = runtimes; foreach (var x in runtimeGraph.Runtimes.Values) { WriteRuntimeDescription(runtimes, x); } }
private IEnumerable<string> FindImporters(RuntimeGraph runtimeGraph, string runtime) { foreach (var runtimePair in runtimeGraph.Runtimes) { var expanded = runtimeGraph.ExpandRuntime(runtimePair.Key); if (expanded.Contains(runtime)) { yield return runtimePair.Key; } } }
private RuntimeGraph GetRuntimeGraph(RestoreTargetGraph graph, IReadOnlyList <NuGetv3LocalRepository> localRepositories) { // TODO: Caching! RuntimeGraph runtimeGraph; if (_request.RuntimeGraphCache.TryGetValue(graph.Framework, out runtimeGraph)) { return(runtimeGraph); } _logger.LogVerbose(Strings.Log_ScanningForRuntimeJson); runtimeGraph = RuntimeGraph.Empty; // maintain visited nodes to avoid duplicate runtime graph for the same node var visitedNodes = new HashSet <string>(StringComparer.OrdinalIgnoreCase); graph.Graphs.ForEach(node => { var match = node?.Item?.Data?.Match; if (match == null) { return; } // Ignore runtime.json from rejected nodes if (node.Disposition == Disposition.Rejected) { return; } // ignore the same node again if (!visitedNodes.Add(match.Library.Name)) { return; } // Locate the package in the local repository var info = NuGetv3LocalRepositoryUtility.GetPackage(localRepositories, match.Library.Name, match.Library.Version); if (info != null) { var package = info.Package; var nextGraph = LoadRuntimeGraph(package); if (nextGraph != null) { _logger.LogVerbose(string.Format(CultureInfo.CurrentCulture, Strings.Log_MergingRuntimes, match.Library)); runtimeGraph = RuntimeGraph.Merge(runtimeGraph, nextGraph); } } }); _request.RuntimeGraphCache[graph.Framework] = runtimeGraph; return(runtimeGraph); }
public IEnumerable<RuntimeFallbacks> Expand(RuntimeGraph runtimeGraph, IEnumerable<string> runtimes) { foreach (var runtime in runtimes) { var importers = FindImporters(runtimeGraph, runtime); foreach (var importer in importers) { // ExpandRuntime return runtime itself as first item so we are skiping it yield return new RuntimeFallbacks(importer, runtimeGraph.ExpandRuntime(importer).Skip(1)); } } }
public void MergingInEmptyGraphHasNoEffect() { var graph = new RuntimeGraph(new[] { new RuntimeDescription("any"), new RuntimeDescription("win8", new[] { "any" }) }); var newGraph = RuntimeGraph.Merge(graph, RuntimeGraph.Empty); Assert.Equal(new RuntimeGraph(new[] { new RuntimeDescription("any"), new RuntimeDescription("win8", new[] { "any" }) }), newGraph); }
public void MergingInEmptyGraphHasNoEffect() { var graph = new RuntimeGraph(new[] { new RuntimeDescription("any"), new RuntimeDescription("win8", new[] { "any" }) }); var newGraph = RuntimeGraph.Merge(graph, RuntimeGraph.Empty); Assert.Equal(new RuntimeGraph(new[] { new RuntimeDescription("any"), new RuntimeDescription("win8", new[] { "any" }) }), newGraph); }
private RestoreTargetGraph(bool inConflict, NuGetFramework framework, string runtimeIdentifier, RuntimeGraph runtimeGraph, GraphNode<RemoteResolveResult> graph, ISet<RemoteMatch> install, ISet<GraphItem<RemoteResolveResult>> flattened, ISet<LibraryRange> unresolved) { InConflict = inConflict; RuntimeIdentifier = runtimeIdentifier; RuntimeGraph = runtimeGraph; Framework = framework; Graph = graph; Conventions = new ManagedCodeConventions(runtimeGraph); Install = install; Flattened = flattened; Unresolved = unresolved; }
public static void WriteRuntimeGraph(string filePath, RuntimeGraph runtimeGraph) { using (var fileStream = new FileStream(filePath, FileMode.Create)) { using (var textWriter = new StreamWriter(fileStream)) { using (var jsonWriter = new JsonTextWriter(textWriter)) { jsonWriter.Formatting = Formatting.Indented; var json = new JObject(); WriteRuntimeGraph(json, runtimeGraph); json.WriteTo(jsonWriter); } } } }
public void MergingAddsCompletelyNewRuntimes() { var leftGraph = new RuntimeGraph(new[] { new RuntimeDescription("any"), new RuntimeDescription("win8", new[] { "any", "win7" }) }); var rightGraph = new RuntimeGraph(new[] { new RuntimeDescription("win7") }); var graph = RuntimeGraph.Merge(leftGraph, rightGraph); Assert.Equal(new RuntimeGraph(new[] { new RuntimeDescription("any"), new RuntimeDescription("win8", new[] { "any", "win7" }), new RuntimeDescription("win7") }), graph); }
public void MergingAddsCompletelyNewRuntimes() { var leftGraph = new RuntimeGraph(new[] { new RuntimeDescription("any"), new RuntimeDescription("win8", new[] { "any", "win7" }) }); var rightGraph = new RuntimeGraph(new[] { new RuntimeDescription("win7") }); var graph = RuntimeGraph.Merge(leftGraph, rightGraph); Assert.Equal(new RuntimeGraph(new[] { new RuntimeDescription("any"), new RuntimeDescription("win8", new[] { "any", "win7" }), new RuntimeDescription("win7") }), graph); }
public ManagedCodeConventions(RuntimeGraph runtimeGraph) { _runtimeGraph = runtimeGraph; var props = new Dictionary<string, ContentPropertyDefinition>(); props[TfmProperty.Name] = TfmProperty; props[AnyProperty.Name] = AnyProperty; props[AssemblyProperty.Name] = AssemblyProperty; props[LocaleProperty.Name] = LocaleProperty; props[MSBuildProperty.Name] = MSBuildProperty; props[PropertyNames.RuntimeIdentifier] = new ContentPropertyDefinition( PropertyNames.RuntimeIdentifier, compatibilityTest: RuntimeIdentifier_CompatibilityTest); Properties = new ReadOnlyDictionary<string, ContentPropertyDefinition>(props); Criteria = new ManagedCodeCriteria(this); Patterns = new ManagedCodePatterns(this); }
public void MergingCombinesDependenciesInDependencySetsDefinedInBoth() { var leftGraph = new RuntimeGraph(new[] { new RuntimeDescription("any"), new RuntimeDescription("win8", new[] { "any", "win7" }, new[] { new RuntimeDependencySet("Foo", new[] { new RuntimePackageDependency("Foo.win8", new VersionRange(new NuGetVersion(1, 2, 3))) }), }) }); var rightGraph = new RuntimeGraph(new[] { new RuntimeDescription("win8", new[] { new RuntimeDependencySet("Foo", new[] { new RuntimePackageDependency("Foo.more.win8", new VersionRange(new NuGetVersion(4, 5, 6))) }), }) }); var graph = RuntimeGraph.Merge(leftGraph, rightGraph); Assert.Equal(new RuntimeGraph(new[] { new RuntimeDescription("any"), new RuntimeDescription("win8", new[] { "any", "win7" }, new[] { new RuntimeDependencySet("Foo", new[] { new RuntimePackageDependency("Foo.win8", new VersionRange(new NuGetVersion(1, 2, 3))), new RuntimePackageDependency("Foo.more.win8", new VersionRange(new NuGetVersion(4, 5, 6))) }), }), }), leftGraph); }
public void ExpandShouldExpandRuntimeBasedOnGraph(string start, string expanded) { var graph = new RuntimeGraph(new[] { new RuntimeDescription("win8-x86", new[] { "win8", "win7-x86" }), new RuntimeDescription("win8", new[] { "win7" }), new RuntimeDescription("win7-x86", new[] { "win7" }), new RuntimeDescription("win7"), }); Assert.Equal( expanded.Split(','), graph.ExpandRuntime(start).ToArray()); }
public static RestoreTargetGraph Create( bool inConflict, NuGetFramework framework, string runtimeIdentifier, RuntimeGraph runtimeGraph, GraphNode<RemoteResolveResult> graph, RemoteWalkContext context, ILogger log) { var install = new HashSet<RemoteMatch>(); var flattened = new HashSet<GraphItem<RemoteResolveResult>>(); var unresolved = new HashSet<LibraryRange>(); graph.ForEach(node => { if (node == null || node.Key == null || node.Disposition == Disposition.Rejected) { return; } if (node.Item == null || node.Item.Data.Match == null) { if (node.Key.TypeConstraint != LibraryTypes.Reference && node.Key.VersionRange != null) { unresolved.Add(node.Key); } return; } if (!string.Equals(node.Item.Data.Match.Library.Name, node.Key.Name, StringComparison.Ordinal)) { // Fix casing of the library name to be installed node.Item.Data.Match.Library.Name = node.Key.Name; } // If the package came from a remote library provider, it needs to be installed locally var isRemote = context.RemoteLibraryProviders.Contains(node.Item.Data.Match.Provider); if (isRemote) { install.Add(node.Item.Data.Match); } flattened.Add(node.Item); }); return new RestoreTargetGraph( inConflict, framework, runtimeIdentifier, runtimeGraph, graph, install, flattened, unresolved); }
private Task<RestoreTargetGraph[]> WalkRuntimeDependencies(LibraryRange projectRange, RestoreTargetGraph graph, RuntimeGraph projectRuntimeGraph, RemoteDependencyWalker walker, RemoteWalkContext context, NuGetv3LocalRepository localRepository) { // Load runtime specs _log.LogVerbose("Scanning packages for runtime.json files..."); var runtimeGraph = projectRuntimeGraph; graph.Graph.ForEach(node => { var match = node?.Item?.Data?.Match; if (match == null) { return; } // Locate the package in the local repository var package = localRepository.FindPackagesById(match.Library.Name).FirstOrDefault(p => p.Version == match.Library.Version); if (package != null) { var nextGraph = LoadRuntimeGraph(package); if (nextGraph != null) { _log.LogVerbose($"Merging in runtimes defined in {match.Library}"); runtimeGraph = RuntimeGraph.Merge(runtimeGraph, nextGraph); } } }); var resultGraphs = new List<Task<RestoreTargetGraph>>(); foreach (var runtimeName in projectRuntimeGraph.Runtimes.Keys) { _log.LogInformation($"Restoring packages for {graph.Framework} on {runtimeName}"); resultGraphs.Add(WalkDependencies(projectRange, graph.Framework, runtimeName, runtimeGraph, walker, context)); } return Task.WhenAll(resultGraphs); }
private async Task<RestoreTargetGraph> WalkDependencies(LibraryRange projectRange, NuGetFramework framework, string runtimeIdentifier, RuntimeGraph runtimeGraph, RemoteDependencyWalker walker, RemoteWalkContext context) { _log.LogInformation($"Restoring packages for {framework}"); var graph = await walker.WalkAsync( projectRange, framework, runtimeIdentifier, runtimeGraph); // Resolve conflicts _log.LogVerbose($"Resolving Conflicts for {framework}"); var inConflict = !graph.TryResolveConflicts(); // Flatten and create the RestoreTargetGraph to hold the packages return RestoreTargetGraph.Create(inConflict, framework, runtimeIdentifier, runtimeGraph, graph, context, _log); }
private async Task<GraphNode<RemoteResolveResult>> CreateGraphNode(Dictionary<LibraryRange, Task<GraphItem<RemoteResolveResult>>> cache, LibraryRange libraryRange, NuGetFramework framework, string runtimeName, RuntimeGraph runtimeGraph, Func<string, bool> predicate) { var node = new GraphNode<RemoteResolveResult>(libraryRange) { Item = await FindLibraryCached(cache, libraryRange, framework), }; if (node.Item == null) { // Reject null items node.Disposition = Disposition.Rejected; } else { if (node.Key.VersionRange != null && node.Key.VersionRange.IsFloating) { lock (cache) { if (!cache.ContainsKey(node.Key)) { cache[node.Key] = Task.FromResult(node.Item); } } } var tasks = new List<Task<GraphNode<RemoteResolveResult>>>(); var dependencies = node.Item.Data.Dependencies ?? Enumerable.Empty<LibraryDependency>(); foreach (var dependency in dependencies) { if (predicate(dependency.Name)) { tasks.Add(CreateGraphNode(cache, dependency.LibraryRange, framework, runtimeName, runtimeGraph, ChainPredicate(predicate, node.Item, dependency))); if (!string.IsNullOrEmpty(runtimeName) && runtimeGraph != null) { // Look up any additional dependencies for this package foreach (var runtimeDependency in runtimeGraph.FindRuntimeDependencies(runtimeName, dependency.Name)) { // Add the dependency to the tasks var runtimeLibraryRange = new LibraryRange() { Name = runtimeDependency.Id, VersionRange = runtimeDependency.VersionRange }; tasks.Add(CreateGraphNode( cache, runtimeLibraryRange, framework, runtimeName, runtimeGraph, ChainPredicate(predicate, node.Item, dependency))); } } } } while (tasks.Any()) { var task = await Task.WhenAny(tasks); tasks.Remove(task); var dependencyNode = await task; // Not required for anything dependencyNode.OuterNode = node; node.InnerNodes.Add(dependencyNode); } } return node; }
public Task<GraphNode<RemoteResolveResult>> WalkAsync(LibraryRange library, NuGetFramework framework, string runtimeIdentifier, RuntimeGraph runtimeGraph) { var cache = new Dictionary<LibraryRange, Task<GraphItem<RemoteResolveResult>>>(); return CreateGraphNode(cache, library, framework, runtimeIdentifier, runtimeGraph, _ => true); }