windows-autoconf
Advanced tools
Comparing version 1.9.6 to 1.9.7
110
index.js
@@ -9,2 +9,3 @@ 'use strict' | ||
* @property {String} CmdPath | ||
* @property {Object} FullCmd | ||
* @property {Object} MSBuild | ||
@@ -43,5 +44,5 @@ * @property {Object} VCTools | ||
this._bindings.execSync = (cmd, options) => { | ||
this._bindings.log(`==== CMD ====\n${cmd}\n=============`) | ||
lazy.debug(`==== CMD ====\n${cmd}\n=============`) | ||
const ret = this._bindings._execSync(cmd, options) | ||
this._bindings.log(`${ret}\n=============`) | ||
lazy.debug(`${ret}\n=============`) | ||
return ret | ||
@@ -86,5 +87,6 @@ } | ||
function checkSetup (setups) { | ||
if (setups && setups[0] === 'No COM') return | ||
if (setups && setups[0] === 'No COM') return 'No COM' | ||
setups.sort((a, b) => a.Version.localeCompare(b.Version)).reverse() | ||
const setup = setups.find(s => s.MSBuild && s.VCTools && (s.SDK || s.SDK8)) | ||
if (setups.length && !setup) return 'No C++' | ||
return setup | ||
@@ -112,23 +114,36 @@ } | ||
function tryVS2017Registry () { | ||
let vsSetupsRaw | ||
try { | ||
const vsSetupsRaw = execAndParse(module.exports.try_registry_path) | ||
vsSetupsRaw = execAndParse(module.exports.try_registry_path) | ||
if (vsSetupsRaw[0] === 'ERROR') { | ||
lazy.bindings.log('Couldn\'t find VS2017 in registry:(') | ||
lazy.debug('Couldn\'t execute 2017 registry finder') | ||
return | ||
} | ||
vsSetupsRaw.sort((a, b) => a.localeCompare(b)).reverse() | ||
const vsSetup = vsSetupsRaw.find(i => Number(i.RegistryVersion) === 15.0) | ||
if (!vsSetup) return | ||
lazy.debugDir(vsSetup) | ||
if (!lazy.bindings.fs.existsSync(vsSetup.CmdPath)) return | ||
} catch (e) { | ||
lazy.debug('Couldn\'t execute 2017 registry finder: ' + e.message) | ||
} | ||
const reg = lazy.bindings.execSync(`"${vsSetup.CmdPath}" -no_logo & set`).toString().trim().split(/\r?\n/g) | ||
vsSetup.SDKFull = reg.find(l => l.includes('WindowsSDKVersion')).split('=').pop().replace('\\', '') | ||
vsSetup.Version = reg.find(l => l.includes('VCToolsInstallDir')).replace(/.*?\\([\d.]{5,})\\.*/, '$1') | ||
vsSetup.SDK = vsSetup.SDKFull.replace(/\d+$/, '0') | ||
vsSetup.Product = vsSetup.InstallationPath.split('\\').slice(-2, -1)[0] | ||
return vsSetup | ||
const vsSetup = vsSetupsRaw.find(i => Number(i.RegistryVersion) === 15.0) | ||
if (!vsSetup) { | ||
lazy.debug('Couldn\'t find ver 15.0 in registry') | ||
return | ||
} | ||
lazy.debugDir(vsSetup) | ||
if (!lazy.bindings.fs.existsSync(vsSetup.CmdPath)) { | ||
lazy.debug(`${vsSetup.CmdPath} doesn't exist`) | ||
return | ||
} | ||
let env | ||
try { | ||
env = resolveDevEnvironmentInner(`"${vsSetup.CmdPath}" -no_logo`) | ||
lazy.debugDir(env) | ||
} catch (e) { | ||
lazy.bindings.log('Couldn\'t find VS2017 via the registry') | ||
lazy.debug('Couldn\'t execute 2017 VsDevCmd.bat: ' + e.message) | ||
} | ||
vsSetup.SDKFull = env['WindowsSDKVersion'].split('=').pop().replace('\\', '') | ||
vsSetup.Version = Boolean(env['VCToolsInstallDir']) && env['VCToolsInstallDir'].replace(/.*?\\([\d.]{5,})\\.*/, '$1') | ||
vsSetup.SDK = vsSetup.SDKFull.replace(/\d+$/, '0') | ||
vsSetup.Product = vsSetup.InstallationPath.split('\\').slice(-2, -1)[0] | ||
return vsSetup | ||
} | ||
@@ -139,4 +154,14 @@ | ||
const sdkSetups = execAndParse(module.exports.try_registry_sdk_path) | ||
const vers = sdkSetups.map(s => s['ProductVersion']).sort().reverse() | ||
const sdkSetup = sdkSetups.find(s => s['ProductVersion'] === vers[0]) | ||
lazy.debug(JSON.stringify(sdkSetups, null, ' ')) | ||
const vers = sdkSetups | ||
.filter(s => s['InstallationFolder']) | ||
.map(s => { | ||
const parts = s['ProductVersion'].split('.') | ||
const ver = Number(parts.shift() + '.' + parts.join('')) | ||
return {ver, ProductVersion: s['ProductVersion']} | ||
}) | ||
.sort((a, b) => a[0] - b[0]) | ||
.reverse() | ||
lazy.debug(JSON.stringify(vers, null, ' ')) | ||
const sdkSetup = sdkSetups.find(s => s['ProductVersion'] === vers[0].ProductVersion) | ||
return sdkSetup | ||
@@ -179,3 +204,3 @@ } catch (e) { | ||
const vsSetup = getVS2017Setup() | ||
if (!vsSetup) return | ||
if (!vsSetup || typeof vsSetup === 'string') return | ||
const ver = '15.0' | ||
@@ -222,19 +247,20 @@ const MSBuildToolsPath = lazy.bindings.path.join(vsSetup.InstallationPath, 'MSBuild', ver, 'Bin') | ||
function getWithFullCmd (targetArch) { | ||
function getWithFullCmd (argTargetArch) { | ||
let setup = getMSVSSetup() | ||
setup.target_arch = targetArch | ||
if (setup.version === 'auto') throw new Error('No Visual Studio found. Try to run from an MSVS console') | ||
if (argTargetArch === 'x86') argTargetArch = 'ia32' | ||
setup.arg_target_arch = argTargetArch | ||
setup.hostBits = getOSBits() | ||
setup.hostArch = setup.hostBits === 64 ? 'amd64' : 'x86' | ||
setup.targetArch = argTargetArch === 'x64' ? 'amd64' : argTargetArch === 'ia32' ? 'x86' : argTargetArch | ||
if (setup.version === 'auto') throw new Error('No Visual Studio found. Try to run from an MSVS console') | ||
// NOTE: Largely inspired by `GYP`::MSVSVersion.py | ||
if (setup.version === '2017') { | ||
const argArch = targetArch === 'x64' ? 'amd64' : targetArch === 'ia32' ? 'x86' : new Error(`Arch: '${targetArch}' is not supported`) | ||
if (argArch instanceof Error) throw argArch | ||
const argHost = setup.hostBits === 64 ? 'amd64' : 'x86' | ||
setup.FullCmd = `${setup.CmdPath} -arch=${argArch} -host_arch=${argHost} -no_logo` | ||
setup.FullCmd = `"${setup.CmdPath}" -arch=${setup.targetArch} -host_arch=${setup.hostArch} -no_logo` | ||
} else { | ||
// NOTE: Largely inspired by `GYP`::MSVSVersion.py | ||
let cmdPathParts | ||
let arg | ||
setup.effectiveBits = setup.InstallationPath.includes('(x86)') ? 32 : setup.hostBits | ||
if (targetArch === 'ia32') { | ||
if (argTargetArch === 'ia32') { | ||
if (setup.effectiveBits === 64) { | ||
@@ -247,7 +273,7 @@ cmdPathParts = ['VC', 'vcvarsall.bat'] | ||
} | ||
} else if (targetArch === 'x64') { | ||
} else if (argTargetArch === 'x64') { | ||
cmdPathParts = ['VC', 'vcvarsall.bat'] | ||
arg = setup.effectiveBits === 64 ? 'amd64' : 'x86_amd64' | ||
} else { | ||
throw new Error(`Arch: '${targetArch}' is not supported`) | ||
throw new Error(`Arch: '${argTargetArch}' is not supported`) | ||
} | ||
@@ -266,16 +292,12 @@ setup.CmdPath = lazy.bindings.path.join(setup.InstallationPath, ...cmdPathParts) | ||
function resolveDevEnvironmentInner (setup) { | ||
const vcEnvCmd = setup.FullCmd | ||
const pre = lazy.bindings.execSync('set').toString().trim().split(/\r\n/g) | ||
const preSet = new Set(pre) | ||
const rawLines = lazy.bindings.execSync(`${vcEnvCmd} & set`, {env: {}}).toString().trim().split(/\r\n/g) | ||
const hasFail = rawLines.slice(0, 2).some(l => l.includes('missing') || l.includes('not be installed')) | ||
function resolveDevEnvironmentInner (fullCmd) { | ||
const lines = lazy.bindings.execSync(`${fullCmd} & set`, {env: {}}).toString().trim().split(/\r\n/g) | ||
const hasFail = lines.slice(0, 2).some(l => l.includes('missing') || l.includes('not be installed')) | ||
if (hasFail) { | ||
// noinspection ExceptionCaughtLocallyJS | ||
throw new Error('Visual studio tools for C++ where not installed for ' + setup.target_arch) | ||
const lastArg = fullCmd.split('-').pop() | ||
throw new Error(`Visual studio tools for C++ could not be setup for ${lastArg}\nby ${fullCmd}`) | ||
} | ||
const lines = rawLines.filter(l => !preSet.has(l)) | ||
const env = lines.reduce((s, l) => { | ||
const kv = l.split('=') | ||
s[kv[0]] = kv[1] | ||
if (kv.length === 2) s[kv[0]] = kv[1] | ||
return s | ||
@@ -299,3 +321,3 @@ }, {}) | ||
function resolveDevEnvironment (targetArch) { | ||
function resolveDevEnvironment (targetArch, noCache) { | ||
const setup = getWithFullCmd(targetArch) | ||
@@ -308,3 +330,3 @@ lazy.debugDir(setup) | ||
const cacheName = lazy.bindings.path.join(cacheDir, `_${cacheKey}${setup.Version}.json`) | ||
if (cachable && lazy.bindings.fs.existsSync(cacheName)) { | ||
if (!noCache && cachable && lazy.bindings.fs.existsSync(cacheName)) { | ||
const file = lazy.bindings.fs.readFileSync(cacheName) | ||
@@ -316,3 +338,3 @@ const ret = JSON.parse(file) | ||
} else { | ||
const env = resolveDevEnvironmentInner(setup) | ||
const env = resolveDevEnvironmentInner(setup.FullCmd, targetArch) | ||
cachable && lazy.bindings.fs.writeFileSync(cacheName, JSON.stringify(env)) | ||
@@ -319,0 +341,0 @@ lazy.debug('actual resolution') |
{ | ||
"name": "windows-autoconf", | ||
"version": "1.9.6", | ||
"version": "1.9.7", | ||
"description": "Try to find MS build tools", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -33,3 +33,3 @@ /* eslint-disable no-path-concat */ | ||
describe('Try cmd tools', () => { | ||
describe('Try COM', () => { | ||
describe('Try COM', function () { | ||
before(checkCom) | ||
@@ -49,6 +49,13 @@ | ||
it('Powershell -Version 2', () => { | ||
it('Powershell -Version 2', function () { | ||
const csfile = getter.try_powershell_path.replace(/\\[^\\]+$/, '\\GetVS2017Configuration.cs').replace('"', '') | ||
const cmd = `"powershell.exe" -Version 2 -NoProfile -ExecutionPolicy Unrestricted -Command "& { Add-Type -Path '${csfile}'; [VisualStudioConfiguration.Main]::Query()}"` | ||
const ret = getter._forTesting.execAndParse(cmd) | ||
let ret | ||
try { | ||
ret = getter._forTesting.execAndParse(cmd) | ||
} catch (e) { | ||
if (e.output[2].toString('utf16le').includes('not installed')) { | ||
this.skip() | ||
} | ||
} | ||
const setup = ret[0] | ||
@@ -117,5 +124,5 @@ if (setup === 'No COM') return | ||
it('Powershell', () => { | ||
it('Powershell', function () { | ||
const setup = getter._forTesting.tryVS2017Powershell() | ||
if (setup === 'No COM') return | ||
if (setup === 'No C++') return this.skip() | ||
@@ -130,4 +137,6 @@ assert(setup.Product) | ||
it('Compile and run', () => { | ||
it('Compile and run', function () { | ||
const setup = getter._forTesting.tryVS2017CSC() | ||
if (setup === 'No C++') return this.skip() | ||
assert(setup.Product) | ||
@@ -142,44 +151,47 @@ assert(setup.InstallationPath) | ||
it('Registry', function () { | ||
this.timeout(10000) | ||
const setup = getter._forTesting.tryVS2017Registry() | ||
if (!setup) { | ||
console.log('registry method failed') | ||
return this.skip() | ||
} | ||
assert(setup.RegistryVersion) | ||
assert(setup.InstallationPath) | ||
assert(setup.CmdPath) | ||
assert(setup.Product) | ||
assert(setup.Version) | ||
assert(setup.SDKFull) | ||
assert(setup.SDK) | ||
}) | ||
describe('Registry scripts', function () { | ||
before(function () { | ||
this.regSetup = getter._forTesting.tryVS2017Registry() | ||
if (!this.regSetup) return this.skip() | ||
}) | ||
it('Registry SDK', function () { | ||
this.timeout(10000) | ||
const setup = getter._forTesting.tryRegistrySDK() | ||
if (!setup) { | ||
console.log('registry method failed') | ||
return | ||
} | ||
assert(setup['InstallationFolder']) | ||
assert(setup['ProductVersion']) | ||
}) | ||
it('Find VS', function () { | ||
assert(this.regSetup.RegistryVersion) | ||
assert(this.regSetup.InstallationPath) | ||
assert(this.regSetup.CmdPath) | ||
assert(this.regSetup.Product) | ||
assert(this.regSetup.SDKFull) | ||
assert(this.regSetup.SDK) | ||
}) | ||
it('Registry MSBuild', function () { | ||
this.timeout(10000) | ||
const msbSetup = getter._forTesting.tryRegistryMSBuild() | ||
if (!msbSetup) { | ||
console.log('registry method failed') | ||
return this.skip() | ||
} | ||
assert(msbSetup.ver) | ||
assert(msbSetup.MSBuildToolsPath) | ||
assert(fs.existsSync(msbSetup.MSBuildToolsPath)) | ||
assert(msbSetup.MSBuildPath) | ||
const parts = msbSetup.MSBuildPath.split('\\') | ||
assert(parts.length >= 4) | ||
assert(parts.pop() === 'MSBuild.exe') | ||
assert(fs.existsSync(msbSetup.MSBuildPath)) | ||
it('Find VC 14.10', function () { | ||
if (typeof this.regSetup.Version !== 'string') return this.skip() | ||
assert(this.regSetup.Version.includes('14.10'), 'should have a 14.10 VC version') | ||
}) | ||
it('Find SDK', function () { | ||
const setup = getter._forTesting.tryRegistrySDK() | ||
if (!setup) { | ||
console.log('registry method failed') | ||
return | ||
} | ||
assert(setup['InstallationFolder']) | ||
assert(setup['ProductVersion']) | ||
}) | ||
it('Find MSBuild', function () { | ||
const msbSetup = getter._forTesting.tryRegistryMSBuild() | ||
if (!msbSetup) { | ||
console.log('registry method failed') | ||
return this.skip() | ||
} | ||
assert(msbSetup.ver) | ||
assert(msbSetup.MSBuildToolsPath) | ||
assert(fs.existsSync(msbSetup.MSBuildToolsPath)) | ||
assert(msbSetup.MSBuildPath) | ||
const parts = msbSetup.MSBuildPath.split('\\') | ||
assert(parts.length >= 4) | ||
assert(parts.pop() === 'MSBuild.exe') | ||
assert(fs.existsSync(msbSetup.MSBuildPath)) | ||
}) | ||
}) | ||
@@ -204,7 +216,9 @@ | ||
describe('Try node wrapper', function () { | ||
this.timeout(10000) | ||
it('getMSVSVersion', () => { | ||
const version = getter.getMSVSVersion() | ||
assert.equal(version, process.env['GYP_MSVS_VERSION'] || '2017') | ||
if ('GYP_MSVS_VERSION' in process.env) { | ||
assert.equal(version, process.env['GYP_MSVS_VERSION']) | ||
} else { | ||
assert(['2010', '2012', '2013', '2015', '2015', '2017'].includes(version)) | ||
} | ||
}) | ||
@@ -341,43 +355,29 @@ | ||
describe('genEnvironment', function () { | ||
this.timeout(20000) | ||
it('resolve for x64', () => { | ||
let env | ||
try { | ||
env = getter.resolveDevEnvironment('x64') | ||
} catch (e) { | ||
if (!e.message.includes('not installed for')) throw e | ||
console.log(e.message) | ||
return | ||
function testEnvGen (arch, noCache) { | ||
return function () { | ||
let env | ||
try { | ||
env = getter.resolveDevEnvironment(arch, noCache) | ||
} catch (e) { | ||
if (!e.message.includes('could not be setup for')) throw e | ||
console.log(e.message) | ||
return | ||
} | ||
assert(env, 'didn\'t get ENVIRONMENT :(') | ||
const VCINSTALLDIR = Object.keys(env).find(k => k.includes('VCINSTALLDIR')) | ||
assert(VCINSTALLDIR, 'didn\'t get VCINSTALLDIR :( env:\n' + JSON.stringify(env, null, ' ')) | ||
if (env['VisualStudioVersion'] === '15.0') { | ||
assert.equal(env['VSCMD_ARG_TGT_ARCH'], arch) | ||
assert(env['__VSCMD_PREINIT_PATH'], 'Last env var should be __VSCMD_PREINIT_PATH') | ||
} | ||
} | ||
assert(env, 'didn\'t get ENVIRONMENT :(') | ||
const COMNTOOLS = Object.keys(env).find(k => k.includes('VCINSTALLDIR')) | ||
assert(COMNTOOLS, 'didn\'t get VCINSTALLDIR :(') | ||
if (env['VisualStudioVersion'] === '15.0') { | ||
assert.equal(env['VSCMD_ARG_TGT_ARCH'], 'x64') | ||
assert(env['__VSCMD_PREINIT_PATH'], 'Last env var should be __VSCMD_PREINIT_PATH') | ||
} | ||
}) | ||
} | ||
it('resolve for x86', () => { | ||
let env | ||
try { | ||
env = getter.resolveDevEnvironment('ia32') | ||
} catch (e) { | ||
if (!e.message.includes('not installed for')) throw e | ||
console.log(e.message) | ||
return | ||
} | ||
assert(env, 'didn\'t get ENVIRONMENT :(') | ||
if (env instanceof String) { | ||
console.log(env) | ||
return | ||
} | ||
const COMNTOOLS = Object.keys(env).find(k => k.includes('VCINSTALLDIR')) | ||
assert(COMNTOOLS, 'didn\'t get VCINSTALLDIR :(') | ||
if (env['VisualStudioVersion'] === '15.0') { | ||
assert.equal(env['VSCMD_ARG_TGT_ARCH'], 'x86') | ||
assert(env['__VSCMD_PREINIT_PATH'], 'Last env var should be __VSCMD_PREINIT_PATH') | ||
} | ||
}) | ||
it('resolve for x64 - no cache', testEnvGen('x64', true)) | ||
it('resolve for x64', testEnvGen('x64')) | ||
it('resolve for x86 - no cache', testEnvGen('x86', true)) | ||
it('resolve for x86', testEnvGen('x86')) | ||
}) |
Sorry, the diff of this file is not supported yet
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
44570
20
674
5