Skip to content

Commit b0fd9b4

Browse files
committed
New: #405: Added support for deterministic source paths
1 parent ffb79d9 commit b0fd9b4

File tree

2 files changed

+83
-6
lines changed

2 files changed

+83
-6
lines changed

src/Readme.txt

+1
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ CHANGELOG
6565

6666
4.8.6.0
6767

68+
* New: #405: Added support for deterministic source paths
6869
* New: Improved name of generic classes (https://github.com/coverlet-coverage/coverlet/issues/1077)
6970

7071
4.8.5.0

src/ReportGenerator.Core/Parser/FileReading/LocalFileReader.cs

+82-6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Globalization;
44
using System.IO;
55
using System.Linq;
6+
using System.Text.RegularExpressions;
67
using Palmmedia.ReportGenerator.Core.Common;
78
using Palmmedia.ReportGenerator.Core.Properties;
89

@@ -13,11 +14,52 @@ namespace Palmmedia.ReportGenerator.Core.Parser.FileReading
1314
/// </summary>
1415
internal class LocalFileReader : IFileReader
1516
{
17+
/// <summary>
18+
/// Regex to analyze if a path is a deterministic path
19+
/// </summary>
20+
private static Regex deterministicPathRegex = new Regex("\\/_\\d?\\/", RegexOptions.Compiled);
21+
22+
/// <summary>
23+
/// The source directories for typical environments like Azure DevOps or Github Actions.
24+
/// </summary>
25+
private static IReadOnlyList<string> deterministicSourceDirectories;
26+
1627
/// <summary>
1728
/// The source directories.
1829
/// </summary>
1930
private readonly IReadOnlyList<string> sourceDirectories;
2031

32+
static LocalFileReader()
33+
{
34+
var directories = new List<string>();
35+
36+
// Azure Devops - Windows
37+
if (Directory.Exists(@"D:\a\1\s"))
38+
{
39+
directories.Add(@"D:\a\1\s");
40+
}
41+
42+
// Azure Devops - Unix
43+
if (Directory.Exists("/a/1/s"))
44+
{
45+
directories.Add("/a/1/s");
46+
}
47+
48+
// Github Actions - Windows
49+
if (Directory.Exists(@"D:\a") && !Directory.Exists(@"D:\a\1\s"))
50+
{
51+
directories.Add(@"D:\a");
52+
}
53+
54+
// Github Actions - Unix
55+
if (Directory.Exists("/home/runner/work"))
56+
{
57+
directories.Add("/home/runner/work");
58+
}
59+
60+
deterministicSourceDirectories = directories;
61+
}
62+
2163
/// <summary>
2264
/// Initializes a new instance of the <see cref="LocalFileReader" /> class.
2365
/// </summary>
@@ -48,18 +90,18 @@ public LocalFileReader(IEnumerable<string> sourceDirectories)
4890
/// <returns><code>null</code> if an error occurs, otherwise the lines of the file.</returns>
4991
public string[] LoadFile(string path, out string error)
5092
{
51-
path = this.MapPath(path);
93+
string mappedPath = this.MapPath(path);
5294

5395
try
5496
{
55-
if (!File.Exists(path))
97+
if (!File.Exists(mappedPath))
5698
{
5799
error = string.Format(CultureInfo.InvariantCulture, Resources.FileDoesNotExist, path);
58100
return null;
59101
}
60102

61-
var encoding = FileHelper.GetEncoding(path);
62-
string[] lines = File.ReadAllLines(path, encoding);
103+
var encoding = FileHelper.GetEncoding(mappedPath);
104+
string[] lines = File.ReadAllLines(mappedPath, encoding);
63105

64106
error = null;
65107
return lines;
@@ -73,14 +115,48 @@ public string[] LoadFile(string path, out string error)
73115

74116
private string MapPath(string path)
75117
{
76-
if (this.sourceDirectories.Count == 0 || File.Exists(path))
118+
if (File.Exists(path))
77119
{
78120
return path;
79121
}
80122

123+
if (path.StartsWith("/_") && deterministicPathRegex.IsMatch(path))
124+
{
125+
path = path.Substring(path.IndexOf("/", 2) + 1);
126+
127+
if (File.Exists(path))
128+
{
129+
return path;
130+
}
131+
132+
if (this.sourceDirectories.Count == 0)
133+
{
134+
return MapPath(path, deterministicSourceDirectories);
135+
}
136+
}
137+
138+
if (this.sourceDirectories.Count > 0)
139+
{
140+
return MapPath(path, this.sourceDirectories);
141+
}
142+
143+
return path;
144+
}
145+
146+
private static string MapPath(string path, IEnumerable<string> directories)
147+
{
148+
/*
149+
* Search in source dirctories
150+
*
151+
* E.g. with source directory 'C:\agent\1\work\s' the following locations will be searched:
152+
* C:\agent\1\work\s\_\some\directory\file.cs
153+
* C:\agent\1\work\s\some\directory\file.cs
154+
* C:\agent\1\work\s\directory\file.cs
155+
* C:\agent\1\work\s\file.cs
156+
*/
81157
string[] parts = path.Split('/', '\\');
82158

83-
foreach (var sourceDirectory in this.sourceDirectories)
159+
foreach (var sourceDirectory in directories)
84160
{
85161
for (int i = 0; i < parts.Length; i++)
86162
{

0 commit comments

Comments
 (0)