public void CircularDependency() { var a = new Node("A"); var b = new Node("B"); var c = new Node("C"); var d = new Node("D"); var e = new Node("E"); a.Dependencies = new Collection <Node> { b, d }; b.Dependencies = new Collection <Node> { c, e }; c.Dependencies = new Collection <Node> { d, e }; e.Dependencies = new Collection <Node> { a }; DependencySorter.SortDependencies(new Collection <Node> { a, b, c, d, e }); }
public void SortTest() { var a = new Node("A"); var b = new Node("B"); var c = new Node("C"); var d = new Node("D"); var e = new Node("E"); a.Dependencies = new Collection <Node> { b, d }; b.Dependencies = new Collection <Node> { c, e }; c.Dependencies = new Collection <Node> { d, e }; var expected = new List <Node> { d, e, c, b, a }; var actual = DependencySorter.SortDependencies(new Collection <Node> { a, b, c, d, e }).ToList(); Assert.Equal(expected, actual); }
public void PartiallySorted() { var a = new Node("A"); var b = new Node("B"); var c = new Node("C"); var d = new Node("D"); var e = new Node("E"); a.Dependencies = new Collection <Node> { }; b.Dependencies = new Collection <Node> { a }; c.Dependencies = new Collection <Node> { b }; d.Dependencies = new Collection <Node> { e }; e.Dependencies = new Collection <Node> { }; var expected = new List <Node> { a, b, c, e, d }; var actual = DependencySorter.SortDependencies(new Collection <Node> { a, b, c, d, e }).ToList(); CollectionAssert.AreEqual(expected, actual); }
public void CircularDependency() { var a = new Node("A"); var b = new Node("B"); var c = new Node("C"); var d = new Node("D"); var e = new Node("E"); a.Dependencies = new Collection <Node> { b, d }; b.Dependencies = new Collection <Node> { c, e }; c.Dependencies = new Collection <Node> { d, e }; e.Dependencies = new Collection <Node> { a }; Assert.Throws <InvalidOperationException>(() => DependencySorter.SortDependencies(new Collection <Node> { a, b, c, d, e })); }
private static void BuildCar(string dependenciesPath) { //builds the car var input = File.OpenText(dependenciesPath); DependencySorter<String> sorter = new DependencySorter<string>(); for (string line; (line = input.ReadLine()) != null; ) {//go through each line in input file, parse the dependencies, and add to the DependencySorter object //split line based on dependancy string[] splitDependancy = Regex.Split(line, "->"); //trim the objects var objectName = splitDependancy[0].Trim(); var dependantObject = splitDependancy[1].Trim(); //add the parts required sorter.AddCarPart(objectName); sorter.AddCarPart(dependantObject); //add a dependancy relationship sorter.AddDependantRelationship(dependantObject, objectName); } try { //now, finally sort the loaded user generated list of dependancies var result = sorter.SortDependancies(); //output to a file named output.txt StreamWriter file = new System.IO.StreamWriter("output.txt"); result.ForEach(file.WriteLine); file.Close(); foreach (var val in result) {//output to screen Console.Write(val + "\n"); } } catch (CircularException ce) { Console.ForegroundColor = ConsoleColor.Red; Console.Write("Error: " + ce.Message); Console.ResetColor(); } catch (Exception e) { Console.ForegroundColor = ConsoleColor.Red; Console.Write("Error: " + e.Message); Console.ResetColor(); } Console.ForegroundColor = ConsoleColor.Green; Console.Write("\nOutput complete\nPress Return To Continue, Please"); Console.ResetColor(); Console.ReadLine(); }
/// <summary> /// Called to write the js and css to string output /// </summary> /// <param name="allDependencies"></param> /// <param name="paths"></param> /// <param name="jsOutput"></param> /// <param name="cssOutput"></param> /// <param name="http"></param> internal void WriteDependencies(List <IClientDependencyFile> allDependencies, HashSet <IClientDependencyPath> paths, out string jsOutput, out string cssOutput, HttpContextBase http) { //create the hash to see if we've already stored it var hashCodeCombiner = new HashCodeCombiner(); foreach (var d in allDependencies) { hashCodeCombiner.AddObject(d); } var hash = hashCodeCombiner.GetCombinedHashCode(); //we may have already processed this so don't do it again if (http.Items["BaseRenderer.RegisterDependencies." + hash] == null) { var folderPaths = paths; UpdateFilePaths(allDependencies, folderPaths, http); EnsureNoDuplicates(allDependencies, folderPaths); //now we regenerate the hash since dependencies have been removed/etc.. // and update the context items so it's not run again hashCodeCombiner = new HashCodeCombiner(); foreach (var d in allDependencies) { hashCodeCombiner.AddObject(d); } hash = hashCodeCombiner.GetCombinedHashCode(); http.Items["BaseRenderer.RegisterDependencies." + hash] = true; } var cssBuilder = new StringBuilder(); var jsBuilder = new StringBuilder(); //group by the group and order by the value foreach (var group in allDependencies.GroupBy(x => x.Group).OrderBy(x => x.Key)) { //sort both the js and css dependencies properly var jsDependencies = DependencySorter.SortItems( group.Where(x => x.DependencyType == ClientDependencyType.Javascript).ToList()); var cssDependencies = DependencySorter.SortItems( group.Where(x => x.DependencyType == ClientDependencyType.Css).ToList()); //render WriteStaggeredDependencies(cssDependencies, http, cssBuilder, RenderCssDependencies, RenderSingleCssFile); WriteStaggeredDependencies(jsDependencies, http, jsBuilder, RenderJsDependencies, RenderSingleJsFile); } cssOutput = cssBuilder.ToString(); jsOutput = jsBuilder.ToString(); }
public void Sort_CollectionWithCircularReference_ThrowsException() { var collection = DependencyTestData.CreateTestDataWithCircularReference(); var sorter = new DependencySorter <string>(collection); var exception = Assert.Throws <CircularReferenceException>(() => sorter.Sort()); Assert.Contains(exception.PossibleCircularReferences, x => (string)x == DependencyTestData.Application); Assert.Contains(exception.PossibleCircularReferences, x => (string)x == DependencyTestData.Shell); }
public void SimpleTest() { var prop = new Node("Property"); var val = new Node("Value"); val.Dependencies = new Collection <Node> { prop }; var expected = new List <Node> { prop, val }; var actual = DependencySorter.SortDependencies(new Collection <Node> { prop, val }).ToList(); CollectionAssert.AreEqual(expected, actual); }
private static void SortPackages() { var dependencySorter = new DependencySorter <PluginPackage>(); foreach (var package in packages) { Trace.WriteLine("Sorting " + package.Name); dependencySorter.AddObjects(package); var dependencies = new List <PluginPackage>(); foreach (var reference in package.References) { dependencies.Add(packages.First(p => p.Id == reference.Id)); } if (dependencies.Count > 0) { dependencySorter.SetDependencies(package, dependencies.ToArray()); } } packages = dependencySorter.Sort().ToList(); }
internal static int[] GetDependencySortOrder(IReadOnlyList <DataMatrixColumn> fields) { var g = new DependencySorter <int>(); g.AddObjects(fields.Select(c => c.Index).ToArray()); //add edges foreach (var field in fields) { if (field.DependsOn != null) { var dependsOn = GetIndexes(fields, field.DependsOn).ToArray(); g.SetDependencies(field.Index, dependsOn); } } var result = g.Sort(); return(result); }
public void Sort_CorrectCollection_ReturnCorrectSortedElements() { var collection = DependencyTestData.CreateTestData(); var sorter = new DependencySorter <string>(collection); var result = sorter.Sort().ToArray(); var expected = new[] { DependencyTestData.Cpu, DependencyTestData.Kernel, DependencyTestData.VgaDriver, DependencyTestData.Shell, DependencyTestData.Application }; Assert.Equal(expected, result); }
public static void LoadPlugins(String folder, PluginContext context) { try { PluginSystem.folder = folder; PluginSystem.context = context; Assembly.ReflectionOnlyLoadFrom(Path.Combine(folder, @"..\SharpCraft.dll")); var list = new DependencySorter<String>(); Trace.WriteLine("Locating plugins . . ."); Trace.Indent(); var sw = Stopwatch.StartNew(); foreach (var file in Directory.GetFiles(folder, "*.dll", SearchOption.AllDirectories)) { try { Trace.WriteLine("File: " + Path.GetFileName(file)); Trace.Indent(); var assembly = Assembly.ReflectionOnlyLoadFrom(file); foreach (var type in assembly.GetTypes().Where(t => t.Implements<IPlugin>())) { try { Trace.WriteLine("Type: " + type.FullName); assemblies.Add(type.FullName, file); list.AddObjects(type.FullName); Trace.Indent(); foreach (var requires in type.GetRequires()) { list.SetDependencies(type.FullName, requires); Trace.WriteLine("Requires: " + requires); } Trace.Unindent(); } catch (Exception e) { Trace.WriteLine("Exception: " + e.Message); } } Trace.Unindent(); } catch (ReflectionTypeLoadException e) { Trace.WriteLine("Exception: " + e); Trace.Indent(); foreach (var exception in e.LoaderExceptions) { Trace.WriteLine("LoaderException: " + exception); } Trace.Unindent(); } } sw.Stop(); Trace.WriteLine("Done! (" + sw.Elapsed.TotalMilliseconds.ToString("0.00") + " ms)"); Trace.Unindent(); Trace.WriteLine("Loading plugin assemblies and instanciating types. . ."); Trace.Indent(); sw.Restart(); foreach (var s in list.Sort()) { Trace.WriteLine("Loading assembly '" + Path.GetFileName(assemblies[s]) + "' for type '" + s + "'"); plugins.Add((IPlugin)Activator.CreateInstance(assemblies[s], s).Unwrap()); } sw.Stop(); Trace.WriteLine("Done! (" + sw.Elapsed.TotalMilliseconds.ToString("0.00") + " ms)"); Trace.Unindent(); Trace.WriteLine("Initializing plugins . . ."); Trace.Indent(); sw.Restart(); foreach (var plugin in plugins) { Trace.WriteLine("Initializing " + plugin.GetType().FullName); Trace.Indent(); try { plugin.Initialize(context); } catch (Exception e) { Trace.WriteLine(e); } Trace.Unindent(); } sw.Stop(); Trace.WriteLine("Done! (" + sw.Elapsed.TotalMilliseconds.ToString("0.00") + " ms)"); Trace.Unindent(); } catch (Exception exception) { MessageBox.Show( "Fatal exception!" + Environment.NewLine + exception + Environment.NewLine + "Aborting execution!", typeof(PluginSystem) + ".Initialize()", MessageBoxButton.OK, MessageBoxImage.Error); Process.GetCurrentProcess().Kill(); } }
internal static void LoadPlugins(string folder) { try { var list = new DependencySorter <string>(); Trace.WriteLine("Locating plugins . . ."); Trace.Indent(); var sw = Stopwatch.StartNew(); foreach (var file in Directory.GetFiles(folder, "*.dll", SearchOption.AllDirectories)) { try { string fileName = Path.GetFileName(file); if (fileName == "Cirnix.JassNative.Runtime.dll") { continue; } string version = "null"; try { version = FileVersionInfo.GetVersionInfo(file).FileVersion; } catch { } Trace.WriteLine($"File: {fileName} ({version})"); Trace.Indent(); var assembly = Assembly.ReflectionOnlyLoadFrom(file); foreach (var type in assembly.GetTypes().Where(t => t.Implements <IPlugin>())) { try { Trace.WriteLine("Type: " + type.FullName); assemblies.Add(type.FullName, file); list.AddObjects(type.FullName); Trace.Indent(); foreach (var requires in type.GetRequires()) { list.SetDependencies(type.FullName, requires); Trace.WriteLine("Requires: " + requires); } Trace.Unindent(); } catch (Exception e) { Trace.WriteLine("Exception: " + e.Message); } } Trace.Unindent(); } catch (ReflectionTypeLoadException e) { Trace.WriteLine("Exception: " + e); Trace.Indent(); foreach (var exception in e.LoaderExceptions) { Trace.WriteLine("LoaderException: " + exception); } Trace.Unindent(); } } sw.Stop(); Trace.WriteLine($"Done! ({sw.Elapsed.TotalMilliseconds:0.00} ms)"); Trace.Unindent(); Trace.WriteLine("Loading plugin assemblies and instanciating types. . ."); Trace.Indent(); sw.Restart(); foreach (var s in list.Sort()) { Trace.WriteLine($"Loading assembly '{Path.GetFileName(assemblies[s])}' for type '{s}'"); try { var hObj = Activator.CreateInstance(assemblies[s], s); plugins.Add((IPlugin)hObj.Unwrap()); } catch (TargetInvocationException e) { if (e.InnerException is FileNotFoundException) { Trace.WriteLine(e.InnerException.Message); } else { throw e; } } } sw.Stop(); Trace.WriteLine($"Done! ({sw.Elapsed.TotalMilliseconds:0.00} ms)"); Trace.Unindent(); Trace.WriteLine("Initializing plugins . . ."); Trace.Indent(); sw.Restart(); foreach (var plugin in plugins) { Trace.WriteLine("Initializing " + plugin.GetType().FullName); Trace.Indent(); try { plugin.Initialize(); } catch (Exception e) { Trace.WriteLine(e); } Trace.Unindent(); } sw.Stop(); Trace.WriteLine($"Done! ({sw.Elapsed.TotalMilliseconds:0.00} ms)"); Trace.Unindent(); } catch (Exception exception) { MessageBox.Show( $"Fatal exception!{Environment.NewLine}{exception}{Environment.NewLine}Aborting execution!", $"{typeof(PluginSystem)}.Initialize()", MessageBoxButton.OK, MessageBoxImage.Error); Process.GetCurrentProcess().Kill(); } }
/// <summary> /// Creates a new <see cref="SolutionDependencyContext"/>, possibly for a different subset of projects /// of the <see cref="Solutions"/> than the default set (all projects except build projects). /// </summary> /// <param name="m">The monitor to use.</param> /// <param name="traceGraphDetails">True to trace the details of the input and output (sorted) graphs.</param> /// <param name="projectFilter"> /// Optional project filter. /// By default all projects are considered except build projects (see <see cref="Solution.BuildProject"/>). /// </param> /// <returns>The context or null on error.</returns> public SolutionDependencyContext CreateDependencyContext(IActivityMonitor m, bool traceGraphDetails, Func <IProject, bool> projectFilter = null) { if (projectFilter == null) { projectFilter = p => !p.IsBuildProject; } var sortables = new Dictionary <ISolution, SolutionItem>(); foreach (var s in _solutions) { var sItem = new SolutionItem(s, s.Projects.Where(p => projectFilter(p)).Select(p => _projects[p])); sortables.Add(s, sItem); } var options = new DependencySorterOptions(); if (traceGraphDetails) { options.HookInput = i => i.Trace(m); options.HookOutput = i => i.Trace(m); } IDependencySorterResult result = DependencySorter.OrderItems(m, sortables.Values, null, options); if (!result.IsComplete) { result.LogError(m); return(new SolutionDependencyContext(this, result, GetBuildProjectInfo(m))); } // Building the list of SolutionDependencyContext.DependencyRow. var table = result.SortedItems // 1 - Selects solutions along with their ordered index. .Where(sorted => sorted.GroupForHead == null && sorted.Item is SolutionItem) .Select(sorted => ( Solution: (Solution)sorted.StartValue, // The projects from this solution that reference packages that are // produced by local solutions have a direct requires to a Package // that has a local Project. // 2 - First Map: LocalRefs is a set of value tuple (Project Origin, Package Target). LocalRefs: sorted.Children .Select(c => (SProject: c, Project: (Project)c.StartValue)) .SelectMany(c => c.SProject.DirectRequires .Select(r => r.Item) .OfType <LocalPackageItem>() .Select(package => (Origin: c.Project, Target: package)) ))) // 3 - Second Map: Expands the LocalRefs. .SelectMany(s => s.LocalRefs.Any() ? s.LocalRefs.Select(r => new DependentSolution.Row ( s.Solution, r.Origin, r.Target.Project )) : new[] { new DependentSolution.Row(s.Solution, null, null) } ) .ToList(); // Now that the table of SolutionDependencyContext.DependencyRow is built, use it to compute the // pure solution dependency graph. // var index = new Dictionary <object, DependentSolution>(); ISolution current = null; var depSolutions = new DependentSolution[sortables.Count]; int idx = 0; foreach (var r in table) { if (current != r.Solution) { current = r.Solution; var newDependent = new DependentSolution(current, table, s => index[s]); depSolutions[idx++] = newDependent; index.Add(current.Name, newDependent); index.Add(current, newDependent); } } Array.Sort(depSolutions, (d1, d2) => { int cmp = d1.Rank - d2.Rank; if (cmp == 0) { cmp = d1.Solution.Name.CompareTo(d2.Solution.Name); } return(cmp); }); for (int i = 0; i < depSolutions.Length; ++i) { depSolutions[i].Index = i; } return(new SolutionDependencyContext(this, index, result, table, depSolutions, GetBuildProjectInfo(m))); }
/// <summary> /// Gets the information about build projects (see <see cref="Solution.BuildProject"/>) /// and their dependencies. /// </summary> /// <param name="m">The monitor to use.</param> /// <param name="traceGraphDetails">True to trace the details of the input and output (sorted) graphs.</param> /// <returns>The build projects information.</returns> BuildProjectsInfo GetBuildProjectInfo(IActivityMonitor m) { Debug.Assert(!_projects.PureProjectsMode); _projects.PureProjectsMode = true; try { using (m.OpenTrace($"Creating Build Projects information.")) { IDependencySorterResult rBuildProjects = DependencySorter.OrderItems(m, _projects.AllProjectItems.Where(p => p.Project.IsBuildProject), null); if (!rBuildProjects.IsComplete) { rBuildProjects.LogError(m); return(new BuildProjectsInfo(rBuildProjects, null)); } else { var rankedProjects = rBuildProjects.SortedItems .Where(i => i.Item is ProjectItem) .Select(i => (i.Rank, ((ProjectItem)i.Item).Project, DirectDeps: i.Requires .Select(s => s.Item) .OfType <ProjectItem>() .Select(p => p.Project), AllDeps: i.GetAllRequires() .Select(s => s.Item) .OfType <ProjectItem>() .Select(p => p.Project))); var zeroBuildProjects = rankedProjects.Select((p, idx) => new ZeroBuildProjectInfo( idx, p.Rank, p.Project, // UpgradePackages: Among direct dependencies, consider only the // published projects and the ones who are actually referenced // as a package (ignores ProjectReference). p.DirectDeps .Where(d => d.IsPublished && p.Project.PackageReferences.Any(r => d.GeneratedArtifacts .Select(a => a.Artifact) .Contains(r.Target.Artifact))) .ToArray(), // UpgradeZeroProjects: Among direct dependencies, consider all the // published projects, the ones who are actually referenced // as a package AND the ones that are ProjectReference. // ProjectReference MUST be transformed into PackageReference // during ZeroBuild. p.DirectDeps .Where(d => d.IsPublished) .ToArray(), // Dependencies: Considers all the projects. p.AllDeps.ToArray() )) .ToArray(); Debug.Assert(zeroBuildProjects.Select(z => z.Rank).IsSortedLarge()); Debug.Assert(zeroBuildProjects.Select(z => z.Index).IsSortedStrict()); return(new BuildProjectsInfo(rBuildProjects, zeroBuildProjects)); } } } finally { _projects.PureProjectsMode = false; } }
public static void LoadPlugins(String folder, PluginContext context) { try { PluginSystem.folder = folder; PluginSystem.context = context; Assembly.ReflectionOnlyLoadFrom(Path.Combine(folder, @"..\SharpCraft.dll")); var list = new DependencySorter <String>(); Trace.WriteLine("Locating plugins . . ."); Trace.Indent(); var sw = Stopwatch.StartNew(); foreach (var file in Directory.GetFiles(folder, "*.dll", SearchOption.AllDirectories)) { try { Trace.WriteLine("File: " + Path.GetFileName(file)); Trace.Indent(); var assembly = Assembly.ReflectionOnlyLoadFrom(file); foreach (var type in assembly.GetTypes().Where(t => t.Implements <IPlugin>())) { try { Trace.WriteLine("Type: " + type.FullName); assemblies.Add(type.FullName, file); list.AddObjects(type.FullName); Trace.Indent(); foreach (var requires in type.GetRequires()) { list.SetDependencies(type.FullName, requires); Trace.WriteLine("Requires: " + requires); } Trace.Unindent(); } catch (Exception e) { Trace.WriteLine("Exception: " + e.Message); } } Trace.Unindent(); } catch (ReflectionTypeLoadException e) { Trace.WriteLine("Exception: " + e); Trace.Indent(); foreach (var exception in e.LoaderExceptions) { Trace.WriteLine("LoaderException: " + exception); } Trace.Unindent(); } } sw.Stop(); Trace.WriteLine("Done! (" + sw.Elapsed.TotalMilliseconds.ToString("0.00") + " ms)"); Trace.Unindent(); Trace.WriteLine("Loading plugin assemblies and instanciating types. . ."); Trace.Indent(); sw.Restart(); foreach (var s in list.Sort()) { Trace.WriteLine("Loading assembly '" + Path.GetFileName(assemblies[s]) + "' for type '" + s + "'"); plugins.Add((IPlugin)Activator.CreateInstance(assemblies[s], s).Unwrap()); } sw.Stop(); Trace.WriteLine("Done! (" + sw.Elapsed.TotalMilliseconds.ToString("0.00") + " ms)"); Trace.Unindent(); Trace.WriteLine("Initializing plugins . . ."); Trace.Indent(); sw.Restart(); foreach (var plugin in plugins) { Trace.WriteLine("Initializing " + plugin.GetType().FullName); Trace.Indent(); try { plugin.Initialize(context); } catch (Exception e) { Trace.WriteLine(e); } Trace.Unindent(); } sw.Stop(); Trace.WriteLine("Done! (" + sw.Elapsed.TotalMilliseconds.ToString("0.00") + " ms)"); Trace.Unindent(); } catch (Exception exception) { MessageBox.Show( "Fatal exception!" + Environment.NewLine + exception + Environment.NewLine + "Aborting execution!", typeof(PluginSystem) + ".Initialize()", MessageBoxButton.OK, MessageBoxImage.Error); Process.GetCurrentProcess().Kill(); } }
private static void SortPackages() { var dependencySorter = new DependencySorter<PluginPackage>(); foreach (var package in packages) { Trace.WriteLine("Sorting " + package.Name); dependencySorter.AddObjects(package); var dependencies = new List<PluginPackage>(); foreach (var reference in package.References) { dependencies.Add(packages.First(p => p.Id == reference.Id)); } if (dependencies.Count > 0) dependencySorter.SetDependencies(package, dependencies.ToArray()); } packages = dependencySorter.Sort().ToList(); }