-
Notifications
You must be signed in to change notification settings - Fork 392
Implementation exclusion of files according to source file paths #64
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implementation exclusion of files according to source file paths #64
Conversation
…luding file globbing)
222eef7
to
d3b2db1
Compare
Would love to hear what you think is the best way to test this feature |
@tonerdo i'm not a "msbuild workflow" expert...but if we could have a simple guide/resouce link "how to test/debug" this project will grow much faster(very likely this is obvious for a msbuild workflow dev). |
return fileMatchResult.Files | ||
.Select( | ||
f => System.IO.Path.GetFullPath( | ||
System.IO.Path.Combine(directoryInfo.ToString(), f.Path) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think instead of directoryInfo.ToString()
you can use parentDir
right?
https://source.dot.net/#System.IO.FileSystem/System/IO/DirectoryInfo.cs,29
https://source.dot.net/#System.IO.FileSystem/System/IO/FileSystemInfo.cs,108
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: you can avoid System.IO.
and use Path.xxx
(using System.IO;
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- I could, but I'd rather be consistent with directoryInfo as being the source of truth after passing it parentDir, thanks to the sources you've provided I could verify this is basically the same (ToString just passes the value given in the ctor), Thanks!
- Will Do, Thanks!
namespace Coverlet.Core.Helpers | ||
{ | ||
internal static class InstrumentationHelper | ||
public static class InstrumentationHelper |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tonerdo maybe[InternalsVisibleToAttribute]
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wasn't sure about this, whatever you guys think, it's also not essential to have to put that new method in that class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please lets leave this as internal
} | ||
|
||
public static string[] GetExcludedFiles(string[] exclusionRules, string parentDir) { | ||
if (exclusionRules == null || exclusionRules.Length == 0 ) return null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMHO usually i prefer Array.Empty<string>()
https://docs.microsoft.com/en-us/dotnet/api/system.array.empty?view=netcore-2.0 less check condition/code for internal use.
using Microsoft.Extensions.FileSystemGlobbing; | ||
|
||
using Coverlet.Core.Instrumentation; | ||
using Microsoft.Extensions.FileSystemGlobbing.Abstractions; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tonerdo one question...do you have some style guide? On corefx repo the standard is
6. Namespace imports should be specified at the top of the file, outside of namespace declarations and should be sorted alphabetically.
using System.IO; | ||
using System.Linq; | ||
using System.Reflection.PortableExecutable; | ||
using Microsoft.Extensions.FileSystemGlobbing; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i did't know this ext...thank's!
@ido-namely one useful think i've learn from my contributions(on very first one) is to use "special key" to link PR to issue for simple "navigation". https://help.github.com/articles/closing-issues-using-keywords/ if for instance on PR explanation you write:
a link is automatically created on issue thread and you don't need to write anything on issue thread anymore but discussion move on PR. |
{ | ||
_module = module; | ||
_identifier = identifier; | ||
_excludedFiles = excludedFiles; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if you change this to _excludedFiles = excludedFiles ?? Enumerable.Empty<string>()
you won't need the null checks elsewhere
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
foreach (var method in type.Methods) | ||
{ | ||
var sourceFiles = method.DebugInformation.SequencePoints.Select(s => s.Document.Url).Distinct(); | ||
if (_excludedFiles != null && sourceFiles.Any(_excludedFiles.Contains)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Odd that the method could be declared in multiple files (I guess this is the case with partial methods
in partial classes
). If this is indeed case, you'd only want to exclude the method if sourceFiles.All(...)
. @tonerdo you're obviously a lot more familiar with this - am I interpreting this correctly?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well we can't have partial methods
thats for sure. I think a .First(...)
will suffice in this case
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They are part of the language: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/partial-method
If it isn't something that is supported in coverlet, then I guess we don't need to worry about it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OMG I've never even heard of partial methods
until today. I guess we learn everyday. Taking my new found knowledge into consideration I'll still go with .First(...)
, reason being that sequence points start at the body of the method and no matter how many partials of the same method you have, you can only have one implementation (hence, one body) and the document that implementation is contained in is where all sequence points for that method will point to
@ido-namely @MarcoRossignoli See steps to build and test project here: https://github.com/tonerdo/coverlet#building-the-project |
3ee4d5d
to
8adfb45
Compare
<CoverletOutputDirectory Condition="$(CoverletOutputDirectory) == ''">$(MSBuildProjectDirectory)</CoverletOutputDirectory> | ||
<CoverletOutputName Condition=" '$(CoverletOutputName)' == '' ">coverage</CoverletOutputName> | ||
<CoverletOutput>$([MSBuild]::EnsureTrailingSlash('$(CoverletOutputDirectory)'))$(CoverletOutputName)</CoverletOutput> | ||
<CoverletExclusionParentDir Condition="$(CoverletExclusionParentDir) == ''">$(MSBuildProjectDirectory)</CoverletExclusionParentDir> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lets default to the current directory as the parent if the path the user provides is relative. Too many options can be confusing
<Target Name="InstrumentModulesNoBuild" BeforeTargets="VSTest"> | ||
<Coverlet.MSbuild.Tasks.InstrumentationTask | ||
Condition="'$(VSTestNoBuild)' == 'true' and $(CollectCoverage) == 'true'" | ||
ExclusionRules="$(ExclusionRules)" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's simply call this Exclude
. Also you need to define it in the props
file
public string Path { get; set; } | ||
|
||
[Required] | ||
public string[] ExclusionRules { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/ExclusionRules/Exclude
_coverage.PrepareModules(); | ||
var excludedFiles = InstrumentationHelper.GetExcludedFiles( | ||
ExclusionRules, ExclusionParentDir); | ||
Coverage = new Coverage(Path, Guid.NewGuid().ToString(), excludedFiles); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
InstrumentationHelper
shouldn't be used outside the core assembly. Pass the exclusion rules into the Coverage
constructor and figure out the excluded files from there
} | ||
|
||
public static string[] GetExcludedFiles(string[] exclusionRules, string parentDir) { | ||
if (!(exclusionRules?.Length > 0) ) return null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should instead return an empty array here so we don't have to do null checks in places that use the result of this method
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Once you fix up the conflicts, this is ready to merge
…luding file globbing)
…t into exclude-files-by-path
2671796
to
ff0e936
Compare
ff0e936
to
4ddf02d
Compare
Hey @tonerdo , found some problems, please don't merge yet |
@tonerdo maybe you already know this app https://github.com/apps/wip useful to permit to PR writer to block merge, used a lot on corefx |
@tonerdo I fixe the problem I faced. I see there is some problem in appveyor, not sure if it's related to the project or not. |
README.md
Outdated
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: You can also ignore specific source files from code coverage using the Exclude
property
awesome! this looks great guys. Thank you @ido-namely for taking this on. |
…-by-path Implementation exclusion of files according to source file paths
(including file globbing)
Goes to #56