private static void TopSort(Dep dep, Dictionary <Dep, List <Dep> > graph, ISet <Dep> visitedConfigurations, List <Dep> processingConfigs, List <Dep> result, bool printCycle) { dep.UpdateConfigurationIfNull(); visitedConfigurations.Add(dep); processingConfigs.Add(dep); foreach (var d in graph[dep]) { d.UpdateConfigurationIfNull(); if (processingConfigs.Contains(d)) { if (!printCycle) { throw new CementException("Unable to build! Circular dependency found!"); } while (!processingConfigs.First().Equals(d)) { processingConfigs = processingConfigs.Skip(1).ToList(); } processingConfigs.Add(d); Console.WriteLine(String.Join(" ->\n", processingConfigs)); throw new CementException("Unable to build! Circular dependency found!"); } if (!visitedConfigurations.Contains(d)) { TopSort(d, graph, visitedConfigurations, processingConfigs, result, printCycle); } } processingConfigs.Remove(dep); result.Add(dep); }
private static void Dfs(Dep dep, Dictionary <Dep, List <Dep> > graph, HashSet <Dep> visitedConfigurations) { dep.UpdateConfigurationIfNull(); if (Yaml.Exists(dep.Name) && !Yaml.ConfigurationParser(dep.Name).ConfigurationExists(dep.Configuration)) { ConsoleWriter.WriteWarning($"Configuration '{dep.Configuration}' was not found in {dep.Name}. Will take full-build config"); dep.Configuration = "full-build"; } visitedConfigurations.Add(dep); graph[dep] = new List <Dep>(); if (!Directory.Exists(Path.Combine(Helper.CurrentWorkspace, dep.Name))) { throw new CementBuildException("Failed to find module '" + dep.Name + "'"); } var currentDeps = new DepsParser(Path.Combine(Helper.CurrentWorkspace, dep.Name)).Get(dep.Configuration).Deps ?? new List <Dep>(); currentDeps = currentDeps.Select(d => new Dep(d.Name, null, d.Configuration)).ToList(); foreach (var d in currentDeps) { d.UpdateConfigurationIfNull(); graph[dep].Add(d); if (!visitedConfigurations.Contains(d)) { Dfs(d, graph, visitedConfigurations); } } }
private static bool Dfs(Dep dep, List <string> cycle) { dep.UpdateConfigurationIfNull(); var depNameAndConfig = dep.Name + Helper.ConfigurationDelimiter + dep.Configuration; ModulesInProcessing.Add(depNameAndConfig); VisitedConfigurations.Add(depNameAndConfig); var deps = new DepsParser(Path.Combine(Helper.CurrentWorkspace, dep.Name)).Get(dep.Configuration).Deps ?? new List <Dep>(); foreach (var d in deps) { d.UpdateConfigurationIfNull(); var currentDep = d.Name + Helper.ConfigurationDelimiter + d.Configuration; if (ModulesInProcessing.Contains(currentDep)) { cycle.Add(currentDep); cycle.Add(depNameAndConfig); return(true); } if (VisitedConfigurations.Contains(currentDep)) { continue; } if (Dfs(d, cycle)) { cycle.Add(depNameAndConfig); return(true); } } ModulesInProcessing.Remove(depNameAndConfig); return(false); }
private void PrintProcessedModuleInfo(Dep dep, GetInfo getInfo, string treeish) { var longestModuleName = modules.Select(m => m.Name.Length).Max() + 5; dep.UpdateConfigurationIfNull(); var name = dep.Name + (dep.Configuration == null || dep.Configuration.Equals("full-build") ? "" : Helper.ConfigurationDelimiter + dep.Configuration); var outputTreeish = getInfo.Forced && !treeish.Equals("master") ? treeish + " *forced" : dep.Treeish ?? "master"; if (getInfo.HookUpdated) { outputTreeish += " (hook updated) "; } if (getInfo.Pulled) { outputTreeish += " *pulled"; ConsoleWriter.Shared.WriteUpdate(GetPrintString(longestModuleName, name, outputTreeish, getInfo.CommitInfo)); Log.LogDebug($"{"[" + dep.Name + "]",-30}{outputTreeish,-18} {getInfo.CommitInfo}"); return; } if (getInfo.ForcedLocal) { outputTreeish += " *forced local"; ConsoleWriter.Shared.WriteWarning(GetPrintString(longestModuleName, name, outputTreeish, getInfo.CommitInfo)); Log.LogDebug($"{"[" + dep.Name + "]",-30}{outputTreeish,-18} {getInfo.CommitInfo}"); return; } if (getInfo.Reset) { outputTreeish += " *reset"; ConsoleWriter.Shared.WriteWarning(GetPrintString(longestModuleName, name, outputTreeish, getInfo.CommitInfo)); Log.LogDebug($"{"[" + dep.Name + "]",-30}{outputTreeish,-18} {getInfo.CommitInfo}"); return; } if (getInfo.Changed || getInfo.Cloned) { Log.LogDebug($"{"[" + dep.Name + "]",-30}{outputTreeish + (getInfo.Cloned ? " *cloned" : " *changed"),-18} {getInfo.CommitInfo}"); ConsoleWriter.Shared.WriteUpdate(GetPrintString(longestModuleName, name, outputTreeish, getInfo.CommitInfo)); } else { Log.LogDebug($"{"[" + dep.Name + "]",-30}{outputTreeish + " *skipped",-18} {getInfo.CommitInfo}"); ConsoleWriter.Shared.WriteSkip(GetPrintString(longestModuleName, name, outputTreeish, getInfo.CommitInfo)); } }
private static void CheckAndUpdateDepConfiguration(Dep dep) { dep.UpdateConfigurationIfNull(); var key = dep.ToString(); if (!DepConfigurationExistsCache.ContainsKey(key)) { if (!Directory.Exists(Path.Combine(Helper.CurrentWorkspace, dep.Name))) { throw new CementBuildException("Failed to find module '" + dep.Name + "'"); } DepConfigurationExistsCache[key] = !Yaml.Exists(dep.Name) || Yaml.ConfigurationParser(dep.Name).ConfigurationExists(dep.Configuration); } if (!DepConfigurationExistsCache[key]) { ConsoleWriter.WriteWarning( $"Configuration '{dep.Configuration}' was not found in {dep.Name}. Will take full-build config"); dep.Configuration = "full-build"; } }