Skip to content

Commit d52997e

Browse files
committed
feat: convert internal classes from util.inherits to classes
BREAKING CHANGE: the `Gyp` class exported is now created using ECMAScript classes and therefore might have small differences to classes that were previously created with `util.inherits`.
1 parent 355622f commit d52997e

File tree

7 files changed

+303
-340
lines changed

7 files changed

+303
-340
lines changed

lib/configure.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ const win = process.platform === 'win32'
99
const findNodeDirectory = require('./find-node-directory')
1010
const createConfigGypi = require('./create-config-gypi')
1111
const { format: msgFormat } = require('util')
12-
const findPython = require('./find-python')
13-
const findVisualStudio = win ? require('./find-visualstudio') : null
12+
const { findPython } = require('./find-python')
13+
const { findVisualStudio } = win ? require('./find-visualstudio') : {}
1414

1515
async function configure (gyp, argv) {
1616
const buildDir = path.resolve('build')

lib/find-python.js

Lines changed: 39 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,15 @@
22

33
const log = require('./log')
44
const semver = require('semver')
5-
const { _extend: extend } = require('util') // eslint-disable-line n/no-deprecated-api
65
const { execFile } = require('./util')
76
const win = process.platform === 'win32'
87

8+
function getOsUserInfo () {
9+
try {
10+
return require('os').userInfo().username
11+
} catch {}
12+
}
13+
914
const systemDrive = process.env.SystemDrive || 'C:'
1015
const username = process.env.USERNAME || process.env.USER || getOsUserInfo()
1116
const localAppData = process.env.LOCALAPPDATA || `${systemDrive}\\${username}\\AppData\\Local`
@@ -32,40 +37,36 @@ for (const majorMinor of ['311', '310', '39', '38']) {
3237
}
3338
}
3439

