3
3
using System . Globalization ;
4
4
using System . IO ;
5
5
using System . Linq ;
6
+ using System . Text . RegularExpressions ;
6
7
using Palmmedia . ReportGenerator . Core . Common ;
7
8
using Palmmedia . ReportGenerator . Core . Properties ;
8
9
@@ -13,11 +14,52 @@ namespace Palmmedia.ReportGenerator.Core.Parser.FileReading
13
14
/// </summary>
14
15
internal class LocalFileReader : IFileReader
15
16
{
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
+
16
27
/// <summary>
17
28
/// The source directories.
18
29
/// </summary>
19
30
private readonly IReadOnlyList < string > sourceDirectories ;
20
31
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
+
21
63
/// <summary>
22
64
/// Initializes a new instance of the <see cref="LocalFileReader" /> class.
23
65
/// </summary>
@@ -48,18 +90,18 @@ public LocalFileReader(IEnumerable<string> sourceDirectories)
48
90
/// <returns><code>null</code> if an error occurs, otherwise the lines of the file.</returns>
49
91
public string [ ] LoadFile ( string path , out string error )
50
92
{
51
- path = this . MapPath ( path ) ;
93
+ string mappedPath = this . MapPath ( path ) ;
52
94
53
95
try
54
96
{
55
- if ( ! File . Exists ( path ) )
97
+ if ( ! File . Exists ( mappedPath ) )
56
98
{
57
99
error = string . Format ( CultureInfo . InvariantCulture , Resources . FileDoesNotExist , path ) ;
58
100
return null ;
59
101
}
60
102
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 ) ;
63
105
64
106
error = null ;
65
107
return lines ;
@@ -73,14 +115,48 @@ public string[] LoadFile(string path, out string error)
73
115
74
116
private string MapPath ( string path )
75
117
{
76
- if ( this . sourceDirectories . Count == 0 || File . Exists ( path ) )
118
+ if ( File . Exists ( path ) )
77
119
{
78
120
return path ;
79
121
}
80
122
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
+ */
81
157
string [ ] parts = path . Split ( '/' , '\\ ' ) ;
82
158
83
- foreach ( var sourceDirectory in this . sourceDirectories )
159
+ foreach ( var sourceDirectory in directories )
84
160
{
85
161
for ( int i = 0 ; i < parts . Length ; i ++ )
86
162
{
0 commit comments