public UniqueProjectRule(Func<Project, bool> filter, Func<Project, string> id, Func<Project, string> description, Severity severity, ConfigLocation location) : base(severity, location) { this.filter = filter; this.id = id; this.description = description; }
private static OutputMessage CreateMessage(string type, ConfigLocation location) { return new OutputMessage().Append("The ") .Append(type) .Append(" defined in ") .Append(location.LineNum) .Append(" of config file is never used: ") .Append(location.LineText); }
public DepenendencyRule(Severity severity, LibraryMatcher source, LibraryMatcher target, DependencyMatcher dependency, bool allow, ConfigLocation location) : base(severity, location) { Source = source ?? ((l, r) => true); Target = target ?? ((l, r) => true); Dependency = dependency ?? ((d, r) => true); Allow = allow; }
public Ignore(LibraryMatcher matches, ConfigLocation location) { Matches = matches; Location = location; }
public LibraryMatcher ParseLibraryMatcher(string matchLine, ConfigLocation location) { return ParseInternediaryLibraryMatcher(matchLine, location) .Finalize(); }
private void ParseRule(string line, ConfigLocation location) { var severity = Severity.Error; DependencyMatcher dependencyFilter = null; if (line.EndsWith("]")) { var start = line.LastIndexOf("[", StringComparison.InvariantCulture); var details = line.Substring(start + 1, line.Length - start - 2); line = line.Substring(0, start) .Trim(); foreach (var detail in details.Split(',') .Select(d => d.Trim())) { Severity tmp; if (severities.TryGetValue(detail.ToLower(), out tmp)) severity = tmp; else dependencyFilter = dependencyFilter.And(ParseDependencyMatcher(detail, location)); } } var factory = customRules.Get(line.ToLower()); if (factory != null) { config.Rules.Add(factory(location, severity, dependencyFilter)); return; } if (ParseRule(line, location, NOT_DEPENDS, severity, dependencyFilter)) return; if (ParseRule(line, location, DEPENDS, severity, dependencyFilter)) return; throw new ConfigParserException(location, "Invalid rule"); }
private void ParseOutputProjects(string line, ConfigLocation location) { config.Output.Projects.Add(PathUtils.ToAbsolute(basePath, line)); }
private void ParseOutputArchitecture(string line, ConfigLocation location) { var file = PathUtils.ToAbsolute(basePath, line); var extension = Path.GetExtension(file) ?? ""; if (extension.Equals(".xml", StringComparison.CurrentCultureIgnoreCase)) config.Output.Architecture.Add(new XMLArchitectureOutputer(file)); else if (extension.Equals(".dot", StringComparison.CurrentCultureIgnoreCase)) config.Output.Architecture.Add(new DotArchitectureOutputer(file)); else config.Output.Architecture.Add(new TextArchitectureOutputer(file)); }
private InternediaryLibraryMatcher ParseInternediaryLibraryMatcher(string matchLine, ConfigLocation location) { InternediaryLibraryMatcher result = null; var lineTypes = new Dictionary<string, Action<string, ConfigLocation>> { { "not:", (line, loc) => { InternediaryLibraryMatcher matcher = ParseInternediaryLibraryMatcher(line, loc); result = (library, reporter) => !matcher(library, (f, v, m) => reporter(f, v, !m)); } }, { "local:", (line, loc) => result = Matchers.Projects.Place(true) .And(ParseInternediaryLibraryMatcher(line, loc)) }, { "non local:", (line, loc) => result = Matchers.Projects.Place(false) .And(ParseInternediaryLibraryMatcher(line, loc)) }, { "project:", (line, loc) => result = Matchers.Projects.Type(true) .And(ParseInternediaryLibraryMatcher(line, loc)) }, { "lib:", (line, loc) => result = Matchers.Projects.Type(false) .And(ParseInternediaryLibraryMatcher(line, loc)) }, { "regex:", (line, loc) => result = Matchers.Projects.NameRE(line) }, { "path:", (line, loc) => result = Matchers.Projects.Path(basePath, line) }, { "path regex:", (line, loc) => result = Matchers.Projects.PathRE(line) }, { "lang:", (line, loc) => result = Matchers.Projects.Language(line) }, { "", (line, loc) => result = Matchers.Projects.Name(line) }, }; ParseLine(lineTypes, matchLine, location); return result; }
private void ParseInput(string line, ConfigLocation configLocation) { string absolute = PathUtils.ToAbsolute(basePath, line); config.Inputs.Add(PathUtils.RemoveSeparatorAtEnd(absolute)); }
public NoCircularDepenendenciesRule(Severity severity, ConfigLocation location) : base(severity, location) { }
public UnusedConfigOutputEntry(string type, ConfigLocation location) : base("Config/Unused " + type, Severity.Info, CreateMessage(type, location)) { Location = location; }
public ConfigParserException(ConfigLocation location, string message) : this(string.Format("{0} in line {1}: {2}", message, location.LineNum, location.LineText)) { }
private void ParseIgnore(string line, ConfigLocation location) { var matcher = ParseLibraryMatcher(line, location); config.Ignores.Add(new Config.Ignore(matcher, location)); }
protected BaseRule(Severity severity, ConfigLocation location) { Severity = severity; Location = location; }
private void ParseInOutput(string line, ConfigLocation location) { if (line == "ignore loading infos") config.InOutput.Ignore.Add(w => w.Type.StartsWith("Loading/")); else if (line == "ignore config infos") config.InOutput.Ignore.Add(w => w.Type.StartsWith("Config/")); else throw new ConfigParserException(location, "Invalid line"); }
public UniqueDependenciesRule(Severity severity, DependencyMatcher filter, ConfigLocation location) : base(severity, location) { this.filter = filter ?? ((d, r) => true); }
private InternediaryDependencyMatcher ParseInternediaryDependencyMatcher(string detail, ConfigLocation location) { InternediaryDependencyMatcher result = null; var lineTypes = new Dictionary<string, Action<string, ConfigLocation>> { { "not:", (line, loc) => { var matcher = ParseInternediaryDependencyMatcher(line, loc); result = (library, reporter) => !matcher(library, (f, v, m) => reporter(f, v, !m)); } }, { "dep:", (line, loc) => result = Matchers.Dependencies.Type(line) }, { "dep path:", (line, loc) => result = Matchers.Dependencies.Path(basePath, line) }, { "dep path regex:", (line, loc) => result = Matchers.Dependencies.PathRE(line) }, }; ParseLine(lineTypes, detail, location); return result; }
private static NoCircularDepenendenciesRule NewNoCircularDepenendenciesRule(ConfigLocation l, Severity s, DependencyMatcher d) { if (d != null) throw new ConfigParserException(l, "No dependency details are possible in project rules"); return new NoCircularDepenendenciesRule(s, l); }
private void ParseLine(Dictionary<string, Action<string, ConfigLocation>> types, string line, ConfigLocation location) { var type = types.FirstOrDefault(t => t.Key == "" || line.StartsWith(t.Key)); if (type.Value == null) throw new ConfigParserException(location, "Unknown line"); var remaining = line.Substring(type.Key.Length) .Trim(); if (type.Key == "" && remaining.IndexOf(':') >= 0) throw new ConfigParserException(location, "Invalid expression"); try { type.Value(remaining, location); } catch (ConfigParserException) { throw; } catch (Exception e) { throw new ConfigParserException(location, e.Message); } }
private static UniqueProjectRule NewUniqueGuidProjectRule(ConfigLocation l, Severity s, DependencyMatcher d) { if (d != null) throw new ConfigParserException(l, "No dependency details are possible in project rules"); return new UniqueProjectRule(p => p.Guid != null, p => p.Guid.ToString(), p => "with GUID " + p.Guid, s, l); }
// ReSharper disable once UnusedParameter.Local private void ParseOutputDependencies(string line, ConfigLocation location, bool onlyWithMessages) { var file = PathUtils.ToAbsolute(basePath, line); var extension = Path.GetExtension(file) ?? ""; if (extension.Equals(".xml", StringComparison.CurrentCultureIgnoreCase)) config.Output.Dependencies.Add(FilterIfNeeded(onlyWithMessages, new XMLDependenciesOutputer(file))); else if (extension.Equals(".dot", StringComparison.CurrentCultureIgnoreCase)) config.Output.Dependencies.Add(FilterIfNeeded(onlyWithMessages, new DotDependenciesOutputer(file))); else config.Output.Dependencies.Add(FilterIfNeeded(onlyWithMessages, new TextDependenciesOutputer(file))); }
private static UniqueProjectRule NewUniqueNameProjectRule(ConfigLocation l, Severity s, DependencyMatcher d) { if (d != null) throw new ConfigParserException(l, "No dependency details are possible in project rules"); return new UniqueProjectRule(p => p.ProjectName != null, p => p.Name, p => "named " + p.Name, s, l); }
private void ParseOutputResults(string line, ConfigLocation location) { if (line.Equals("console", StringComparison.CurrentCultureIgnoreCase)) config.Output.Results.Add(new ConsoleEntryOutputer(false)); else if (line.Equals("console verbose", StringComparison.CurrentCultureIgnoreCase)) config.Output.Results.Add(new ConsoleEntryOutputer(true)); else { var file = PathUtils.ToAbsolute(basePath, line); var extension = Path.GetExtension(file) ?? ""; if (extension.Equals(".xml", StringComparison.CurrentCultureIgnoreCase)) config.Output.Results.Add(new XMLEntryOutputer(file)); else config.Output.Results.Add(new TextEntryOutputer(file)); } }
private DependencyMatcher ParseDependencyMatcher(string detail, ConfigLocation location) { return ParseInternediaryDependencyMatcher(detail, location) .Finalize(); }
private bool ParseRule(string line, ConfigLocation location, string separator, Severity severity, DependencyMatcher dependencyFilter) { var pos = line.IndexOf(separator, StringComparison.Ordinal); if (pos < 0) return false; var left = ParseLibraryMatcher(line.Substring(0, pos) .Trim(), location); var right = ParseLibraryMatcher(line.Substring(pos + separator.Length) .Trim(), location); config.Rules.Add(new DepenendencyRule(severity, left, right, dependencyFilter, separator == DEPENDS, location)); return true; }
private void ParseGroup(string line, ConfigLocation location) { int pos = line.IndexOf(GROUP_ELEMENT, StringComparison.CurrentCultureIgnoreCase); if (pos < 0) throw new ConfigParserException(location, "Invalid group (should contain Name " + GROUP_ELEMENT + " Contents)"); string name = line.Substring(0, pos) .Trim(); if ("<No Group>".Equals(name, StringComparison.CurrentCultureIgnoreCase)) name = null; string matchLine = line.Substring(pos + DEPENDS.Length) .Trim(); LibraryMatcher matcher = ParseLibraryMatcher(matchLine, location); config.Groups.Add(new Config.Group(name, matcher, location)); }
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 Group(string name, LibraryMatcher matches, ConfigLocation location) { Name = name; Matches = matches; Location = location; }