From 9d64870144f2ce673a04aa8e712e895a25b6fe2e Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Wed, 10 Nov 2021 13:02:16 +0900 Subject: [PATCH] fix: require node-gyp@^8.4.0 & handle old Electron versions (#907) Co-authored-by: Mark Lee Co-authored-by: Mark Lee --- package.json | 8 +++-- src/module-type/node-gyp.ts | 9 +++++ test/helpers/module-setup.ts | 6 ++-- test/module-type-node-gyp.ts | 61 +++++++++++++++++++++++++++++++ yarn.lock | 69 ++++++++++++++++++++++-------------- 5 files changed, 122 insertions(+), 31 deletions(-) create mode 100644 test/module-type-node-gyp.ts diff --git a/package.json b/package.json index e7ece13..29707c9 100644 --- a/package.json +++ b/package.json @@ -47,8 +47,9 @@ "lzma-native": "^8.0.1", "node-abi": "^3.0.0", "node-api-version": "^0.1.4", - "node-gyp": "^8.1.0", + "node-gyp": "^8.4.0", "ora": "^5.1.0", + "semver": "^7.3.5", "tar": "^6.0.5", "yargs": "^17.0.1" }, @@ -64,6 +65,7 @@ "@types/mocha": "^9.0.0", "@types/node": "^16.0.1", "@types/node-abi": "^3.0.0", + "@types/semver": "^7.3.9", "@types/tar": "^6.1.0", "@types/yargs": "^17.0.2", "@typescript-eslint/eslint-plugin": "^4.0.1", @@ -119,7 +121,9 @@ "node_modules" ], "mocha": { - "extensions": ["ts"], + "extensions": [ + "ts" + ], "require": "ts-node/register" }, "nyc": { diff --git a/src/module-type/node-gyp.ts b/src/module-type/node-gyp.ts index 7856177..73eb8ed 100644 --- a/src/module-type/node-gyp.ts +++ b/src/module-type/node-gyp.ts @@ -3,6 +3,7 @@ import detectLibc from 'detect-libc'; import NodeGypRunner from 'node-gyp'; import path from 'path'; import { promisify } from 'util'; +import semver from 'semver'; import { ELECTRON_GYP_DIR } from '../constants'; import { getClangEnvironmentVars } from '../clang-fetcher'; @@ -36,6 +37,14 @@ export class NodeGyp extends NativeModule { args.push(`--msvs_version=${this.rebuilder.msvsVersion}`); } + // Headers of old Electron versions do not have a valid config.gypi file + // and --force-process-config must be passed to node-gyp >= 8.4.0 to + // correctly build modules for them. + // See also https://github.com/nodejs/node-gyp/pull/2497 + if (!semver.satisfies(this.rebuilder.electronVersion, '^14.2.0 || ^15.3.0 || >= 16.0.0-alpha.1')) { + args.push('--force-process-config'); + } + return args; } diff --git a/test/helpers/module-setup.ts b/test/helpers/module-setup.ts index fa34f6f..3a71794 100644 --- a/test/helpers/module-setup.ts +++ b/test/helpers/module-setup.ts @@ -14,14 +14,16 @@ export function resetMSVSVersion(): void { } } -export async function resetTestModule(testModulePath: string): Promise { +export async function resetTestModule(testModulePath: string, installModules = true): Promise { await fs.remove(testModulePath); await fs.mkdir(testModulePath, { recursive: true }); await fs.copyFile( path.resolve(__dirname, '../../test/fixture/native-app1/package.json'), path.resolve(testModulePath, 'package.json') ); - await spawn('npm', ['install'], { cwd: testModulePath }); + if (installModules) { + await spawn('npm', ['install'], { cwd: testModulePath }); + } resetMSVSVersion(); } diff --git a/test/module-type-node-gyp.ts b/test/module-type-node-gyp.ts new file mode 100644 index 0000000..9ebd170 --- /dev/null +++ b/test/module-type-node-gyp.ts @@ -0,0 +1,61 @@ +import { EventEmitter } from 'events'; +import { expect } from 'chai'; +import os from 'os'; +import path from 'path'; + +import { cleanupTestModule, resetTestModule } from './helpers/module-setup'; +import { NodeGyp } from '../src/module-type/node-gyp'; +import { Rebuilder } from '../src/rebuild'; + +describe('node-gyp', () => { + describe('buildArgs', () => { + const testModulePath = path.resolve(os.tmpdir(), 'electron-rebuild-test'); + + before(async () => await resetTestModule(testModulePath, false)); + after(async () => await cleanupTestModule(testModulePath)); + + function nodeGypArgsForElectronVersion(electronVersion: string): Promise { + const rebuilder = new Rebuilder({ + buildPath: testModulePath, + electronVersion: electronVersion, + lifecycle: new EventEmitter() + }); + const nodeGyp = new NodeGyp(rebuilder, testModulePath); + return nodeGyp.buildArgs([]); + } + + context('sufficiently old Electron versions which lack a bundled config.gypi', () => { + it('adds --force-process-config for < 14', async () => { + const args = await nodeGypArgsForElectronVersion('12.0.0'); + expect(args).to.include('--force-process-config'); + }); + + it('adds --force-process-config for between 14.0.0 and < 14.2.0', async () => { + const args = await nodeGypArgsForElectronVersion('14.1.0'); + expect(args).to.include('--force-process-config'); + }); + + it('adds --force-process-config for versions between 15.0.0 and < 15.3.0', async () => { + const args = await nodeGypArgsForElectronVersion('15.2.0'); + expect(args).to.include('--force-process-config'); + }); + }); + + context('for sufficiently new Electron versions', () => { + it('does not add --force-process-config for ^14.2.0', async () => { + const args = await nodeGypArgsForElectronVersion('14.2.0'); + expect(args).to.not.include('--force-process-config'); + }); + + it('does not add --force-process-config for ^15.3.0', async () => { + const args = await nodeGypArgsForElectronVersion('15.3.0'); + expect(args).to.not.include('--force-process-config'); + }); + + it('does not add --force-process-config for >= 16.0.0', async () => { + const args = await nodeGypArgsForElectronVersion('16.0.0-alpha.1'); + expect(args).to.not.include('--force-process-config'); + }); + }); + }); +}); diff --git a/yarn.lock b/yarn.lock index cf04a29..e2c4075 100644 --- a/yarn.lock +++ b/yarn.lock @@ -844,6 +844,11 @@ resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.1.tgz#d8f1c0d0dc23afad6dc16a9e993a0865774b4065" integrity sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g== +"@types/semver@^7.3.9": + version "7.3.9" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.9.tgz#152c6c20a7688c30b967ec1841d31ace569863fc" + integrity sha512-L/TMpyURfBkf+o/526Zb6kd/tchUP3iBDEPjqjb+U2MAJhVRxxrmr2fwpe08E7QsV7YLcpq0tUaQ9O9x97ZIxQ== + "@types/tar@^6.1.0": version "6.1.0" resolved "https://registry.yarnpkg.com/@types/tar/-/tar-6.1.0.tgz#a73202f706c592242a62e8e5970b2694662f1d8d" @@ -4590,27 +4595,6 @@ make-fetch-happen@^5.0.0: socks-proxy-agent "^4.0.0" ssri "^6.0.0" -make-fetch-happen@^8.0.14: - version "8.0.14" - resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-8.0.14.tgz#aaba73ae0ab5586ad8eaa68bd83332669393e222" - integrity sha512-EsS89h6l4vbfJEtBZnENTOFk8mCRpY5ru36Xe5bcX1KYIli2mkSHqoFsp5O1wMDvTJJzxe/4THpCTtygjeeGWQ== - dependencies: - agentkeepalive "^4.1.3" - cacache "^15.0.5" - http-cache-semantics "^4.1.0" - http-proxy-agent "^4.0.1" - https-proxy-agent "^5.0.0" - is-lambda "^1.0.1" - lru-cache "^6.0.0" - minipass "^3.1.3" - minipass-collect "^1.0.2" - minipass-fetch "^1.3.2" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.4" - promise-retry "^2.0.1" - socks-proxy-agent "^5.0.0" - ssri "^8.0.0" - make-fetch-happen@^9.0.1, make-fetch-happen@^9.0.4: version "9.0.4" resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-9.0.4.tgz#ceaa100e60e0ef9e8d1ede94614bb2ba83c8bb24" @@ -4633,6 +4617,28 @@ make-fetch-happen@^9.0.1, make-fetch-happen@^9.0.4: socks-proxy-agent "^5.0.0" ssri "^8.0.0" +make-fetch-happen@^9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz#53085a09e7971433e6765f7971bf63f4e05cb968" + integrity sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg== + dependencies: + agentkeepalive "^4.1.3" + cacache "^15.2.0" + http-cache-semantics "^4.1.0" + http-proxy-agent "^4.0.1" + https-proxy-agent "^5.0.0" + is-lambda "^1.0.1" + lru-cache "^6.0.0" + minipass "^3.1.3" + minipass-collect "^1.0.2" + minipass-fetch "^1.3.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + negotiator "^0.6.2" + promise-retry "^2.0.1" + socks-proxy-agent "^6.0.0" + ssri "^8.0.0" + map-obj@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" @@ -5066,15 +5072,15 @@ node-gyp@^7.1.0, node-gyp@^7.1.2: tar "^6.0.2" which "^2.0.2" -node-gyp@^8.1.0: - version "8.2.0" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-8.2.0.tgz#ef509ccdf5cef3b4d93df0690b90aa55ff8c7977" - integrity sha512-KG8SdcoAnw2d6augGwl1kOayALUrXW/P2uOAm2J2+nmW/HjZo7y+8TDg7LejxbekOOSv3kzhq+NSUYkIDAX8eA== +node-gyp@^8.4.0: + version "8.4.0" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-8.4.0.tgz#6e1112b10617f0f8559c64b3f737e8109e5a8338" + integrity sha512-Bi/oCm5bH6F+FmzfUxJpPaxMEyIhszULGR3TprmTeku8/dMFcdTcypk120NeZqEt54r1BrgEKtm2jJiuIKE28Q== dependencies: env-paths "^2.2.0" glob "^7.1.4" graceful-fs "^4.2.6" - make-fetch-happen "^8.0.14" + make-fetch-happen "^9.1.0" nopt "^5.0.0" npmlog "^4.1.2" rimraf "^3.0.2" @@ -6817,7 +6823,16 @@ socks-proxy-agent@^5.0.0: debug "4" socks "^2.3.3" -socks@^2.3.3: +socks-proxy-agent@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-6.1.0.tgz#869cf2d7bd10fea96c7ad3111e81726855e285c3" + integrity sha512-57e7lwCN4Tzt3mXz25VxOErJKXlPfXmkMLnk310v/jwW20jWRVcgsOit+xNkN3eIEdB47GwnfAEBLacZ/wVIKg== + dependencies: + agent-base "^6.0.2" + debug "^4.3.1" + socks "^2.6.1" + +socks@^2.3.3, socks@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/socks/-/socks-2.6.1.tgz#989e6534a07cf337deb1b1c94aaa44296520d30e" integrity sha512-kLQ9N5ucj8uIcxrDwjm0Jsqk06xdpBjGNQtpXy4Q8/QY2k+fY7nZH8CARy+hkbG+SGAovmzzuauCpBlb8FrnBA==