diff --git a/README.md b/README.md index d2ac00b63..eb5d61f19 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,7 @@ Options: -g, --gid Set the gid (posix only) -a, --append Turns on append results to file mode rather than replace --tmpDir Directory to test modules in + --printLockFile Print the failed module's package-lock.json/yarn.lock file ``` ### Examples: diff --git a/lib/bin/citgm-all.js b/lib/bin/citgm-all.js index cbb61544d..3a630ce2d 100755 --- a/lib/bin/citgm-all.js +++ b/lib/bin/citgm-all.js @@ -69,6 +69,7 @@ const options = { tmpDir: app.tmpDir, customTest: app.customTest, yarn: app.yarn, + printLockFile: app.printLockFile, includeTags: app.includeTags || [], excludeTags: app.excludeTags || [] }; diff --git a/lib/bin/citgm.js b/lib/bin/citgm.js index 3bdc2763f..d5ffec345 100755 --- a/lib/bin/citgm.js +++ b/lib/bin/citgm.js @@ -45,7 +45,8 @@ const options = { sha: app.sha, tmpDir: app.tmpDir, customTest: app.customTest, - yarn: app.yarn + yarn: app.yarn, + printLockFile: app.printLockFile }; if (!windows) { diff --git a/lib/citgm.js b/lib/citgm.js index d6b74981f..c98dce74b 100644 --- a/lib/citgm.js +++ b/lib/citgm.js @@ -9,6 +9,7 @@ import { grabModuleData } from './grab-module-data.js'; import { grabProject } from './grab-project.js'; import { lookup } from './lookup.js'; import { + getLockFileContent, getPackageManagers, pkgInstall, pkgTest @@ -115,6 +116,19 @@ export class Tester extends EventEmitter { if (!payload.expectFail) { this.emit('fail', err); payload.error = err; + + if (this.options.printLockFile) { + const lockFile = await getLockFileContent(this); + + if (lockFile?.content) { + // TODO - multiline output is not handled well + this.emit( + 'data', + 'info', + `${this.module.name} ${lockFile.fileName} lock file content ${lockFile?.content}` + ); + } + } } } else if (payload.expectFail) { this.emit('fail', 'this module should have failed'); diff --git a/lib/common-args.js b/lib/common-args.js index adcb00aec..53af0363f 100644 --- a/lib/common-args.js +++ b/lib/common-args.js @@ -82,6 +82,11 @@ export function commonArgs() { description: 'Install and test the project using yarn instead of npm', default: false }) + .option('printLockFile', { + type: 'boolean', + description: `Print the failed module's package-lock.json/yarn.lock file`, + default: false + }) .example( 'citgm-all --customTest /path/to/customTest.js', 'Runs a custom node test script instead of "npm test"' diff --git a/lib/package-manager/get-lock-file.js b/lib/package-manager/get-lock-file.js new file mode 100644 index 000000000..87d219201 --- /dev/null +++ b/lib/package-manager/get-lock-file.js @@ -0,0 +1,31 @@ +import { readFile } from 'node:fs/promises'; +import { join } from 'node:path'; + +export async function getLockFile(packageManager, context) { + let lockFileName = 'package-lock.json'; + + if (packageManager === 'yarn') { + lockFileName = 'yarn.lock'; + } + const lockFilePath = join(context.path, context.module.name, lockFileName); + + try { + const fileContent = await readFile(lockFilePath, 'utf8'); + + return { + fileName: lockFileName, + content: fileContent.toString() + }; + } catch (err) { + if (err.code === 'ENOENT') { + return undefined; + } + + context.emit( + 'data', + 'warn', + `${context.module.name} ${packageManager}-get-lock-file:`, + `Failed to read lock file ${lockFileName} ${err.message}` + ); + } +} diff --git a/lib/package-manager/index.js b/lib/package-manager/index.js index 657dae4c5..f39082a19 100644 --- a/lib/package-manager/index.js +++ b/lib/package-manager/index.js @@ -1,6 +1,7 @@ import install from './install.js'; import { test } from './test.js'; import { getExecutable } from './get-executable.js'; +import { getLockFile } from './get-lock-file.js'; export function pkgInstall(context) { if (context.options.yarn || context.module.useYarn) { @@ -25,3 +26,11 @@ export async function getPackageManagers() { ]); return { npm, yarn }; } + +export function getLockFileContent(context) { + if (context.options.yarn || context.module.useYarn) { + return getLockFile('yarn', context); + } else { + return getLockFile('npm', context); + } +}