Skip to content

Conversation

@daveMueller
Copy link
Collaborator

@daveMueller daveMueller commented Nov 10, 2019

closes #197, closes #408 and really closes #295 and maintains #257

@daveMueller daveMueller changed the title #197, #408, #413 Coberturoa Reporter Jenkins + Source Link Support #197, #408 Coberturoa Reporter Jenkins + Source Link Support Nov 10, 2019
@daveMueller
Copy link
Collaborator Author

daveMueller commented Nov 10, 2019

Filename attribute is now relative to system root and the reports can properly be displayed in jenkins running on linux or windows. I also attached a snipped form the generated report where the source tag and the filename tag can be seen.

This doesn't really solve the issue #413 because the introduced relative paths aren't relative to the project base.

SourceFile

SourceFileLinux

image

@MarcoRossignoli
Copy link
Collaborator

Thanks David bit busy next week I'll take a look asap!

@MarcoRossignoli MarcoRossignoli added the tenet-reporters Issue related to coverage output files(reporters) label Nov 10, 2019
{
public string Identifier;
public Modules Modules;
public bool IsSourceLinkUsed;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I prefer to maintain switch name UseSourceLink

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this necessary?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

return Encoding.UTF8.GetString(stream.ToArray());
}

private static IEnumerable<string> GetRootDirs(Modules modules, bool isSourceLinkUsed)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not

if (isSourceLinkUsed)
{
	return new[] { string.Empty };
}
else
{
	return modules.Values.SelectMany(k => k.Keys).Select(Directory.GetDirectoryRoot).Distinct();
}

Does it work?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I tested it. Done.

return sources.Select(Directory.GetDirectoryRoot).Distinct();
}

private static string GetRelativePathFromBase(IEnumerable<string> basePaths, string path, bool isSourceLinkUsed)
Copy link
Collaborator

@MarcoRossignoli MarcoRossignoli Nov 21, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rename rootPaths and useSourceLink pls

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

{
if (path.StartsWith(basePath))
{
relativePath = path.Substring(basePath.Length);
Copy link
Collaborator

@MarcoRossignoli MarcoRossignoli Nov 21, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what do you think about

            if (isSourceLinkUsed)
            {
                return path;
            }

            foreach (var root in basePaths)
            {
                if (path.StartsWith(root))
                {
                    return path.Substring(root.Length);
                }
            }

            Debug.Assert(false, "Unexpected, we should find at least one path starts with one pre-build roots list");

            return path;

it seems more logic to me...when we found one valid root we can return immediatly, if we don't found any valid root(unexpected) we return original path, so we avoid exception and we'll generate a file(better than nothing), I added also an assertion so on debug we'll catch possible problem.

Copy link
Collaborator Author

@daveMueller daveMueller Dec 5, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I agree. Done.

@MarcoRossignoli
Copy link
Collaborator

Thank's @daveMueller for the effort here and sorry for the delay.

I'd like to add more tests on this

  1. one test with 2 file from two different windows roots i.e. c:\proj\file.cs and e:\proj\file.cs
  2. one test with source link parameter true

@MarcoRossignoli
Copy link
Collaborator

@daveMueller let me know if you want complete this or if can finish this PR on top of your precious work!

@daveMueller
Copy link
Collaborator Author

@daveMueller let me know if you want complete this or if can finish this PR on top of your precious work!

@MarcoRossignoli Yes I will complete it. I already did most of the things you mentioned locally. My daytime job has been keeping me busy last week but I think I will find some free time on the weekend.

@MarcoRossignoli
Copy link
Collaborator

MarcoRossignoli commented Nov 29, 2019

No worries no rush, only asked to know!
And feel free to say "I don't have time" you're not obligated, thanks a lot for your effort!

@daveMueller
Copy link
Collaborator Author

@MarcoRossignoli I still want to refactore the tests. Had some problems to get them running on X plat and so they are still not really clean. If you have some ideas what could be changed, please let me know.

CoberturaReporter reporter = new CoberturaReporter();
string report = reporter.Report(result);

var doc = XDocument.Load(new MemoryStream(Encoding.UTF8.GetBytes(report)));
Copy link
Collaborator

@MarcoRossignoli MarcoRossignoli Dec 5, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about

List<string> rootPaths = doc.Element("coverage").Element("sources").Elements().Select(e => e.Value).ToList();
List<string> relativePaths = doc.Element("coverage").Element("packages").Element("package").Element("classes").Elements().Select(e => e.Attribute("filename").Value).ToList();
List<string> possiblePaths = new List<string>();
foreach (string root in rootPaths)
{
    foreach (string relativePath in relativePaths)
    {
        possiblePaths.Add(Path.Combine(root, relativePath));
    }
}
            
Assert.Contains(absolutePath1, possiblePaths);
Assert.Contains(absolutePath2, possiblePaths);

This should be the expected alg of every reporter that can read a cobertura format...we try every permutation root+path and check if exists

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I changed it that way.

CoberturaReporter reporter = new CoberturaReporter();
string report = reporter.Report(result);

var doc = XDocument.Load(new MemoryStream(Encoding.UTF8.GetBytes(report)));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok maybe cleanup a bit with doc.Element("coverage").Element("packages").Element("package").Element("classes").Elements().Select(e => e.Attribute("filename").Value).Single();

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@MarcoRossignoli
Copy link
Collaborator

@daveMueller can you test and attach also a reportgenerator result?Only to be sure to be compatible with it(most used tool).

@daveMueller
Copy link
Collaborator Author

@MarcoRossignoli are the attached screenshots sufficient?

Here is the relevant part of a cobertura report:
image

And this is the reportgenerator output for the cobertura report.
image

@MarcoRossignoli
Copy link
Collaborator

yep thank you

@MarcoRossignoli
Copy link
Collaborator

MarcoRossignoli commented Dec 7, 2019

@danielpalme can you take a look at report generated at #614 (comment) and double confirm that it's ok?
This is the idea of how a reported should interpret a cobertura report https://github.com/tonerdo/coverlet/pull/614/files#diff-1eb780449e930439d94fbbcd49400e39R176 for us, are we close enough?

@MarcoRossignoli MarcoRossignoli changed the title #197, #408 Coberturoa Reporter Jenkins + Source Link Support Fix cobertura Jenkins reporter + source link support Dec 7, 2019
@danielpalme
Copy link

Your code looks fine to me.
ReportGenerator iterates through the source elements and combines the value with the filename attribute. The first combined file path that exists on disk is used.
Another option would be to just use the absolute path for the the filename attribute. Then no "guessing" is required.
Advantages:

  • Faster
  • More reliable (example a class with same name exists in several directories/namespaces)

See:
https://github.com/danielpalme/ReportGenerator/blob/master/src/ReportGenerator.Core/Parser/Preprocessing/CoberturaReportPreprocessor.cs

@MarcoRossignoli
Copy link
Collaborator

Another option would be to just use the absolute path for the the filename attribute. Then no "guessing" is required

This is the old behavior, but we need to split root+relative due to Jenkins reporter, it doesn't work well without sources

Copy link
Collaborator

@MarcoRossignoli MarcoRossignoli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks fine!

@MarcoRossignoli MarcoRossignoli merged commit 57ec8d3 into coverlet-coverage:master Dec 8, 2019
@MarcoRossignoli
Copy link
Collaborator

Thank's Dave!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

tenet-reporters Issue related to coverage output files(reporters)

Projects

None yet

3 participants