Skip to content

Commit 1940e86

Browse files
authored
Merge pull request #146 from tonyhallett/feature-configurable-output-directory
Feature configurable output directory
2 parents 1da6ad2 + b89f358 commit 1940e86

33 files changed

+1106
-143
lines changed

FineCodeCoverage/Core/Cobertura/CoberturaUtil.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Collections.Generic;
55
using FineCodeCoverage.Engine.Model;
66
using System.ComponentModel.Composition;
7+
using System.IO;
78

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

19-
private CoverageReport LoadReportFile(string inputFilePath)
20+
private CoverageReport LoadReport(string xml)
2021
{
21-
using (var reader = XmlReader.Create(inputFilePath, READER_SETTINGS))
22+
using (var reader = XmlReader.Create(new StringReader(xml), READER_SETTINGS))
2223
{
2324
var report = (CoverageReport)SERIALIZER.Deserialize(reader);
2425
return report;
@@ -67,11 +68,11 @@ private CoverageReport LoadReportFile(string inputFilePath)
6768
// return jsonText;
6869
//}
6970

70-
public void ProcessCoberturaXmlFile(string xmlFilePath)
71+
public void ProcessCoberturaXml(string xml)
7172
{
7273
CoverageLines = new List<CoverageLine>();
7374

74-
coverageReport = LoadReportFile(xmlFilePath);
75+
coverageReport = LoadReport(xml);
7576

7677
foreach (var package in coverageReport.Packages.Package)
7778
{

FineCodeCoverage/Core/Cobertura/ICoberturaUtil.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ interface ICoberturaUtil
77
{
88
List<CoverageLine> CoverageLines { get; }
99

10-
void ProcessCoberturaXmlFile(string xmlFilePath);
10+
void ProcessCoberturaXml(string xml);
1111
string[] GetSourceFiles(string assemblyName, string qualifiedClassName, int file);
1212
}
1313
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using System;
2+
using System.ComponentModel.Composition;
3+
using System.IO;
4+
using FineCodeCoverage.Core.Utilities;
5+
using FineCodeCoverage.Options;
6+
7+
namespace FineCodeCoverage.Engine
8+
{
9+
[Order(1, typeof(ICoverageToolOutputFolderSolutionProvider))]
10+
class AppOptionsCoverageToolOutputFolderSolutionProvider : ICoverageToolOutputFolderSolutionProvider
11+
{
12+
private readonly IAppOptionsProvider appOptionsProvider;
13+
14+
[ImportingConstructor]
15+
public AppOptionsCoverageToolOutputFolderSolutionProvider(IAppOptionsProvider appOptionsProvider)
16+
{
17+
this.appOptionsProvider = appOptionsProvider;
18+
}
19+
public string Provide(Func<string> solutionFolderProvider)
20+
{
21+
var appOptions = appOptionsProvider.Get();
22+
if (!String.IsNullOrEmpty(appOptions.FCCSolutionOutputDirectoryName))
23+
{
24+
var solutionFolder = solutionFolderProvider();
25+
if(solutionFolder != null)
26+
{
27+
return Path.Combine(solutionFolder, appOptions.FCCSolutionOutputDirectoryName);
28+
}
29+
}
30+
return null;
31+
}
32+
}
33+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.ComponentModel.Composition;
4+
using System.Linq;
5+
using FineCodeCoverage.Core.Utilities;
6+
using FineCodeCoverage.Engine.Model;
7+
8+
namespace FineCodeCoverage.Engine
9+
{
10+
[Order(1, typeof(ICoverageToolOutputFolderProvider))]
11+
class CoverageToolOutputFolderFromSolutionProvider : ICoverageToolOutputFolderProvider
12+
{
13+
private readonly ISolutionFolderProvider solutionFolderProvider;
14+
private readonly IOrderedEnumerable<Lazy<ICoverageToolOutputFolderSolutionProvider, IOrderMetadata>> solutionFolderProviders;
15+
16+
[ImportingConstructor]
17+
public CoverageToolOutputFolderFromSolutionProvider(ISolutionFolderProvider solutionFolderProvider, [ImportMany] IEnumerable<Lazy<ICoverageToolOutputFolderSolutionProvider, IOrderMetadata>> solutionFolderProviders)
18+
{
19+
this.solutionFolderProvider = solutionFolderProvider;
20+
this.solutionFolderProviders = solutionFolderProviders.OrderBy(p => p.Metadata.Order);
21+
}
22+
23+
public string Provide(List<ICoverageProject> coverageProjects)
24+
{
25+
var provided = false;
26+
string providedDirectory = null;
27+
return solutionFolderProviders.SelectFirstNonNull(p => p.Value.Provide(() =>
28+
{
29+
if(!provided)
30+
{
31+
providedDirectory = solutionFolderProvider.Provide(coverageProjects[0].ProjectFile);
32+
provided = true;
33+
}
34+
return providedDirectory;
35+
}));
36+
37+
}
38+
}
39+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.ComponentModel.Composition;
4+
using System.IO;
5+
using System.Linq;
6+
using FineCodeCoverage.Core.Utilities;
7+
using FineCodeCoverage.Engine.Model;
8+
9+
namespace FineCodeCoverage.Engine
10+
{
11+
[Export(typeof(ICoverageToolOutputManager))]
12+
internal class CoverageToolOutputManager : ICoverageToolOutputManager
13+
{
14+
private readonly ILogger logger;
15+
private readonly IFileUtil fileUtil;
16+
private const string unifiedHtmlFileName = "index.html";
17+
private const string unifiedXmlFileName = "Cobertura.xml";
18+
private const string processedHtmlFileName = "index-processed.html";
19+
private const string projectCoverageToolOutputFolderName = "coverage-tool-output";
20+
private string outputFolderForAllProjects;
21+
private List<ICoverageProject> coverageProjects;
22+
private readonly IOrderedEnumerable<Lazy<ICoverageToolOutputFolderProvider, IOrderMetadata>> outputFolderProviders;
23+
24+
[ImportingConstructor]
25+
public CoverageToolOutputManager(IFileUtil fileUtil, ILogger logger,[ImportMany] IEnumerable<Lazy<ICoverageToolOutputFolderProvider, IOrderMetadata>> outputFolderProviders)
26+
{
27+
this.logger = logger;
28+
this.fileUtil = fileUtil;
29+
this.outputFolderProviders = outputFolderProviders.OrderBy(p => p.Metadata.Order);
30+
}
31+
32+
public void SetProjectCoverageOutputFolder(List<ICoverageProject> coverageProjects)
33+
{
34+
this.coverageProjects = coverageProjects;
35+
DetermineOutputFolder();
36+
if (outputFolderForAllProjects == null)
37+
{
38+
foreach(var coverageProject in coverageProjects)
39+
{
40+
coverageProject.CoverageOutputFolder = Path.Combine(coverageProject.FCCOutputFolder, projectCoverageToolOutputFolderName);
41+
}
42+
}
43+
else
44+
{
45+
fileUtil.TryEmptyDirectory(outputFolderForAllProjects);
46+
foreach (var coverageProject in coverageProjects)
47+
{
48+
coverageProject.CoverageOutputFolder = Path.Combine(outputFolderForAllProjects, coverageProject.ProjectName);
49+
}
50+
}
51+
}
52+
53+
public void OutputReports(string unifiedHtml, string processedReport, string unifiedXml)
54+
{
55+
var outputFolder = outputFolderForAllProjects ?? coverageProjects[0].CoverageOutputFolder;
56+
57+
fileUtil.WriteAllText(Path.Combine(outputFolder, unifiedHtmlFileName), unifiedHtml);
58+
fileUtil.WriteAllText(Path.Combine(outputFolder, processedHtmlFileName), processedReport);
59+
fileUtil.WriteAllText(Path.Combine(outputFolder, unifiedXmlFileName), unifiedXml);
60+
}
61+
62+
private void DetermineOutputFolder()
63+
{
64+
outputFolderForAllProjects = outputFolderProviders.SelectFirstNonNull(p => p.Value.Provide(coverageProjects));
65+
if(outputFolderForAllProjects != null)
66+
{
67+
logger.Log($"FCC output in {outputFolderForAllProjects}");
68+
}
69+
}
70+
}
71+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
using System;
2+
using System.ComponentModel.Composition;
3+
using System.IO;
4+
using FineCodeCoverage.Core.Utilities;
5+
6+
namespace FineCodeCoverage.Engine
7+
{
8+
[Order(2,typeof(ICoverageToolOutputFolderSolutionProvider))]
9+
class FccOutputExistenceCoverageToolOutputFolderSolutionProvider : ICoverageToolOutputFolderSolutionProvider
10+
{
11+
private const string fccOutputFolderName = "fcc-output";
12+
private readonly IFileUtil fileUtil;
13+
14+
[ImportingConstructor]
15+
public FccOutputExistenceCoverageToolOutputFolderSolutionProvider(IFileUtil fileUtil)
16+
{
17+
this.fileUtil = fileUtil;
18+
}
19+
20+
public string Provide(Func<string> solutionFolderProvider)
21+
{
22+
var solutionFolder = solutionFolderProvider();
23+
if (solutionFolder != null)
24+
{
25+
var provided = Path.Combine(solutionFolder, fccOutputFolderName);
26+
if (fileUtil.DirectoryExists(provided))
27+
{
28+
return provided;
29+
}
30+
}
31+
return null;
32+
}
33+
}
34+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using System.Collections.Generic;
2+
using FineCodeCoverage.Engine.Model;
3+
4+
namespace FineCodeCoverage.Engine
5+
{
6+
internal interface ICoverageToolOutputFolderProvider
7+
{
8+
string Provide(List<ICoverageProject> coverageProjects);
9+
}
10+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
using System;
2+
3+
namespace FineCodeCoverage.Engine
4+
{
5+
interface ICoverageToolOutputFolderSolutionProvider
6+
{
7+
string Provide(Func<string> solutionFolderProvider);
8+
}
9+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using System.Collections.Generic;
2+
using FineCodeCoverage.Engine.Model;
3+
4+
namespace FineCodeCoverage.Engine
5+
{
6+
internal interface ICoverageToolOutputManager
7+
{
8+
void SetProjectCoverageOutputFolder(List<ICoverageProject> coverageProjects);
9+
void OutputReports(string unifiedHtml, string processedReport, string unifiedXml);
10+
}
11+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace FineCodeCoverage.Engine
2+
{
3+
interface ISolutionFolderProvider
4+
{
5+
string Provide(string projectFile);
6+
}
7+
}

0 commit comments

Comments
 (0)