Skip to content

output directory from AllProjectsCoverageOutputFolder #143

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

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions FineCodeCoverage/Core/Cobertura/CoberturaUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Collections.Generic;
using FineCodeCoverage.Engine.Model;
using System.ComponentModel.Composition;
using System.IO;

namespace FineCodeCoverage.Engine.Cobertura
{
Expand All @@ -16,9 +17,9 @@ internal class CoberturaUtil:ICoberturaUtil
private CoverageReport coverageReport;
public List<CoverageLine> CoverageLines { get; private set; }

private CoverageReport LoadReportFile(string inputFilePath)
private CoverageReport LoadReport(string xml)
{
using (var reader = XmlReader.Create(inputFilePath, READER_SETTINGS))
using (var reader = XmlReader.Create(new StringReader(xml), READER_SETTINGS))
{
var report = (CoverageReport)SERIALIZER.Deserialize(reader);
return report;
Expand Down Expand Up @@ -67,11 +68,11 @@ private CoverageReport LoadReportFile(string inputFilePath)
// return jsonText;
//}

public void ProcessCoberturaXmlFile(string xmlFilePath)
public void ProcessCoberturaXml(string xml)
{
CoverageLines = new List<CoverageLine>();

coverageReport = LoadReportFile(xmlFilePath);
coverageReport = LoadReport(xml);

foreach (var package in coverageReport.Packages.Package)
{
Expand Down
2 changes: 1 addition & 1 deletion FineCodeCoverage/Core/Cobertura/ICoberturaUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ interface ICoberturaUtil
{
List<CoverageLine> CoverageLines { get; }

void ProcessCoberturaXmlFile(string xmlFilePath);
void ProcessCoberturaXml(string xml);
string[] GetSourceFiles(string assemblyName, string qualifiedClassName, int file);
}
}
80 changes: 80 additions & 0 deletions FineCodeCoverage/Core/CoverageToolOutputManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.IO;
using System.Linq;
using FineCodeCoverage.Core.Utilities;
using FineCodeCoverage.Engine.Model;

namespace FineCodeCoverage.Engine
{
[Export(typeof(ICoverageToolOutputManager))]
internal class CoverageToolOutputManager : ICoverageToolOutputManager
{
private readonly ILogger logger;
private readonly IFileUtil fileUtil;
private const string unifiedHtmlFileName = "index.html";
private const string unifiedXmlFileName = "Cobertura.xml";
private const string processedHtmlFileName = "index-processed.html";
private const string projectCoverageToolOutputFolderName = "coverage-tool-output";
private string outputFolderForAllProjects;
private List<ICoverageProject> coverageProjects;

[ImportingConstructor]
public CoverageToolOutputManager(IFileUtil fileUtil, ILogger logger)
{
this.logger = logger;
this.fileUtil = fileUtil;
}

public void SetProjectCoverageOutputFolder(List<ICoverageProject> coverageProjects)
{
this.coverageProjects = coverageProjects;
DetermineOutputFolderForAllProjects();
if(outputFolderForAllProjects == null)
{
foreach(var coverageProject in coverageProjects)
{
coverageProject.CoverageOutputFolder = Path.Combine(coverageProject.FCCOutputFolder, projectCoverageToolOutputFolderName);
}
}
else
{
fileUtil.TryEmptyDirectory(outputFolderForAllProjects);
foreach (var coverageProject in coverageProjects)
{
coverageProject.CoverageOutputFolder = Path.Combine(outputFolderForAllProjects, coverageProject.ProjectName);
}
}
}

public void SetReportOutput(string unifiedHtml, string processedReport, string unifiedXml)
{
var outputFolder = outputFolderForAllProjects ?? coverageProjects[0].CoverageOutputFolder;

fileUtil.WriteAllText(Path.Combine(outputFolder, unifiedHtmlFileName), unifiedHtml);
fileUtil.WriteAllText(Path.Combine(outputFolder, processedHtmlFileName), processedReport);
fileUtil.WriteAllText(Path.Combine(outputFolder, unifiedXmlFileName), unifiedXml);
}

private void DetermineOutputFolderForAllProjects()
{
outputFolderForAllProjects = null;
var coverageProjectWithAllProjectsCoverageOutputFolder = coverageProjects.FirstOrDefault(cp => cp.AllProjectsCoverageOutputFolder != null);
if(coverageProjectWithAllProjectsCoverageOutputFolder != null)
{
var allProjectsCoverageOutputFolder = fileUtil.EnsureAbsolute(
coverageProjectWithAllProjectsCoverageOutputFolder.AllProjectsCoverageOutputFolder,
fileUtil.ParentDirectoryPath(coverageProjectWithAllProjectsCoverageOutputFolder.ProjectFile)
);

outputFolderForAllProjects = allProjectsCoverageOutputFolder;
logger.Log($"Outputting coverage files to - {outputFolderForAllProjects}");
return;
}


logger.Log($"Outputting coverage files in project output folder");

}
}
}
54 changes: 21 additions & 33 deletions FineCodeCoverage/Core/FCCEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ internal class FCCEngine : IFCCEngine
{
internal int InitializeWait { get; set; } = 5000;
internal const string initializationFailedMessagePrefix = "Initialization failed. Please check the following error which may be resolved by reopening visual studio which will start the initialization process again.";
internal const string errorReadingReportGeneratorOutputMessage = "error reading report generator output";
private readonly object colorThemeService;
private string CurrentTheme => $"{((dynamic)colorThemeService)?.CurrentTheme?.Name}".Trim();

Expand All @@ -44,6 +43,7 @@ internal class FCCEngine : IFCCEngine
private readonly IAppDataFolder appDataFolder;
private readonly IServiceProvider serviceProvider;
private IInitializeStatusProvider initializeStatusProvider;
private readonly ICoverageToolOutputManager coverageOutputManager;
internal System.Threading.Tasks.Task reloadCoverageTask;

[ImportingConstructor]
Expand All @@ -56,10 +56,12 @@ public FCCEngine(
IAppOptionsProvider appOptionsProvider,
ILogger logger,
IAppDataFolder appDataFolder,
ICoverageToolOutputManager coverageOutputManager,
[Import(typeof(SVsServiceProvider))]
IServiceProvider serviceProvider
)
{
this.coverageOutputManager = coverageOutputManager;
this.coverageUtilManager = coverageUtilManager;
this.coberturaUtil = coberturaUtil;
this.msTestPlatformUtil = msTestPlatformUtil;
Expand Down Expand Up @@ -142,54 +144,38 @@ private async System.Threading.Tasks.Task<string[]> RunCoverageAsync(List<ICover

}

private void RaiseUpdateOutputWindow(string reportFilePath)
private void RaiseUpdateOutputWindow(string reportHtml)
{
UpdateOutputWindowEventArgs updateOutputWindowEventArgs = new UpdateOutputWindowEventArgs { };

try
{
if (!string.IsNullOrEmpty(reportFilePath))
{
var htmlContent = File.ReadAllText(reportFilePath);
updateOutputWindowEventArgs.HtmlContent = htmlContent;
}
}
catch
{
logger.Log(errorReadingReportGeneratorOutputMessage);
}
finally
{
UpdateOutputWindow?.Invoke(updateOutputWindowEventArgs);
}
UpdateOutputWindowEventArgs updateOutputWindowEventArgs = new UpdateOutputWindowEventArgs { HtmlContent = reportHtml};
UpdateOutputWindow?.Invoke(updateOutputWindowEventArgs);
}
private void UpdateUI(List<CoverageLine> coverageLines, string reportFilePath)
private void UpdateUI(List<CoverageLine> coverageLines, string reportHtml)
{
CoverageLines = coverageLines;
UpdateMarginTags?.Invoke(new UpdateMarginTagsEventArgs());
RaiseUpdateOutputWindow(reportFilePath);
RaiseUpdateOutputWindow(reportHtml);
}

private async System.Threading.Tasks.Task<(List<CoverageLine> coverageLines,string reportFilePath)> RunAndProcessReportAsync(string[] coverOutputFiles,CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();

List<CoverageLine> coverageLines = null;
string reportFilePath = null;
string processedReport = null;

var darkMode = CurrentTheme.Equals("Dark", StringComparison.OrdinalIgnoreCase);

var result = await reportGeneratorUtil.RunReportGeneratorAsync(coverOutputFiles, darkMode, true);

if (result.Success)
{
coberturaUtil.ProcessCoberturaXmlFile(result.UnifiedXmlFile);
coberturaUtil.ProcessCoberturaXml(result.UnifiedXml);
coverageLines = coberturaUtil.CoverageLines;

reportGeneratorUtil.ProcessUnifiedHtmlFile(result.UnifiedHtmlFile, darkMode, out var htmlFilePath);
reportFilePath = htmlFilePath;
processedReport = reportGeneratorUtil.ProcessUnifiedHtml(result.UnifiedHtml, darkMode);
coverageOutputManager.SetReportOutput(result.UnifiedHtml, processedReport, result.UnifiedXml);
}
return (coverageLines, reportFilePath);
return (coverageLines, processedReport);
}

private async System.Threading.Tasks.Task PrepareCoverageProjectsAsync(List<ICoverageProject> coverageProjects, CancellationToken cancellationToken)
Expand All @@ -213,7 +199,7 @@ private async System.Threading.Tasks.Task PrepareCoverageProjectsAsync(List<ICov
}
}

private void ReloadCoverageTaskContinuation(System.Threading.Tasks.Task<(List<CoverageLine> coverageLines, string reportFilePath)> t)
private void ReloadCoverageTaskContinuation(System.Threading.Tasks.Task<(List<CoverageLine> coverageLines, string reportHtml)> t)
{
switch (t.Status)
{
Expand All @@ -228,7 +214,7 @@ private void ReloadCoverageTaskContinuation(System.Threading.Tasks.Task<(List<Co
case System.Threading.Tasks.TaskStatus.RanToCompletion:
LogReloadCoverageStatus(ReloadCoverageStatus.Done);
#pragma warning disable VSTHRD002 // Avoid problematic synchronous waits
UpdateUI(t.Result.coverageLines, t.Result.reportFilePath);
UpdateUI(t.Result.coverageLines, t.Result.reportHtml);
#pragma warning restore VSTHRD002 // Avoid problematic synchronous waits
break;
}
Expand Down Expand Up @@ -263,24 +249,26 @@ public void ReloadCoverage(Func<System.Threading.Tasks.Task<List<ICoverageProjec
reloadCoverageTask = System.Threading.Tasks.Task.Run(async () =>
{
List<CoverageLine> coverageLines = null;
string reportFilePath = null;
string reportHtml = null;

await PollInitializedStatusAsync(cancellationToken);

LogReloadCoverageStatus(ReloadCoverageStatus.Start);

var coverageProjects = await coverageRequestCallback();

coverageOutputManager.SetProjectCoverageOutputFolder(coverageProjects);

var coverOutputFiles = await RunCoverageAsync(coverageProjects, cancellationToken);

if (coverOutputFiles.Any())
{
var (lines, rFilePath) = await RunAndProcessReportAsync(coverOutputFiles,cancellationToken);
var (lines, report) = await RunAndProcessReportAsync(coverOutputFiles,cancellationToken);
coverageLines = lines;
reportFilePath = rFilePath;
reportHtml = report;
}

return (coverageLines, reportFilePath);
return (coverageLines, reportHtml);

}, cancellationToken)
.ContinueWith(t =>
Expand Down
15 changes: 15 additions & 0 deletions FineCodeCoverage/Core/ICoverageToolOutputManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FineCodeCoverage.Engine.Model;

namespace FineCodeCoverage.Engine
{
internal interface ICoverageToolOutputManager
{
void SetProjectCoverageOutputFolder(List<ICoverageProject> coverageProjects);
void SetReportOutput(string unifiedHtml, string processedReport, string unifiedXml);
}
}
26 changes: 10 additions & 16 deletions FineCodeCoverage/Core/Model/CoverageProject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,9 @@ internal class CoverageProject : ICoverageProject
private readonly bool canUseMsBuildWorkspace;
private XElement projectFileXElement;
private IAppOptions settings;
private string fccPath;
private readonly string fccFolderName = "fine-code-coverage";
private readonly string buildOutputFolderName = "build-output";
private string buildOutputPath;
private string BuildOutputPath => Path.Combine(FCCOutputFolder, buildOutputFolderName);
private readonly string coverageToolOutputFolderName = "coverage-tool-output";

public CoverageProject(IAppOptionsProvider appOptionsProvider, IFileSynchronizationUtil fileSynchronizationUtil, ILogger logger, DTE dte, bool canUseMsBuildWorkspace)
Expand All @@ -39,6 +38,9 @@ public CoverageProject(IAppOptionsProvider appOptionsProvider, IFileSynchronizat
this.canUseMsBuildWorkspace = canUseMsBuildWorkspace;
}

public string AllProjectsCoverageOutputFolder => ProjectFileXElement.XPathSelectElement($"/PropertyGroup/AllProjectsCoverageOutputFolder")?.Value;

public string FCCOutputFolder => Path.Combine(ProjectOutputFolder, fccFolderName);
public bool IsDotNetSdkStyle()
{
return ProjectFileXElement
Expand Down Expand Up @@ -126,7 +128,7 @@ public bool IsDotNetSdkStyle()
public bool HasFailed => !string.IsNullOrWhiteSpace(FailureStage) || !string.IsNullOrWhiteSpace(FailureDescription);
public string ProjectFile { get; set; }
public string ProjectName { get; set; }
public string CoverageOutputFile { get; set; }
public string CoverageOutputFile => Path.Combine(CoverageOutputFolder, $"{ProjectName}.coverage.xml");

private bool TypeMatch(Type type, params Type[] otherTypes)
{
Expand Down Expand Up @@ -356,7 +358,6 @@ public async System.Threading.Tasks.Task StepAsync(string stepName, Func<ICovera

public async System.Threading.Tasks.Task PrepareForCoverageAsync()
{
SetPaths();
EnsureDirectories();
CleanDirectory();
SynchronizeBuildOutput();
Expand Down Expand Up @@ -493,13 +494,6 @@ private async Task<List<ReferencedProject>> GetReferencedProjectsFromProjectFile
return referencedProjectFiles.Select(referencedProjectProjectFile => new ReferencedProject(referencedProjectProjectFile)).ToList();
}

private void SetPaths()
{
fccPath = Path.Combine(ProjectOutputFolder, fccFolderName);
buildOutputPath = Path.Combine(fccPath, buildOutputFolderName);
CoverageOutputFolder = Path.Combine(fccPath, coverageToolOutputFolderName);
CoverageOutputFile = Path.Combine(CoverageOutputFolder, $"{ProjectName}.coverage.xml");
}
private void EnsureDirectories()
{
EnsureFccDirectory();
Expand All @@ -508,11 +502,11 @@ private void EnsureDirectories()
}
private void EnsureFccDirectory()
{
CreateIfDoesNotExist(fccPath);
CreateIfDoesNotExist(FCCOutputFolder);
}
private void EnsureBuildOutputDirectory()
{
CreateIfDoesNotExist(buildOutputPath);
CreateIfDoesNotExist(BuildOutputPath);
}
private void CreateIfDoesNotExist(string path)
{
Expand Down Expand Up @@ -546,7 +540,7 @@ private void EnsureEmptyOutputFolder()
private void CleanDirectory()
{
var exclusions = new List<string> { buildOutputFolderName, coverageToolOutputFolderName };
var fccDirectory = new DirectoryInfo(fccPath);
var fccDirectory = new DirectoryInfo(FCCOutputFolder);

fccDirectory.EnumerateFileSystemInfos().AsParallel().ForAll(fileOrDirectory =>
{
Expand All @@ -570,8 +564,8 @@ private void CleanDirectory()
}
private void SynchronizeBuildOutput()
{
fileSynchronizationUtil.Synchronize(ProjectOutputFolder, buildOutputPath, fccFolderName);
TestDllFile = Path.Combine(buildOutputPath, Path.GetFileName(TestDllFile));
fileSynchronizationUtil.Synchronize(ProjectOutputFolder, BuildOutputPath, fccFolderName);
TestDllFile = Path.Combine(BuildOutputPath, Path.GetFileName(TestDllFile));
}

}
Expand Down
4 changes: 3 additions & 1 deletion FineCodeCoverage/Core/Model/ICoverageProject.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ namespace FineCodeCoverage.Engine.Model
{
internal interface ICoverageProject
{
string CoverageOutputFile { get; set; }
string AllProjectsCoverageOutputFolder { get; }
string FCCOutputFolder { get; }
string CoverageOutputFile { get; }
string CoverageOutputFolder { get; set; }
List<string> ExcludedReferencedProjects { get; }
string FailureDescription { get; set; }
Expand Down
Loading