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`.
This commit is contained in:
Luke Karrys 2023-10-27 16:40:36 -07:00
parent 355622f4aa
commit d52997e975
7 changed files with 307 additions and 344 deletions

View file

@ -2,10 +2,15 @@
const log = require('./log')
const semver = require('semver')
const { _extend: extend } = require('util') // eslint-disable-line n/no-deprecated-api
const { execFile } = require('./util')
const win = process.platform === 'win32'
function getOsUserInfo () {
try {
return require('os').userInfo().username
} catch {}
}
const systemDrive = process.env.SystemDrive || 'C:'
const username = process.env.USERNAME || process.env.USER || getOsUserInfo()
const localAppData = process.env.LOCALAPPDATA || `${systemDrive}\\${username}\\AppData\\Local`
@ -32,40 +37,36 @@ for (const majorMinor of ['311', '310', '39', '38']) {
}
}
function getOsUserInfo () {
try {
return require('os').userInfo().username
} catch (e) {}
}
class PythonFinder {
static findPython = (...args) => new PythonFinder(...args).findPython()
function PythonFinder (configPython) {
this.configPython = configPython
this.errorLog = []
}
PythonFinder.prototype = {
log: log.withPrefix('find Python'),
argsExecutable: ['-c', 'import sys; print(sys.executable);'],
argsVersion: ['-c', 'import sys; print("%s.%s.%s" % sys.version_info[:3]);'],
semverRange: '>=3.6.0',
log = log.withPrefix('find Python')
argsExecutable = ['-c', 'import sys; print(sys.executable);']
argsVersion = ['-c', 'import sys; print("%s.%s.%s" % sys.version_info[:3]);']
semverRange = '>=3.6.0'
// These can be overridden for testing:
execFile,
env: process.env,
win,
pyLauncher: 'py.exe',
winDefaultLocations: winDefaultLocationsArray,
execFile = execFile
env = process.env
win = win
pyLauncher = 'py.exe'
winDefaultLocations = winDefaultLocationsArray
constructor (configPython) {
this.configPython = configPython
this.errorLog = []
}
// Logs a message at verbose level, but also saves it to be displayed later
// at error level if an error occurs. This should help diagnose the problem.
addLog: function addLog (message) {
addLog (message) {
this.log.verbose(message)
this.errorLog.push(message)
},
}
// Find Python by trying a sequence of possibilities.
// Ignore errors, keep trying until Python is found.
findPython: async function findPython () {
async findPython () {
const SKIP = 0
const FAIL = 1
const toCheck = (() => {
@ -161,12 +162,12 @@ PythonFinder.prototype = {
}
return this.fail()
},
}
// Check if command is a valid Python to use.
// Will exit the Python finder on success.
// If on Windows, run in a CMD shell to support BAT/CMD launchers.
checkCommand: async function checkCommand (command) {
async checkCommand (command) {
let exec = command
let args = this.argsExecutable
let shell = false
@ -190,7 +191,7 @@ PythonFinder.prototype = {
this.addLog(`- "${command}" is not in PATH or produced an error`)
throw err
}
},
}
// Check if the py launcher can find a valid Python to use.
// Will exit the Python finder on success.
@ -202,7 +203,7 @@ PythonFinder.prototype = {
// the first command line argument. Since "py.exe -3" would be an invalid
// executable for "execFile", we have to use the launcher to figure out
// where the actual "python.exe" executable is located.
checkPyLauncher: async function checkPyLauncher () {
async checkPyLauncher () {
this.log.verbose(`- executing "${this.pyLauncher}" to get Python 3 executable path`)
// Possible outcomes: same as checkCommand
try {
@ -213,11 +214,11 @@ PythonFinder.prototype = {
this.addLog(`- "${this.pyLauncher}" is not in PATH or produced an error`)
throw err
}
},
}
// Check if a Python executable is the correct version to use.
// Will exit the Python finder on success.
checkExecPath: async function checkExecPath (execPath) {
async checkExecPath (execPath) {
this.log.verbose(`- executing "${execPath}" to get version`)
// Possible outcomes:
// - Error: executable can not be run (likely meaning the command wasn't
@ -249,11 +250,11 @@ PythonFinder.prototype = {
this.addLog(`- "${execPath}" could not be run`)
throw err
}
},
}
// Run an executable or shell command, trimming the output.
run: async function run (exec, args, shell) {
const env = extend({}, this.env)
async run (exec, args, shell) {
const env = Object.assign({}, this.env)
env.TERM = 'dumb'
const opts = { env, shell }
@ -270,14 +271,14 @@ PythonFinder.prototype = {
this.log.silly('execFile: threw:\n%s', err.stack)
throw err
}
},
}
succeed: function succeed (execPath, version) {
succeed (execPath, version) {
this.log.info(`using Python version ${version} found at "${execPath}"`)
return execPath
},
}
fail: function fail () {
fail () {
const errorLog = this.errorLog.join('\n')
const pathExample = this.win
@ -306,10 +307,4 @@ PythonFinder.prototype = {
}
}
const findPython = async (configPython) => new PythonFinder(configPython).findPython()
module.exports = findPython
module.exports.test = {
PythonFinder,
findPython
}
module.exports = PythonFinder