From 2a814b57e1a920a0c910a1007b50142423386ff0 Mon Sep 17 00:00:00 2001 From: "mannie.exe" <7815113+schmannie@users.noreply.github.com> Date: Thu, 21 Jul 2022 10:17:21 -0700 Subject: [PATCH] Respect `package.json`'s `engines.node` field when used as a `node-version-file` (#485) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Allow reading 'package.json' as node-version-file * Run 'npm run build' * Read package.json contents directly during tests - this eliminates OS-specific line-ending issues * Run project Prettier 💅 --- __tests__/data/package.json | 5 +++++ __tests__/installer.test.ts | 27 +++++++++++++++++++++++++++ dist/setup/index.js | 24 +++++++++++++++++------- src/installer.ts | 22 ++++++++++++++++------ 4 files changed, 65 insertions(+), 13 deletions(-) create mode 100644 __tests__/data/package.json diff --git a/__tests__/data/package.json b/__tests__/data/package.json new file mode 100644 index 000000000..e537e2005 --- /dev/null +++ b/__tests__/data/package.json @@ -0,0 +1,5 @@ +{ + "engines": { + "node": ">=14.0.0" + } +} diff --git a/__tests__/installer.test.ts b/__tests__/installer.test.ts index cd5361929..c1e16b5fc 100644 --- a/__tests__/installer.test.ts +++ b/__tests__/installer.test.ts @@ -591,6 +591,33 @@ describe('setup-node', () => { ); }); + it('reads package.json as node-version-file if provided', async () => { + // Arrange + const versionSpec = fs.readFileSync( + path.join(__dirname, 'data/package.json'), + 'utf-8' + ); + const versionFile = 'package.json'; + const expectedVersionSpec = '14'; + process.env['GITHUB_WORKSPACE'] = path.join(__dirname, 'data'); + inputs['node-version-file'] = versionFile; + + parseNodeVersionSpy.mockImplementation(() => expectedVersionSpec); + existsSpy.mockImplementationOnce( + input => input === path.join(__dirname, 'data', versionFile) + ); + // Act + await main.run(); + + // Assert + expect(existsSpy).toHaveBeenCalledTimes(1); + expect(existsSpy).toHaveReturnedWith(true); + expect(parseNodeVersionSpy).toHaveBeenCalledWith(versionSpec); + expect(logSpy).toHaveBeenCalledWith( + `Resolved ${versionFile} as ${expectedVersionSpec}` + ); + }); + it('both node-version-file and node-version are provided', async () => { inputs['node-version'] = '12'; const versionSpec = 'v14'; diff --git a/dist/setup/index.js b/dist/setup/index.js index 28d5dc8fd..0a0c0bade 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -71768,15 +71768,25 @@ function translateArchToDistUrl(arch) { } } function parseNodeVersionFile(contents) { - var _a; + var _a, _b; + let nodeVersion; const found = contents.match(/^(?:nodejs\s+)?v?(?[^\s]+)$/m); - const nodeVersion = (_a = found === null || found === void 0 ? void 0 : found.groups) === null || _a === void 0 ? void 0 : _a.version; - if (nodeVersion) { - return nodeVersion; + nodeVersion = (_a = found === null || found === void 0 ? void 0 : found.groups) === null || _a === void 0 ? void 0 : _a.version; + if (!nodeVersion) { + try { + // Try parsing the file as an NPM `package.json` + // file. + nodeVersion = (_b = JSON.parse(contents).engines) === null || _b === void 0 ? void 0 : _b.node; + if (!nodeVersion) + throw new Error(); + } + catch (err) { + // In the case of an unknown format, + // return as is and evaluate the version separately. + nodeVersion = contents.trim(); + } } - // In the case of an unknown format, - // return as is and evaluate the version separately. - return contents.trim(); + return nodeVersion; } exports.parseNodeVersionFile = parseNodeVersionFile; function isLatestSyntax(versionSpec) { diff --git a/src/installer.ts b/src/installer.ts index 019f2edab..193ff16a7 100644 --- a/src/installer.ts +++ b/src/installer.ts @@ -495,16 +495,26 @@ function translateArchToDistUrl(arch: string): string { } export function parseNodeVersionFile(contents: string): string { + let nodeVersion: string | undefined; + const found = contents.match(/^(?:nodejs\s+)?v?(?[^\s]+)$/m); - const nodeVersion = found?.groups?.version; + nodeVersion = found?.groups?.version; + + if (!nodeVersion) { + try { + // Try parsing the file as an NPM `package.json` + // file. + nodeVersion = JSON.parse(contents).engines?.node; - if (nodeVersion) { - return nodeVersion; + if (!nodeVersion) throw new Error(); + } catch (err) { + // In the case of an unknown format, + // return as is and evaluate the version separately. + nodeVersion = contents.trim(); + } } - // In the case of an unknown format, - // return as is and evaluate the version separately. - return contents.trim(); + return nodeVersion as string; } function isLatestSyntax(versionSpec): boolean {