From 8780f4b0e37e57b3b86d7e9804b87d9702f37eea Mon Sep 17 00:00:00 2001 From: StefanStojanovic Date: Mon, 15 Jan 2024 15:01:14 +0100 Subject: [PATCH] win: update supported vs versions Drop VS2017 support for Node.js v22 and above. Refs: https://github.com/nodejs/build/pull/3603 Refs: https://github.com/nodejs/node/pull/45427 --- lib/find-visualstudio.js | 30 ++++++-- test/test-find-visualstudio.js | 125 ++++++++++++++++++++++++--------- 2 files changed, 114 insertions(+), 41 deletions(-) diff --git a/lib/find-visualstudio.js b/lib/find-visualstudio.js index b57770259a..fa1554785d 100644 --- a/lib/find-visualstudio.js +++ b/lib/find-visualstudio.js @@ -54,7 +54,8 @@ class VisualStudioFinder { } const checks = [ - () => this.findVisualStudio2017OrNewer(), + () => this.findVisualStudio2019OrNewer(), + () => this.findVisualStudio2017(), () => this.findVisualStudio2015(), () => this.findVisualStudio2013() ] @@ -113,9 +114,25 @@ class VisualStudioFinder { throw new Error('Could not find any Visual Studio installation to use') } + // Invoke the PowerShell script to get information about Visual Studio 2019 + // or newer installations + async findVisualStudio2019OrNewer () { + return this.findNewVS([2019, 2022]) + } + + // Invoke the PowerShell script to get information about Visual Studio 2017 + async findVisualStudio2017 () { + if (this.nodeSemver.major >= 22) { + this.addLog( + 'not looking for VS2017 as it is only supported up to Node.js 21') + return null + } + return this.findNewVS([2017]) + } + // Invoke the PowerShell script to get information about Visual Studio 2017 // or newer installations - async findVisualStudio2017OrNewer () { + async findNewVS (supportedYears) { const ps = path.join(process.env.SystemRoot, 'System32', 'WindowsPowerShell', 'v1.0', 'powershell.exe') const csFile = path.join(__dirname, 'Find-VisualStudio.cs') @@ -129,12 +146,12 @@ class VisualStudioFinder { this.log.silly('Running', ps, psArgs) const [err, stdout, stderr] = await execFile(ps, psArgs, { encoding: 'utf8' }) - return this.parseData(err, stdout, stderr) + return this.parseData(err, stdout, stderr, supportedYears) } // Parse the output of the PowerShell script and look for an installation // of Visual Studio 2017 or newer to use - parseData (err, stdout, stderr) { + parseData (err, stdout, stderr, supportedYears) { this.log.silly('PS stderr = %j', stderr) const failPowershell = () => { @@ -175,11 +192,12 @@ class VisualStudioFinder { this.log.silly('vsInfo:', vsInfo) // Remove future versions or errors parsing version number + // Also remove any unsupported versions vsInfo = vsInfo.filter((info) => { - if (info.versionYear) { + if (info.versionYear && supportedYears.indexOf(info.versionYear) !== -1) { return true } - this.addLog(`unknown version "${info.version}" found at "${info.path}"`) + this.addLog(`${info.versionYear ? 'unsupported' : 'unknown'} version "${info.version}" found at "${info.path}"`) return false }) diff --git a/test/test-find-visualstudio.js b/test/test-find-visualstudio.js index 08e9438c45..cbc51babb5 100644 --- a/test/test-find-visualstudio.js +++ b/test/test-find-visualstudio.js @@ -25,8 +25,11 @@ describe('find-visualstudio', function () { it('VS2013', async function () { const finder = new TestVisualStudioFinder(semverV1, null) - finder.findVisualStudio2017OrNewer = async () => { - return finder.parseData(new Error(), '', '') + finder.findVisualStudio2017 = async () => { + return finder.parseData(new Error(), '', '', [2017]) + } + finder.findVisualStudio2019OrNewer = async () => { + return finder.parseData(new Error(), '', '', [2019, 2022]) } finder.regSearchKeys = async (keys, value, addOpts) => { for (let i = 0; i < keys.length; ++i) { @@ -69,10 +72,15 @@ describe('find-visualstudio', function () { patch: 0 }, null) - finder.findVisualStudio2017OrNewer = async () => { + finder.findVisualStudio2017 = async () => { const file = path.join(__dirname, 'fixtures', 'VS_2017_Unusable.txt') const data = fs.readFileSync(file) - return finder.parseData(null, data, '') + return finder.parseData(null, data, '', [2017]) + } + finder.findVisualStudio2019OrNewer = async () => { + const file = path.join(__dirname, 'fixtures', 'VS_2017_Unusable.txt') + const data = fs.readFileSync(file) + return finder.parseData(null, data, '', [2019, 2022]) } finder.regSearchKeys = async (keys, value, addOpts) => { for (let i = 0; i < keys.length; ++i) { @@ -96,8 +104,11 @@ describe('find-visualstudio', function () { it('VS2015', async function () { const finder = new TestVisualStudioFinder(semverV1, null) - finder.findVisualStudio2017OrNewer = async () => { - return finder.parseData(new Error(), '', '') + finder.findVisualStudio2017 = async () => { + return finder.parseData(new Error(), '', '', [2017]) + } + finder.findVisualStudio2019OrNewer = async () => { + return finder.parseData(new Error(), '', '', [2019, 2022]) } finder.regSearchKeys = async (keys, value, addOpts) => { for (let i = 0; i < keys.length; ++i) { @@ -132,7 +143,7 @@ describe('find-visualstudio', function () { it('error from PowerShell', async function () { const finder = new TestVisualStudioFinder(semverV1, null, null) - finder.parseData(new Error(), '', '', (info) => { + finder.parseData(new Error(), '', '', [], (info) => { assert.ok(/use PowerShell/i.test(finder.errorLog[0]), 'expect error') assert.ok(!info, 'no data') }) @@ -141,7 +152,7 @@ describe('find-visualstudio', function () { it('empty output from PowerShell', async function () { const finder = new TestVisualStudioFinder(semverV1, null, null) - finder.parseData(null, '', '', (info) => { + finder.parseData(null, '', '', [], (info) => { assert.ok(/use PowerShell/i.test(finder.errorLog[0]), 'expect error') assert.ok(!info, 'no data') }) @@ -150,7 +161,7 @@ describe('find-visualstudio', function () { it('output from PowerShell not JSON', async function () { const finder = new TestVisualStudioFinder(semverV1, null, null) - finder.parseData(null, 'AAAABBBB', '', (info) => { + finder.parseData(null, 'AAAABBBB', '', [], (info) => { assert.ok(/use PowerShell/i.test(finder.errorLog[0]), 'expect error') assert.ok(!info, 'no data') }) @@ -159,7 +170,7 @@ describe('find-visualstudio', function () { it('wrong JSON from PowerShell', async function () { const finder = new TestVisualStudioFinder(semverV1, null, null) - finder.parseData(null, '{}', '', (info) => { + finder.parseData(null, '{}', '', [], (info) => { assert.ok(/use PowerShell/i.test(finder.errorLog[0]), 'expect error') assert.ok(!info, 'no data') }) @@ -168,7 +179,7 @@ describe('find-visualstudio', function () { it('empty JSON from PowerShell', async function () { const finder = new TestVisualStudioFinder(semverV1, null, null) - finder.parseData(null, '[]', '', (info) => { + finder.parseData(null, '[]', '', [], (info) => { assert.ok(/find .* Visual Studio/i.test(finder.errorLog[0]), 'expect error') assert.ok(!info, 'no data') }) @@ -185,7 +196,7 @@ describe('find-visualstudio', function () { ], path: 'C:\\VS', version: '9999.9999.9999.9999' - }]), '', (info) => { + }]), '', [2017, 2019, 2022], (info) => { assert.ok(/unknown version/i.test(finder.errorLog[0]), 'expect error') assert.ok(/find .* Visual Studio/i.test(finder.errorLog[1]), 'expect error') assert.ok(!info, 'no data') @@ -197,7 +208,7 @@ describe('find-visualstudio', function () { const file = path.join(__dirname, 'fixtures', 'VS_2017_Unusable.txt') const data = fs.readFileSync(file) - finder.parseData(null, data, '', (info) => { + finder.parseData(null, data, '', [2017, 2019, 2022], (info) => { assert.ok(/checking/i.test(finder.errorLog[0]), 'expect error') assert.ok(/find .* Visual Studio/i.test(finder.errorLog[2]), 'expect error') assert.ok(!info, 'no data') @@ -208,11 +219,17 @@ describe('find-visualstudio', function () { const finder = new TestVisualStudioFinder(semverV1, null) poison(finder, 'regSearchKeys') - finder.findVisualStudio2017OrNewer = async () => { + finder.findVisualStudio2017 = async () => { const file = path.join(__dirname, 'fixtures', 'VS_2017_BuildTools_minimal.txt') const data = fs.readFileSync(file) - return finder.parseData(null, data, '') + return finder.parseData(null, data, '', [2017]) + } + finder.findVisualStudio2019OrNewer = async () => { + const file = path.join(__dirname, 'fixtures', + 'VS_2017_BuildTools_minimal.txt') + const data = fs.readFileSync(file) + return finder.parseData(null, data, '', [2019, 2022]) } const { err, info } = await finder.findVisualStudio() assert.strictEqual(err, null) @@ -234,11 +251,17 @@ describe('find-visualstudio', function () { const finder = new TestVisualStudioFinder(semverV1, null) poison(finder, 'regSearchKeys') - finder.findVisualStudio2017OrNewer = async () => { + finder.findVisualStudio2017 = async () => { const file = path.join(__dirname, 'fixtures', 'VS_2017_Community_workload.txt') const data = fs.readFileSync(file) - return finder.parseData(null, data, '') + return finder.parseData(null, data, '', [2017]) + } + finder.findVisualStudio2019OrNewer = async () => { + const file = path.join(__dirname, 'fixtures', + 'VS_2017_Community_workload.txt') + const data = fs.readFileSync(file) + return finder.parseData(null, data, '', [2019, 2022]) } const { err, info } = await finder.findVisualStudio() assert.strictEqual(err, null) @@ -260,10 +283,15 @@ describe('find-visualstudio', function () { const finder = new TestVisualStudioFinder(semverV1, null) poison(finder, 'regSearchKeys') - finder.findVisualStudio2017OrNewer = async () => { + finder.findVisualStudio2017 = async () => { const file = path.join(__dirname, 'fixtures', 'VS_2017_Express.txt') const data = fs.readFileSync(file) - return finder.parseData(null, data, '') + return finder.parseData(null, data, '', [2017]) + } + finder.findVisualStudio2019OrNewer = async () => { + const file = path.join(__dirname, 'fixtures', 'VS_2017_Express.txt') + const data = fs.readFileSync(file) + return finder.parseData(null, data, '', [2019, 2022]) } const { err, info } = await finder.findVisualStudio() assert.strictEqual(err, null) @@ -285,11 +313,17 @@ describe('find-visualstudio', function () { const finder = new TestVisualStudioFinder(semverV1, null) poison(finder, 'regSearchKeys') - finder.findVisualStudio2017OrNewer = async () => { + finder.findVisualStudio2017 = async () => { const file = path.join(__dirname, 'fixtures', 'VS_2019_Preview.txt') const data = fs.readFileSync(file) - return finder.parseData(null, data, '') + return finder.parseData(null, data, '', [2017]) + } + finder.findVisualStudio2019OrNewer = async () => { + const file = path.join(__dirname, 'fixtures', + 'VS_2019_Preview.txt') + const data = fs.readFileSync(file) + return finder.parseData(null, data, '', [2019, 2022]) } const { err, info } = await finder.findVisualStudio() assert.strictEqual(err, null) @@ -311,11 +345,17 @@ describe('find-visualstudio', function () { const finder = new TestVisualStudioFinder(semverV1, null) poison(finder, 'regSearchKeys') - finder.findVisualStudio2017OrNewer = async () => { + finder.findVisualStudio2017 = async () => { + const file = path.join(__dirname, 'fixtures', + 'VS_2019_BuildTools_minimal.txt') + const data = fs.readFileSync(file) + return finder.parseData(null, data, '', [2017]) + } + finder.findVisualStudio2019OrNewer = async () => { const file = path.join(__dirname, 'fixtures', 'VS_2019_BuildTools_minimal.txt') const data = fs.readFileSync(file) - return finder.parseData(null, data, '') + return finder.parseData(null, data, '', [2019, 2022]) } const { err, info } = await finder.findVisualStudio() assert.strictEqual(err, null) @@ -337,11 +377,17 @@ describe('find-visualstudio', function () { const finder = new TestVisualStudioFinder(semverV1, null) poison(finder, 'regSearchKeys') - finder.findVisualStudio2017OrNewer = async () => { + finder.findVisualStudio2017 = async () => { + const file = path.join(__dirname, 'fixtures', + 'VS_2019_Community_workload.txt') + const data = fs.readFileSync(file) + return finder.parseData(null, data, '', [2017]) + } + finder.findVisualStudio2019OrNewer = async () => { const file = path.join(__dirname, 'fixtures', 'VS_2019_Community_workload.txt') const data = fs.readFileSync(file) - return finder.parseData(null, data, '') + return finder.parseData(null, data, '', [2019, 2022]) } const { err, info } = await finder.findVisualStudio() assert.strictEqual(err, null) @@ -372,11 +418,17 @@ describe('find-visualstudio', function () { finder.msBuildPathExists = (path) => { return true } - finder.findVisualStudio2017OrNewer = async () => { + finder.findVisualStudio2017 = async () => { const file = path.join(__dirname, 'fixtures', 'VS_2022_Community_workload.txt') const data = fs.readFileSync(file) - return finder.parseData(null, data, '') + return finder.parseData(null, data, '', [2017]) + } + finder.findVisualStudio2019OrNewer = async () => { + const file = path.join(__dirname, 'fixtures', + 'VS_2022_Community_workload.txt') + const data = fs.readFileSync(file) + return finder.parseData(null, data, '', [2019, 2022]) } const { err, info } = await finder.findVisualStudio() assert.strictEqual(err, null) @@ -394,7 +446,7 @@ describe('find-visualstudio', function () { }) function allVsVersions (finder) { - finder.findVisualStudio2017OrNewer = async () => { + finder.findVisualStudio2017 = async () => { const data0 = JSON.parse(fs.readFileSync(path.join(__dirname, 'fixtures', 'VS_2017_Unusable.txt'))) const data1 = JSON.parse(fs.readFileSync(path.join(__dirname, 'fixtures', @@ -403,17 +455,20 @@ describe('find-visualstudio', function () { 'VS_2017_Community_workload.txt'))) const data3 = JSON.parse(fs.readFileSync(path.join(__dirname, 'fixtures', 'VS_2017_Express.txt'))) - const data4 = JSON.parse(fs.readFileSync(path.join(__dirname, 'fixtures', + const data = JSON.stringify(data0.concat(data1, data2, data3)) + return finder.parseData(null, data, '', [2017]) + } + finder.findVisualStudio2019OrNewer = async () => { + const data0 = JSON.parse(fs.readFileSync(path.join(__dirname, 'fixtures', 'VS_2019_Preview.txt'))) - const data5 = JSON.parse(fs.readFileSync(path.join(__dirname, 'fixtures', + const data1 = JSON.parse(fs.readFileSync(path.join(__dirname, 'fixtures', 'VS_2019_BuildTools_minimal.txt'))) - const data6 = JSON.parse(fs.readFileSync(path.join(__dirname, 'fixtures', + const data2 = JSON.parse(fs.readFileSync(path.join(__dirname, 'fixtures', 'VS_2019_Community_workload.txt'))) - const data7 = JSON.parse(fs.readFileSync(path.join(__dirname, 'fixtures', + const data3 = JSON.parse(fs.readFileSync(path.join(__dirname, 'fixtures', 'VS_2022_Community_workload.txt'))) - const data = JSON.stringify(data0.concat(data1, data2, data3, data4, - data5, data6, data7)) - return finder.parseData(null, data, '') + const data = JSON.stringify(data0.concat(data1, data2, data3)) + return finder.parseData(null, data, '', [2019, 2022]) } finder.regSearchKeys = async (keys, value, addOpts) => { for (let i = 0; i < keys.length; ++i) {