public static DependencyGraph LoadGraph(Config config, List<OutputEntry> warnings) { ProjectLoader[] loaders = { new VsProjectsLoader(), new EclipseProjectsLoader() }; var builder = new DependencyGraphBuilder(config, warnings); loaders.ForEach(l => l.LoadProjects(config.Inputs, builder, warnings)); var graph = builder.Build(); return graph; }
protected override void InternalHandle(Output result, Config config, DependencyGraph graph) { var matches = RulesMatcher.Match(graph, config.Rules); if (!matches.Any()) { result.AppendLine("No matches found"); return; } foreach (var m in matches) { ConsoleEntryOutputer.ToConsole(m, false) .Split('\n') .ForEach(l => result.AppendLine(l)); result.AppendLine(); } }
public Config ParseLines(string filename, string[] lines) { basePath = Path.GetDirectoryName(filename); config = new Config(); var lineTypes = new Dictionary<string, Action<string, ConfigLocation>> { { "input:", ParseInput }, { "group:", ParseGroup }, { "output projects:", ParseOutputProjects }, { "output groups:", ParseOutputGroups }, { "output dependencies:", (line, loc) => ParseOutputDependencies(line, loc, false) }, { "output dependencies with errors:", (line, loc) => ParseOutputDependencies(line, loc, true) }, { "output architecture:", ParseOutputArchitecture }, { "output results:", ParseOutputResults }, { "rule:", ParseRule }, { "ignore:", ParseIgnore }, { "in output:", ParseInOutput }, }; var re = new Regex(@"(?<![a-zA-Z0-9])" + COMMENT, RegexOptions.IgnoreCase); foreach (var item in lines.Indexed()) { // Line number starts in 1 var location = new ConfigLocation(item.Index + 1, item.Item); var line = item.Item.Trim(); var m = re.Match(line); if (m.Success) line = line.Substring(0, m.Index) .Trim(); if (string.IsNullOrWhiteSpace(line)) continue; ParseLine(lineTypes, line, location); } return config; }
public static ArchitectureGraph Load(Config config, DependencyGraph graph) { var rules = config.Rules.OfType<DepenendencyRule>() .Where(r => r.Severity == Severity.Error) .Cast<Rule>() .ToList(); var libs = graph.Vertices.Where(v => v.GroupElement != null) .ToList(); var allowed = new HashSet<GroupDependency>(); var notAllowed = new HashSet<GroupDependency>(); foreach (var p1 in libs) { foreach (var p2 in libs) { if (p1.GroupElement.Name == p2.GroupElement.Name) continue; var dep = new GroupDependency(p1.GroupElement.Name, p2.GroupElement.Name); if (allowed.Contains(dep) && notAllowed.Contains(dep)) continue; var match = RulesMatcher.FindMatch(rules, Dependency.WithProject(p1, p2, new Location("a", 1))) as DependencyRuleMatch; if (match != null) { if (match.Allowed) allowed.Add(dep); else notAllowed.Add(dep); } match = RulesMatcher.FindMatch(rules, Dependency.WithLibrary(p1, p2, new Location("a", 1), null)) as DependencyRuleMatch; if (match != null) { if (match.Allowed) allowed.Add(dep); else notAllowed.Add(dep); } } } var groups = libs.Select(p => p.GroupElement.Name) .Distinct() .ToList(); var deps = new HashSet<GroupDependency>(); foreach (var g1 in groups) { foreach (var g2 in groups) { if (g1 == g2) continue; var dep = new GroupDependency(g1, g2); var isAllowed = allowed.Contains(dep); var isNotAllowed = notAllowed.Contains(dep); if (isAllowed && isNotAllowed) dep = new GroupDependency(g1, g2, GroupDependency.Types.Conflicted); else if (!isAllowed && !isNotAllowed) dep = new GroupDependency(g1, g2, GroupDependency.Types.Implicit); else if (isNotAllowed) dep = null; if (dep != null) deps.Add(dep); } } var groupGraph = new ArchitectureGraph(); groupGraph.AddVertexRange(groups); groupGraph.AddEdgeRange(deps); return groupGraph; }
public GroupsLoader(Config config, DependencyGraph graph, List<OutputEntry> warnings) { this.config = config; this.graph = graph; this.warnings = warnings; }
protected abstract void InternalHandle(Output result, Config config, DependencyGraph graph);
public DependencyGraphBuilder(Config config, List<OutputEntry> warnings) { this.config = config; this.warnings = warnings; }
private static bool IsLocal(Config config, Library lib) { if (lib is Project) return config.Inputs.Any(input => PathUtils.PathMatches(((Project) lib).ProjectPath, input)); else return config.Inputs.Any(input => lib.Paths.Any(p => PathUtils.PathMatches(p, input))); }