public PatternSet(IReadOnlyDictionary <string, ContentPropertyDefinition> properties, IEnumerable <PatternDefinition> groupPatterns, IEnumerable <PatternDefinition> pathPatterns) { GroupPatterns = groupPatterns?.ToList()?.AsReadOnly() ?? Enumerable.Empty <PatternDefinition>(); PathPatterns = pathPatterns?.ToList()?.AsReadOnly() ?? Enumerable.Empty <PatternDefinition>(); PropertyDefinitions = properties; GroupExpressions = GroupPatterns.Select(pattern => new PatternExpression(pattern)).ToArray(); PathExpressions = PathPatterns.Select(pattern => new PatternExpression(pattern)).ToArray(); }
private static bool TryMatch(string path, PathPatterns pathPatterns, out PathMatch match) { var ignoreCache = pathPatterns.IgnoreCache; // Try first to get a previously match from the cache lock (ignoreCache) { return(ignoreCache.TryGetValue(path, out match)); } }
private static void Match(string path, PathPatterns pathPatterns, ref PathMatch match) { var ignoreCache = pathPatterns.IgnoreCache; foreach (var pathPattern in pathPatterns) { if (pathPattern.Ignore.IsPathIgnored(path)) { match = new PathMatch(true, pathPattern); break; } } lock (ignoreCache) { ignoreCache.Add(path, match); } }
private void KeepEntry(SimpleCommit commit, TreeEntry entry, PathPatterns globalPattern, bool keepOnIgnore) { // Early exit if the commit was discarded by a tree-filtering if (commit.Discard) { return; } PathMatch match; var path = entry.Path; if (TryMatch(path, globalPattern, out match)) { // If path is ignored we can update the entries to keep if (match.IsIgnored) { DirectMatch(commit, entry, keepOnIgnore, ref match); } } else { var checkTask = Task.Factory.StartNew(() => { Match(path, globalPattern, ref match); // If path is ignored we can update the entries to keep if (match.IsIgnored) { DirectMatch(commit, entry, keepOnIgnore, ref match); } }); if (DisableTasks) { checkTask.RunSynchronously(); } else { lock (pendingTasks) { pendingTasks.Add(checkTask); } } } }
/// <summary> /// Prepares the filtering by processing keep and remove entries. /// </summary> /// <exception cref="GitRocketFilter.RocketException">Expecting at least a commit or tree filtering option</exception> private void PrepareFiltering() { // Prepare tree filtering keepPathPatterns = ParseTreeFilteringPathPatterns(KeepPatterns, "--keep"); removePathPatterns = ParseTreeFilteringPathPatterns(RemovePatterns, "--remove"); hasTreeFiltering = keepPathPatterns.Count > 0 || removePathPatterns.Count > 0; hasTreeFilteringWithScripts = keepPathPatterns.Any(pattern => !string.IsNullOrWhiteSpace(pattern.ScriptText)); hasTreeFilteringWithScripts = hasTreeFilteringWithScripts || removePathPatterns.Any(pattern => !string.IsNullOrWhiteSpace(pattern.ScriptText)); hasCommitFiltering = !string.IsNullOrWhiteSpace(CommitFilter); // If nothing to do, we are missing a parameter (either commit or tree filtering) if (!hasCommitFiltering && !hasTreeFiltering) { throw new RocketException("Expecting at least a commit or tree filtering option"); } }
private PathPatterns ParseTreeFilteringPathPatterns(string pathPatternsAsText, string context) { var pathPatterns = new PathPatterns(); if (string.IsNullOrWhiteSpace(pathPatternsAsText)) { return(pathPatterns); } var reader = new StringReader(pathPatternsAsText); // non scripted patterns var pathPatternsNoScript = new List <string>(); bool isInMultiLineScript = false; var multiLineScript = new StringBuilder(); string currentMultilinePath = null; string line; while ((line = reader.ReadLine()) != null) { if ((!isInMultiLineScript && string.IsNullOrWhiteSpace(line)) || line.TrimStart().StartsWith("#")) { continue; } if (isInMultiLineScript) { var endOfScriptIndex = line.IndexOf("%}", StringComparison.InvariantCultureIgnoreCase); if (endOfScriptIndex >= 0) { isInMultiLineScript = false; multiLineScript.AppendLine(line.Substring(0, endOfScriptIndex)); pathPatterns.Add(new PathPattern(tempRocketPath, currentMultilinePath, multiLineScript.ToString())); multiLineScript.Length = 0; } else { multiLineScript.AppendLine(line); } } else { var scriptIndex = line.IndexOf("=>", StringComparison.InvariantCultureIgnoreCase); if (scriptIndex >= 0) { var pathPatternText = line.Substring(0, scriptIndex).TrimEnd(); var textScript = line.Substring(scriptIndex + 2).TrimEnd(); var pathPattern = new PathPattern(tempRocketPath, pathPatternText, textScript); pathPatterns.Add(pathPattern); } else { scriptIndex = line.IndexOf("{%", StringComparison.InvariantCultureIgnoreCase); if (scriptIndex >= 0) { isInMultiLineScript = true; multiLineScript.Length = 0; currentMultilinePath = line.Substring(0, scriptIndex).TrimEnd(); var textScript = line.Substring(scriptIndex + 2).TrimEnd(); multiLineScript.AppendLine(textScript); } else { // If this is a normal path pattern line pathPatternsNoScript.Add(line.TrimEnd()); } } } } if (isInMultiLineScript) { throw new RocketException("Expecting the end %}} of multiline script: {0}", multiLineScript); } if (pathPatternsNoScript.Count > 0) { var repoFilter = new Repository(tempRocketPath); repoFilter.Ignore.ResetAllTemporaryRules(); if (Verbose) { foreach (var pattern in pathPatternsNoScript) { OutputWriter.WriteLine("Found {0} pattern [{1}]", context, pattern); } } repoFilter.Ignore.AddTemporaryRules(pathPatternsNoScript); // Add the white list repo at the end to let the scripted rules to run first pathPatterns.Add(new PathPattern(repoFilter)); } return(pathPatterns); }
public Resolution Check(WavePropagator wp) { var wave = wp.Wave; var indices = wp.Indices; // Initialize couldBePath and mustBePath based on wave possibilities var couldBePath = new bool[indices]; var mustBePath = new bool[indices]; for (int i = 0; i < indices; i++) { var couldBe = false; var mustBe = true; for (int p = 0; p < wp.PatternCount; p++) { if (wave.Get(i, p)) { if (PathPatterns.Contains(p)) { couldBe = true; } if (!PathPatterns.Contains(p)) { mustBe = false; } } } couldBePath[i] = couldBe; mustBePath[i] = mustBe; } // Select relevant cells, i.e. those that must be connected. bool[] relevant; if (EndPoints == null) { relevant = mustBePath; } else { relevant = new bool[indices]; if (EndPoints.Length == 0) { return(Resolution.Undecided); } foreach (var endPoint in EndPoints) { var index = wp.Topology.GetIndex(endPoint.X, endPoint.Y, endPoint.Z); relevant[index] = true; } } var walkable = couldBePath; var isArticulation = PathConstraintUtils.GetArticulationPoints(wp.Topology, walkable, relevant); if (isArticulation == null) { return(Resolution.Contradiction); } // All articulation points must be paths, // So ban any other possibilities for (var i = 0; i < indices; i++) { if (!isArticulation[i]) { continue; } for (int p = 0; p < wp.PatternCount; p++) { if (!PathPatterns.Contains(p) && wave.Get(i, p)) { wp.InternalBan(i, p); } } } return(Resolution.Undecided); }