35-
function getOsUserInfo () {
36-
try {
37-
return require('os').userInfo().username
38-
} catch (e) {}
39-
}
40-
41-
function PythonFinder (configPython) {
42-
this.configPython = configPython
43-
this.errorLog = []
44-
}
40+
class PythonFinder {
41+
static findPython = (...args) => new PythonFinder(...args).findPython()
4542

46-
PythonFinder.prototype = {
47-
log: log.withPrefix('find Python'),
48-
argsExecutable: ['-c', 'import sys; print(sys.executable);'],
49-
argsVersion: ['-c', 'import sys; print("%s.%s.%s" % sys.version_info[:3]);'],
50-
semverRange: '>=3.6.0',
43+
log = log.withPrefix('find Python')
44+
argsExecutable = ['-c', 'import sys; print(sys.executable);']
45+
argsVersion = ['-c', 'import sys; print("%s.%s.%s" % sys.version_info[:3]);']
46+
semverRange = '>=3.6.0'
5147

5248
// These can be overridden for testing:
53-
execFile,
54-
env: process.env,
55-
win,
56-
pyLauncher: 'py.exe',
57-
winDefaultLocations: winDefaultLocationsArray,
49+
execFile = execFile
50+
env = process.env
51+
win = win
52+
pyLauncher = 'py.exe'
53+
winDefaultLocations = winDefaultLocationsArray
54+
55+
constructor (configPython) {
56+
this.configPython = configPython
57+
this.errorLog = []
58+
}
5859

5960
// Logs a message at verbose level, but also saves it to be displayed later
6061
// at error level if an error occurs. This should help diagnose the problem.
61-
addLog: function addLog (message) {
62+
addLog (message) {
6263
this.log.verbose(message)
6364
this.errorLog.push(message)
64-
},
65+
}
6566

6667
// Find Python by trying a sequence of possibilities.
6768
// Ignore errors, keep trying until Python is found.
68-
findPython: async function findPython () {
69+
async findPython () {
6970
const SKIP = 0
7071
const FAIL = 1
7172
const toCheck = (() => {
@@ -161,12 +162,12 @@ PythonFinder.prototype = {
161162
}
162163

163164
return this.fail()
164-
},
165+
}
165166

166167
// Check if command is a valid Python to use.
167168
// Will exit the Python finder on success.
168169
// If on Windows, run in a CMD shell to support BAT/CMD launchers.
169-
checkCommand: async function checkCommand (command) {
170+
async checkCommand (command) {
170171
let exec = command
171172
let args = this.argsExecutable
172173
let shell = false
@@ -190,7 +191,7 @@ PythonFinder.prototype = {
190191
this.addLog(`- "${command}" is not in PATH or produced an error`)
191192
throw err
192193
}
193-
},
194+
}
194195

195196
// Check if the py launcher can find a valid Python to use.
196197
// Will exit the Python finder on success.
@@ -202,7 +203,7 @@ PythonFinder.prototype = {
202203
// the first command line argument. Since "py.exe -3" would be an invalid
203204
// executable for "execFile", we have to use the launcher to figure out
204205
// where the actual "python.exe" executable is located.
205-
checkPyLauncher: async function checkPyLauncher () {
206+
async checkPyLauncher () {
206207
this.log.verbose(`- executing "${this.pyLauncher}" to get Python 3 executable path`)
207208
// Possible outcomes: same as checkCommand
208209
try {
@@ -213,11 +214,11 @@ PythonFinder.prototype = {
213214
this.addLog(`- "${this.pyLauncher}" is not in PATH or produced an error`)
214215
throw err
215216
}
216-
},
217+
}
217218

218219
// Check if a Python executable is the correct version to use.
219220
// Will exit the Python finder on success.
220-
checkExecPath: async function checkExecPath (execPath) {
221+
async checkExecPath (execPath) {
221222
this.log.verbose(`- executing "${execPath}" to get version`)
222223
// Possible outcomes:
223224
// - Error: executable can not be run (likely meaning the command wasn't
@@ -249,11 +250,11 @@ PythonFinder.prototype = {
249250
this.addLog(`- "${execPath}" could not be run`)
250251
throw err
251252
}
252-
},
253+
}
253254

254255
// Run an executable or shell command, trimming the output.
255-
run: async function run (exec, args, shell) {
256-
const env = extend({}, this.env)
256+
async run (exec, args, shell) {
257+
const env = Object.assign({}, this.env)
257258
env.TERM = 'dumb'
258259
const opts = { env, shell }
259260

@@ -270,14 +271,14 @@ PythonFinder.prototype = {
270271
this.log.silly('execFile: threw:\n%s', err.stack)
271272
throw err
272273
}
273-
},
274+
}
274275

275-
succeed: function succeed (execPath, version) {
276+
succeed (execPath, version) {
276277
this.log.info(`using Python version ${version} found at "${execPath}"`)
277278
return execPath
278-
},
279+
}
279280

280-
fail: function fail () {
281+
fail () {
281282
const errorLog = this.errorLog.join('\n')
282283

283284
const pathExample = this.win
@@ -306,10 +307,4 @@ PythonFinder.prototype = {
306307
}
307308
}
308309

309-
const findPython = async (configPython) => new PythonFinder(configPython).findPython()
310-
311-
module.exports = findPython
312-
module.exports.test = {
313-
PythonFinder,
314-
findPython
315-
}
310+
module.exports = PythonFinder

lib/find-visualstudio.js

Lines changed: 41 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,28 @@ const { existsSync } = require('fs')
55
const { win32: path } = require('path')
66
const { regSearchKeys, execFile } = require('./util')
77

8-
function VisualStudioFinder (nodeSemver, configMsvsVersion) {
9-
this.nodeSemver = nodeSemver
10-
this.configMsvsVersion = configMsvsVersion
11-
this.errorLog = []
12-
this.validVersions = []
13-
}
8+
class VisualStudioFinder {
9+
static findVisualStudio = (...args) => new VisualStudioFinder(...args).findVisualStudio()
10+
11+
log = log.withPrefix('find VS')
1412

15-
VisualStudioFinder.prototype = {
16-
log: log.withPrefix('find VS'),
13+
regSearchKeys = regSearchKeys
1714

18-
regSearchKeys,
15+
constructor (nodeSemver, configMsvsVersion) {
16+
this.nodeSemver = nodeSemver
17+
this.configMsvsVersion = configMsvsVersion
18+
this.errorLog = []
19+
this.validVersions = []
20+
}
1921

2022
// Logs a message at verbose level, but also saves it to be displayed later
2123
// at error level if an error occurs. This should help diagnose the problem.
22-
addLog: function addLog (message) {
24+
addLog (message) {
2325
this.log.verbose(message)
2426
this.errorLog.push(message)
25-
},
27+
}
2628

27-
findVisualStudio: async function findVisualStudio () {
29+
async findVisualStudio () {
2830
this.configVersionYear = null
2931
this.configPath = null
3032
if (this.configMsvsVersion) {
@@ -65,16 +67,16 @@ VisualStudioFinder.prototype = {
6567
}
6668

6769
return this.fail()
68-
},
70+
}
6971

70-
succeed: function succeed (info) {
72+
succeed (info) {
7173
this.log.info(`using VS${info.versionYear} (${info.version}) found at:` +
7274
`\n"${info.path}"` +
7375
'\nrun with --verbose for detailed information')
7476
return info
75-
},
77+
}
7678

77-
fail: function fail () {
79+
fail () {
7880
if (this.configMsvsVersion && this.envVcInstallDir) {
7981
this.errorLog.push(
8082
'msvs_version does not match this VS Command Prompt or the',
@@ -109,11 +111,11 @@ VisualStudioFinder.prototype = {
109111

110112
this.log.error(`\n${errorLog}\n\n${infoLog}\n`)
111113
throw new Error('Could not find any Visual Studio installation to use')
112-
},
114+
}
113115

114116
// Invoke the PowerShell script to get information about Visual Studio 2017
115117
// or newer installations
116-
findVisualStudio2017OrNewer: async function findVisualStudio2017OrNewer () {
118+
async findVisualStudio2017OrNewer () {
117119
const ps = path.join(process.env.SystemRoot, 'System32',
118120
'WindowsPowerShell', 'v1.0', 'powershell.exe')
119121
const csFile = path.join(__dirname, 'Find-VisualStudio.cs')
@@ -128,11 +130,11 @@ VisualStudioFinder.prototype = {
128130
this.log.silly('Running', ps, psArgs)
129131
const [err, stdout, stderr] = await execFile(ps, psArgs, { encoding: 'utf8' })
130132
return this.parseData(err, stdout, stderr)
131-
},
133+
}
132134

133135
// Parse the output of the PowerShell script and look for an installation
134136
// of Visual Studio 2017 or newer to use
135-
parseData: function parseData (err, stdout, stderr) {
137+
parseData (err, stdout, stderr) {
136138
this.log.silly('PS stderr = %j', stderr)
137139

138140
const failPowershell = () => {
@@ -220,10 +222,10 @@ VisualStudioFinder.prototype = {
220222
this.addLog(
221223
'could not find a version of Visual Studio 2017 or newer to use')
222224
return null
223-
},
225+
}
224226

225227
// Helper - process version information
226-
getVersionInfo: function getVersionInfo (info) {
228+
getVersionInfo (info) {
227229
const match = /^(\d+)\.(\d+)\..*/.exec(info.version)
228230
if (!match) {
229231
this.log.silly('- failed to parse version:', info.version)
@@ -249,14 +251,14 @@ VisualStudioFinder.prototype = {
249251
}
250252
this.log.silly('- unsupported version:', ret.versionMajor)
251253
return {}
252-
},
254+
}
253255

254-
msBuildPathExists: function msBuildPathExists (path) {
256+
msBuildPathExists (path) {
255257
return existsSync(path)
256-
},
258+
}
257259

258260
// Helper - process MSBuild information
259-
getMSBuild: function getMSBuild (info, versionYear) {
261+
getMSBuild (info, versionYear) {
260262
const pkg = 'Microsoft.VisualStudio.VC.MSBuild.Base'
261263
const msbuildPath = path.join(info.path, 'MSBuild', 'Current', 'Bin', 'MSBuild.exe')
262264
const msbuildPathArm64 = path.join(info.path, 'MSBuild', 'Current', 'Bin', 'arm64', 'MSBuild.exe')
@@ -280,10 +282,10 @@ VisualStudioFinder.prototype = {
280282
return msbuildPath
281283
}
282284
return null
283-
},
285+
}
284286

285287
// Helper - process toolset information
286-
getToolset: function getToolset (info, versionYear) {
288+
getToolset (info, versionYear) {
287289
const pkg = 'Microsoft.VisualStudio.Component.VC.Tools.x86.x64'
288290
const express = 'Microsoft.VisualStudio.WDExpress'
289291

@@ -304,10 +306,10 @@ VisualStudioFinder.prototype = {
304306
}
305307
this.log.silly('- invalid versionYear:', versionYear)
306308
return null
307-
},
309+
}
308310

309311
// Helper - process Windows SDK information
310-
getSDK: function getSDK (info) {
312+
getSDK (info) {
311313
const win8SDK = 'Microsoft.VisualStudio.Component.Windows81SDK'
312314
const win10SDKPrefix = 'Microsoft.VisualStudio.Component.Windows10SDK.'
313315
const win11SDKPrefix = 'Microsoft.VisualStudio.Component.Windows11SDK.'
@@ -339,10 +341,10 @@ VisualStudioFinder.prototype = {
339341
return '8.1'
340342
}
341343
return null
342-
},
344+
}
343345

344346
// Find an installation of Visual Studio 2015 to use
345-
findVisualStudio2015: async function findVisualStudio2015 () {
347+
async findVisualStudio2015 () {
346348
if (this.nodeSemver.major >= 19) {
347349
this.addLog(
348350
'not looking for VS2015 as it is only supported up to Node.js 18')
@@ -355,10 +357,10 @@ VisualStudioFinder.prototype = {
355357
versionYear: 2015,
356358
toolset: 'v140'
357359
})
358-
},
360+
}
359361

360362
// Find an installation of Visual Studio 2013 to use
361-
findVisualStudio2013: async function findVisualStudio2013 () {
363+
async findVisualStudio2013 () {
362364
if (this.nodeSemver.major >= 9) {
363365
this.addLog(
364366
'not looking for VS2013 as it is only supported up to Node.js 8')
@@ -371,10 +373,10 @@ VisualStudioFinder.prototype = {
371373
versionYear: 2013,
372374
toolset: 'v120'
373375
})
374-
},
376+
}
375377

376378
// Helper - common code for VS2013 and VS2015
377-
findOldVS: async function findOldVS (info) {
379+
async findOldVS (info) {
378380
const regVC7 = ['HKLM\\Software\\Microsoft\\VisualStudio\\SxS\\VC7',
379381
'HKLM\\Software\\Wow6432Node\\Microsoft\\VisualStudio\\SxS\\VC7']
380382
const regMSBuild = 'HKLM\\Software\\Microsoft\\MSBuild\\ToolsVersions'
@@ -408,14 +410,14 @@ VisualStudioFinder.prototype = {
408410
this.addLog('- not found')
409411
return null
410412
}
411-
},
413+
}
412414

413415
// After finding a usable version of Visual Studio:
414416
// - add it to validVersions to be displayed at the end if a specific
415417
// version was requested and not found;
416418
// - check if this is the version that was requested.
417419
// - check if this matches the Visual Studio Command Prompt
418-
checkConfigVersion: function checkConfigVersion (versionYear, vsPath) {
420+
checkConfigVersion (versionYear, vsPath) {
419421
this.validVersions.push(versionYear)
420422
this.validVersions.push(vsPath)
421423

@@ -438,10 +440,4 @@ VisualStudioFinder.prototype = {
438440
}
439441
}
440442

441-
const findVisualStudio = async (nodeSemver, configMsvsVersion) => new VisualStudioFinder(nodeSemver, configMsvsVersion).findVisualStudio()
442-
443-
module.exports = findVisualStudio
444-
module.exports.test = {
445-
VisualStudioFinder,
446-
findVisualStudio
447-
}
443+
module.exports = VisualStudioFinder

0 commit comments

Comments
 (0)