From 63e591af4b3bfbfc765793454b2802097a76885c Mon Sep 17 00:00:00 2001 From: Michael Jones Date: Fri, 17 May 2024 11:40:02 +0200 Subject: [PATCH] feat!: remove temp file creation and usage --- README.md | 15 +++++++ bin/lcov-result-merger.js | 16 ++------ index.d.ts | 1 - index.js | 22 +++++------ lib/configuration.js | 39 ------------------- ...merge-coverage-report-file-streams-spec.js | 20 ++++------ 6 files changed, 36 insertions(+), 77 deletions(-) diff --git a/README.md b/README.md index badbeb4..797f072 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,8 @@ have the code coverage across all testsuites. This tool will handle this for you. +> See the [Migration Notes](#migrating-notes) below if you are looking to upgrade between major versions. + # Usage ```bash @@ -45,3 +47,16 @@ works well for common tools such as [NYC](https://github.com/istanbuljs/nyc) tha ```bash ./node_modules/.bin/lcov-result-merger 'FILE_PATTERN' ['OUTPUT_FILE'] --prepend-source-files --prepend-path-fix "../src" ``` + +## Migrating Notes +Additional information about breaking changes. + +### Version 6 +- The `--legacy-temp-file` flag has been removed. This means that if your project is expecting an + errant `lcov.info` file to be created in the PWD, then it will need to be updated to instead use + the output file specified when running the command. + +- The internal usage of temp files has also been eliminated. This only effects project that are + directly importing the `mergeCoverageReportFiles` or `mergeCoverageReportFilesStream` functions + into their own code. Both of these methods now return the merged LCOV content directly, in the + form of a string, instead of a path to the temporary file where that content could be read. diff --git a/bin/lcov-result-merger.js b/bin/lcov-result-merger.js index 21c41c7..df14521 100755 --- a/bin/lcov-result-merger.js +++ b/bin/lcov-result-merger.js @@ -1,6 +1,6 @@ #!/usr/bin/env node const fastGlob = require('fast-glob'); -const { copyFile, readFile } = require('node:fs/promises'); +const { writeFile } = require('node:fs/promises'); const { mergeCoverageReportFiles } = require('../index'); const yargs = require('yargs/yargs'); const { hideBin } = require('yargs/helpers'); @@ -37,14 +37,6 @@ const args = yargs(hideBin(process.argv)).command( 'If using --prepend-source-files, this is needed to describe the relative path from the lcov ' + 'directory to the project root.', }, - 'legacy-temp-file': { - type: 'boolean', - default: false, - description: - 'Prior to version 5, a lcov.info file containing the merged output was created in the ' + - "current working directory. The operating system's temporary directory is now used by default, " + - 'but if you relied on prior behavior then this flag will recreate it.', - }, ignore: { type: 'array', default: [], @@ -60,11 +52,11 @@ const args = yargs(hideBin(process.argv)).command( ignore: args.ignore, }); - const tempFilePath = await mergeCoverageReportFiles(files, args); + const mergeResults = await mergeCoverageReportFiles(files, args); if (args.outFile) { - await copyFile(tempFilePath, args.outFile); + await writeFile(args.outFile, mergeResults, 'utf-8'); } else { - process.stdout.write(await readFile(tempFilePath, 'utf-8')); + process.stdout.write(mergeResults + '\n'); } })(); diff --git a/index.d.ts b/index.d.ts index fe3ea8c..1d44be5 100644 --- a/index.d.ts +++ b/index.d.ts @@ -5,7 +5,6 @@ type ConfigurationPojo = { outFile?: string prependSourceFiles?: boolean prependPathFix?: string - legacyTempFile?: boolean ignore?: string[] } diff --git a/index.js b/index.js index a2aa57f..b4c3cd9 100644 --- a/index.js +++ b/index.js @@ -2,11 +2,11 @@ * LCOV result merger * * @author Michael Weibel - * @copyright 2013-2023 Michael Weibel + * @copyright 2013-2024 Michael Weibel * @license MIT */ -const { readFile, writeFile } = require('node:fs/promises'); +const { readFile } = require('node:fs/promises'); const path = require('node:path'); const { Transform } = require('node:stream'); const Configuration = require('./lib/configuration'); @@ -77,7 +77,7 @@ function processFile(sourceDir, data, lcov, config) { } /** - * + * Merge together the LCOV contents of the provided files. * * @param {string[]} filePaths * @param {import("./lib/configuration").ConfigurationPojo} options @@ -93,18 +93,11 @@ async function mergeCoverageReportFiles(filePaths, options) { processFile(path.dirname(filePath), fileContent, report, config); } - const tmpFile = await config.getTempFilePath(); - - await writeFile(tmpFile, Buffer.from(report.toString()), { - encoding: 'utf-8', - flag: 'w+', - }); - - return tmpFile; + return report.toString().trim(); } /** - * + * A Stream wrapper for the merge utility. */ class WrappingTransform extends Transform { constructor(filePathsOrMergeOptions, mergeOptions) { @@ -128,13 +121,16 @@ class WrappingTransform extends Transform { _flush(callback) { mergeCoverageReportFiles(this.filePaths, this.mergeOptions).then( - (tempFile) => callback(null, tempFile), + (fullReport) => callback(null, fullReport.toString().trim()), (error) => callback(error) ); } } /** + * A variation of the `mergeCoverageReportFiles()` utility that will return a + * stream instead of a promise. + * * @param {string[] | import("./lib/configuration").ConfigurationPojo} [filePathsOrOptions] * @param {import("./lib/configuration").ConfigurationPojo} [options] * diff --git a/lib/configuration.js b/lib/configuration.js index e14db5e..7524551 100644 --- a/lib/configuration.js +++ b/lib/configuration.js @@ -1,10 +1,3 @@ -const { join } = require('node:path'); -const { tmpdir } = require('node:os'); -const { mkdtemp } = require('node:fs'); -const { promisify } = require('node:util'); - -const mkdtempAsync = promisify(mkdtemp); - /** * @typedef {Object} ConfigurationPojo * @@ -14,8 +7,6 @@ const mkdtempAsync = promisify(mkdtemp); * @property {boolean} [prepend-source-files=false] * @property {string} [prependPathFix] * @property {string} [prepend-path-fix] - * @property {boolean} [legacyTempFile=false] - * @property {boolean} [legacy-temp-file=false] * @property {string[]} [ignore] */ @@ -67,35 +58,5 @@ module.exports = class Configuration { : typeof partial['prepend-path-fix'] === 'string' ? partial['prepend-path-fix'] : '..'; - - /** - * Prior to version 5, a lcov.info file containing the merged output was created in the - * current working directory. The operating system's temporary directory is now used by default, - * but if you relied on prior behavior then this flag will recreate it. - * - * @type {boolean} - */ - this.legacyTempFile = - typeof partial.legacyTempFile === 'boolean' - ? partial.legacyTempFile - : typeof partial['legacy-temp-file'] === 'boolean' - ? partial['legacy-temp-file'] - : false; - } - - /** - * @param {string} [fileName="lcov.info"] - * @param {string} [prefix="lcov-result-merger"] - * @return {Promise} - */ - async getTempFilePath( - fileName = 'lcov.info', - prefix = 'lcov-result-merger-' - ) { - const tmpPath = this.legacyTempFile - ? '' - : await mkdtempAsync(join(tmpdir(), prefix)); - - return join(tmpPath, fileName); } }; diff --git a/test/test-e2e/merge-coverage-report-file-streams-spec.js b/test/test-e2e/merge-coverage-report-file-streams-spec.js index f215d21..08f4d6c 100644 --- a/test/test-e2e/merge-coverage-report-file-streams-spec.js +++ b/test/test-e2e/merge-coverage-report-file-streams-spec.js @@ -2,14 +2,14 @@ const fastGlob = require('fast-glob'); const chai = require('chai'); -const { getActual, getExpected } = require('../helpers'); +const { getExpected } = require('../helpers'); const { mergeCoverageReportFilesStream } = require('../../index.js'); chai.should(); async function testStream(pattern, filePathsOrOptions, options) { return new Promise((resolve) => { - let tempFilePath; + let mergeResult; const stream = pattern ? fastGlob @@ -19,26 +19,24 @@ async function testStream(pattern, filePathsOrOptions, options) { stream .on('data', (chunk) => { - tempFilePath = chunk.toString(); + mergeResult = chunk.toString(); }) .on('end', () => { - resolve(tempFilePath); + resolve(mergeResult); }); }); } describe('mergeCoverageReportFilesStream', function () { it('should combine the given records into one', async function () { - const output = await testStream('./test/fixtures/basic/*/lcov.info'); - const actual = await getActual(output); + const actual = await testStream('./test/fixtures/basic/*/lcov.info'); const expect = await getExpected('basic'); return actual.should.equal(expect); }); it('should handle a record with : in the name', async function () { - const output = await testStream('./test/fixtures/windows/lcov.info'); - const actual = await getActual(output); + const actual = await testStream('./test/fixtures/windows/lcov.info'); const expect = await getExpected('windows'); return actual.should.equal(expect); @@ -48,8 +46,7 @@ describe('mergeCoverageReportFilesStream', function () { const pattern = './test/fixtures/basic/*/lcov.info'; const options = { 'prepend-source-files': true, 'prepend-path-fix': '' }; - const output = await testStream(pattern, options); - const actual = await getActual(output); + const actual = await testStream(pattern, options); const expect = await getExpected('prepended'); return actual.should.equal(expect); @@ -59,8 +56,7 @@ describe('mergeCoverageReportFilesStream', function () { const pattern = './test/fixtures/coverage-subfolder/*/coverage/lcov.info'; const options = { 'prepend-source-files': true }; - const output = await testStream(pattern, options); - const actual = await getActual(output); + const actual = await testStream(pattern, options); const expect = await getExpected('prepended-path-fix'); return actual.should.equal(expect);