From d016d56bdafd3a8d03bd84cf1e818dcd4214917e Mon Sep 17 00:00:00 2001 From: Ido David Date: Sun, 29 Apr 2018 03:33:39 -0400 Subject: [PATCH] adding support for absolute paths, updating readme files --- README.md | 11 ++++++ build.proj | 2 +- .../Helpers/InstrumentationHelper.cs | 34 +++++++++++++++---- 3 files changed, 39 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 27dc096..390c985 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,7 @@ The above command will automatically fail the build if the average code coverage ### Excluding From Coverage +#### Attributes You can ignore a method or an entire class from code coverage by creating and applying any of the following attributes: * ExcludeFromCoverage @@ -85,6 +86,16 @@ You can ignore a method or an entire class from code coverage by creating and ap Coverlet just uses the type name, so the attributes can be created under any namespace of your choosing. +#### File Path +You can also ignore code coverage by specifing files using the `Exclude` property + - Use single or multiple paths (separate by comma) + - Use absolute or relative paths (relative to the project directory) + - Use file path or directory path with globbing (e.g `dir1/*.cs`) + +```bash +dotnet test /p:CollectCoverage=true /p:Exclude=\"../dir1/class1.cs,../dir2/*.cs,../dir3/**/*.cs,\" +``` + ## Roadmap * Filter modules to be instrumented diff --git a/build.proj b/build.proj index 41b99ca..25cdcad 100644 --- a/build.proj +++ b/build.proj @@ -28,7 +28,7 @@ - + diff --git a/src/coverlet.core/Helpers/InstrumentationHelper.cs b/src/coverlet.core/Helpers/InstrumentationHelper.cs index d3d5117..c36baca 100644 --- a/src/coverlet.core/Helpers/InstrumentationHelper.cs +++ b/src/coverlet.core/Helpers/InstrumentationHelper.cs @@ -113,19 +113,39 @@ namespace Coverlet.Core.Helpers public static IEnumerable GetExcludedFiles(IEnumerable excludeRules, string parentDir = null) { + const string RELATIVE_KEY = nameof(RELATIVE_KEY); parentDir = string.IsNullOrWhiteSpace(parentDir)? Directory.GetCurrentDirectory() : parentDir; + if (excludeRules == null || !excludeRules.Any()) return Enumerable.Empty(); - var matcher = new Matcher(); + + var matcherDict = new Dictionary(){ {RELATIVE_KEY, new Matcher()}}; foreach (var excludeRule in excludeRules) { - matcher.AddInclude(excludeRule); + if (Path.IsPathRooted(excludeRule)) { + var root = Path.GetPathRoot(excludeRule); + if (!matcherDict.ContainsKey(root)) { + matcherDict.Add(root, new Matcher()); + } + matcherDict[root].AddInclude(excludeRule.Substring(root.Length)); + } else { + matcherDict[RELATIVE_KEY].AddInclude(excludeRule); + } + } - - DirectoryInfo directoryInfo = new DirectoryInfo(parentDir); - var fileMatchResult = matcher.Execute(new DirectoryInfoWrapper(directoryInfo)); - return fileMatchResult.Files - .Select(f => Path.GetFullPath(Path.Combine(directoryInfo.ToString(), f.Path))); + var files = new List(); + foreach(var entry in matcherDict) + { + var root = entry.Key; + var matcher = entry.Value; + var directoryInfo = new DirectoryInfo(root.Equals(RELATIVE_KEY) ? parentDir : root); + var fileMatchResult = matcher.Execute(new DirectoryInfoWrapper(directoryInfo)); + var currentFiles = fileMatchResult.Files + .Select(f => Path.GetFullPath(Path.Combine(directoryInfo.ToString(), f.Path))); + files.AddRange(currentFiles); + } + + return files.Distinct(); } } }