@@ -11,51 +11,74 @@ import scala.io.Source
11
11
12
12
object Serializer {
13
13
14
+ val coverageDataFormatVersion = " 3.0"
15
+
14
16
// Write out coverage data to the given data directory, using the default coverage filename
15
- def serialize (coverage : Coverage , dataDir : String ): Unit =
16
- serialize(coverage, coverageFile(dataDir))
17
+ def serialize (coverage : Coverage , dataDir : String , sourceRoot : String ): Unit =
18
+ serialize(coverage, coverageFile(dataDir), new File (sourceRoot) )
17
19
18
20
// Write out coverage data to given file.
19
- def serialize (coverage : Coverage , file : File ): Unit = {
21
+ def serialize (coverage : Coverage , file : File , sourceRoot : File ): Unit = {
20
22
val writer : Writer = new BufferedWriter (
21
23
new OutputStreamWriter (new FileOutputStream (file), Codec .UTF8 .name)
22
24
)
23
25
try {
24
- serialize(coverage, writer)
26
+ serialize(coverage, writer, sourceRoot )
25
27
} finally {
26
28
writer.flush()
27
29
writer.close()
28
30
}
29
31
}
30
32
31
- def serialize (coverage : Coverage , writer : Writer ): Unit = {
33
+ def serialize (
34
+ coverage : Coverage ,
35
+ writer : Writer ,
36
+ sourceRoot : File
37
+ ): Unit = {
38
+ def getRelativePath (filePath : String ): String = {
39
+ val base = sourceRoot.getCanonicalFile().toPath()
40
+ // NOTE: In the real world I have no idea if it's likely that you'll end
41
+ // up with weird issues on windows where the roots don't match, something
42
+ // like your root being D:/ and your file being C:/. If so this blows up.
43
+ // This happened on windows CI for me, since I was using a temp dir, and
44
+ // then trying to reletavize it off the cwd, which were in different
45
+ // drives. For now, we'll let this as is, but if 'other' has different
46
+ // root ever shows its, we'll shut that down real quick here... just not
47
+ // sure what to do in that situation yet.
48
+ val relPath =
49
+ base.relativize(new File (filePath).getCanonicalFile().toPath())
50
+ relPath.toString
51
+ }
52
+
32
53
def writeHeader (writer : Writer ): Unit = {
33
- writer.write(s """ # Coverage data, format version: 2.0
34
- |# Statement data:
35
- |# - id
36
- |# - source path
37
- |# - package name
38
- |# - class name
39
- |# - class type (Class, Object or Trait)
40
- |# - full class name
41
- |# - method name
42
- |# - start offset
43
- |# - end offset
44
- |# - line number
45
- |# - symbol name
46
- |# - tree name
47
- |# - is branch
48
- |# - invocations count
49
- |# - is ignored
50
- |# - description (can be multi-line)
51
- |# '\f' sign
52
- |# ------------------------------------------
53
- | """ .stripMargin.replaceAll(" (\r\n )|\n |\r " , " \n " ))
54
+ writer.write(
55
+ s """ # Coverage data, format version: $coverageDataFormatVersion
56
+ |# Statement data:
57
+ |# - id
58
+ |# - source path
59
+ |# - package name
60
+ |# - class name
61
+ |# - class type (Class, Object or Trait)
62
+ |# - full class name
63
+ |# - method name
64
+ |# - start offset
65
+ |# - end offset
66
+ |# - line number
67
+ |# - symbol name
68
+ |# - tree name
69
+ |# - is branch
70
+ |# - invocations count
71
+ |# - is ignored
72
+ |# - description (can be multi-line)
73
+ |# '\f' sign
74
+ |# ------------------------------------------
75
+ | """ .stripMargin
76
+ )
54
77
}
55
78
56
79
def writeStatement (stmt : Statement , writer : Writer ): Unit = {
57
80
writer.write(s """ ${stmt.id}
58
- | ${stmt.location.sourcePath}
81
+ | ${getRelativePath( stmt.location.sourcePath) }
59
82
| ${stmt.location.packageName}
60
83
| ${stmt.location.className}
61
84
| ${stmt.location.classType}
@@ -71,7 +94,7 @@ object Serializer {
71
94
| ${stmt.ignored}
72
95
| ${stmt.desc}
73
96
|\f
74
- | """ .stripMargin.replaceAll( " ( \r\n )| \n | \r " , " \n " ) )
97
+ | """ .stripMargin)
75
98
}
76
99
77
100
writeHeader(writer)
@@ -84,13 +107,20 @@ object Serializer {
84
107
def coverageFile (dataDir : String ): File =
85
108
new File (dataDir, Constants .CoverageFileName )
86
109
87
- def deserialize (file : File ): Coverage = {
110
+ def deserialize (file : File , sourceRoot : File ): Coverage = {
88
111
val source = Source .fromFile(file)(Codec .UTF8 )
89
- try deserialize(source.getLines())
112
+ try deserialize(source.getLines(), sourceRoot )
90
113
finally source.close()
91
114
}
92
115
93
- def deserialize (lines : Iterator [String ]): Coverage = {
116
+ def deserialize (lines : Iterator [String ], sourceRoot : File ): Coverage = {
117
+ // To integrate it smoothly with rest of the report writers,
118
+ // it is necessary to again convert [sourcePath] into a
119
+ // canonical one.
120
+ def getAbsolutePath (filePath : String ): String = {
121
+ new File (sourceRoot, filePath).getCanonicalPath()
122
+ }
123
+
94
124
def toStatement (lines : Iterator [String ]): Statement = {
95
125
val id : Int = lines.next().toInt
96
126
val sourcePath = lines.next()
@@ -105,7 +135,7 @@ object Serializer {
105
135
fullClassName,
106
136
ClassType .fromString(classType),
107
137
method,
108
- sourcePath
138
+ getAbsolutePath( sourcePath)
109
139
)
110
140
val start : Int = lines.next().toInt
111
141
val end : Int = lines.next().toInt
@@ -133,7 +163,7 @@ object Serializer {
133
163
134
164
val headerFirstLine = lines.next()
135
165
require(
136
- headerFirstLine == " # Coverage data, format version: 2.0 " ,
166
+ headerFirstLine == s " # Coverage data, format version: $coverageDataFormatVersion " ,
137
167
" Wrong file format"
138
168
)
139
169
0 commit comments