Skip to content

Commit 9210f03

Browse files
committed
fix(middleware-code-coverage): Lazy evaluate exclude patterns
This prevents the initial evaluation of exclude patterns on middleware initialization, which is not necessary in case the middleware is not used. Calculating exclude patterns requires to read and parse all .library files of the project and its dependencies.
1 parent e680542 commit 9210f03

File tree

4 files changed

+402
-107
lines changed

4 files changed

+402
-107
lines changed

packages/middleware-code-coverage/lib/middleware.js

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ import {
33
createInstrumentationConfig,
44
shouldInstrumentResource,
55
getLatestSourceMap,
6-
readJsonFile} from "./util.js";
6+
readJsonFile,
7+
getLibraryCoverageExcludePatterns
8+
} from "./util.js";
79
import {createInstrumenter} from "istanbul-lib-instrument";
810
import reportCoverage from "./coverage-reporter.js";
911
import bodyParser from "body-parser";
@@ -104,9 +106,22 @@ export default async function({log, middlewareUtil, options={}, resources}) {
104106
)
105107
);
106108

109+
let excludePatterns;
110+
107111
router.use(async (req, res, next) => {
112+
// Lazy initialize exclude patterns
113+
if (excludePatterns === undefined) {
114+
// Custom patterns take precedence over .library defined patterns (also when set to null)
115+
if (generalConfig.excludePatterns !== undefined) {
116+
excludePatterns = generalConfig.excludePatterns;
117+
} else {
118+
// Read patterns from .library files, this should only be done if needed and only once
119+
excludePatterns = await getLibraryCoverageExcludePatterns(resources.all);
120+
}
121+
}
122+
108123
// Skip files which should not be instrumented
109-
if (!shouldInstrumentResource(req, generalConfig)) {
124+
if (!shouldInstrumentResource(req, excludePatterns)) {
110125
next();
111126
return;
112127
}

packages/middleware-code-coverage/lib/util.js

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,15 @@ import {readFile} from "node:fs/promises";
77
*
88
* @public
99
* @param {object} configuration instrumentation configuration
10-
* @param {@ui5/fs/Resource[]} resources
1110
* @returns {Promise<object>} configuration
1211
*/
13-
export async function createInstrumentationConfig(configuration = {}, resources) {
14-
const excludedPatterns = resources ? await excludePatterns(resources) : [];
15-
12+
export async function createInstrumentationConfig(configuration = {}) {
1613
const {instrument, report, ...generalConfig} = configuration;
1714

1815
return {
1916
// General configuration
2017
cwd: "./",
21-
excludePatterns: excludedPatterns,
18+
2219
// General config overwrites
2320
...generalConfig,
2421

@@ -55,17 +52,17 @@ export function getLatestSourceMap(instrumenter) {
5552
*
5653
* @public
5754
* @param {object} request
58-
* @param {object} config
55+
* @param {Array<RegExp|string>} excludePatterns Patterns to exclude file from instrumentation (RegExp or string)
5956
* @returns {boolean}
6057
*/
61-
export function shouldInstrumentResource(request, config) {
58+
export function shouldInstrumentResource(request, excludePatterns) {
6259
return (
6360
request.path &&
6461
request.path.endsWith(".js") && // Only .js file requests
6562
!isFalsyValue(request.query.instrument) && // instrument only flagged files, ignore "falsy" values
66-
!(config && config.excludePatterns || []).some((pattern) => {
63+
!(excludePatterns || []).some((pattern) => {
6764
if (pattern instanceof RegExp) {
68-
// The ones comming from .library files are regular expressions
65+
// The ones coming from .library files are regular expressions
6966
return pattern.test(request.path);
7067
} else {
7168
return request.path.includes(pattern);
@@ -131,13 +128,13 @@ function isFalsyValue(value) {
131128
* Note: We might consider to move this utility into the @ui5/project
132129
*
133130
* @private
134-
* @param {@ui5/fs/Resource[]} resources
131+
* @param {@ui5/fs/AbstractReader} reader
135132
* @returns {Promise<RegExp[]>} exclude patterns
136133
*/
137-
async function excludePatterns(resources) {
134+
export async function getLibraryCoverageExcludePatterns(reader) {
138135
const aExcludes = [];
139136
// Read excludes from .library files
140-
const aDotLibrary = await resources.byGlob(["/resources/**/.library"]);
137+
const aDotLibrary = await reader.byGlob(["/resources/**/.library"]);
141138
for (const oDotLibrary of aDotLibrary) {
142139
const content = await oDotLibrary.getString();
143140
const result = await xml2js.parseStringPromise(content);

0 commit comments

Comments
 (0)