From 8a215e883b16e182ace94541a600efd5392d33b4 Mon Sep 17 00:00:00 2001 From: Thales Maciel Date: Sat, 24 Jun 2023 14:55:58 -0300 Subject: [PATCH 1/4] refactor --- src/targets/node/nvmResolver.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/targets/node/nvmResolver.ts b/src/targets/node/nvmResolver.ts index 8909a326c..699a3071c 100644 --- a/src/targets/node/nvmResolver.ts +++ b/src/targets/node/nvmResolver.ts @@ -49,6 +49,10 @@ export class NvmResolver implements INvmResolver { ) {} public async resolveNvmVersionPath(version: string) { + let directory: string | undefined = undefined; + const versionManagers: string[] = []; + const versionData = this.parseVersionString(version); + let nvsHome = this.env[Vars.NvsHome]; if (!nvsHome) { // NVS_HOME is not always set. Probe for 'nvs' directory instead @@ -61,9 +65,6 @@ export class NvmResolver implements INvmResolver { } } - let directory: string | undefined = undefined; - const versionManagers: string[] = []; - const versionData = this.parseVersionString(version); if (versionData.nvsFormat || nvsHome) { directory = await this.resolveNvs(nvsHome, versionData); if (!directory && versionData.nvsFormat) { From 246e555fc8368e59d4f121ac88dca432be178a80 Mon Sep 17 00:00:00 2001 From: Thales Maciel Date: Sat, 24 Jun 2023 16:41:36 -0300 Subject: [PATCH 2/4] feat: implements fnm support --- src/dap/errors.ts | 2 +- src/targets/node/nvmResolver.ts | 21 +++++++++++ src/test/node/runtimeVersion.test.ts | 52 ++++++++++++++++++++++++++-- 3 files changed, 72 insertions(+), 3 deletions(-) diff --git a/src/dap/errors.ts b/src/dap/errors.ts index c8ba52af2..9abf2dae2 100644 --- a/src/dap/errors.ts +++ b/src/dap/errors.ts @@ -65,7 +65,7 @@ export function createUserError(text: string, code = ErrorCodes.UserError): Dap. export const nvmNotFound = () => createUserError( l10n.t( - "Attribute 'runtimeVersion' requires Node.js version manager 'nvs' or 'nvm' to be installed.", + "Attribute 'runtimeVersion' requires Node.js version manager 'nvs', 'nvm' or 'fnm' to be installed.", ), ErrorCodes.NvmOrNvsNotFound, ); diff --git a/src/targets/node/nvmResolver.ts b/src/targets/node/nvmResolver.ts index 699a3071c..8b1b82a2e 100644 --- a/src/targets/node/nvmResolver.ts +++ b/src/targets/node/nvmResolver.ts @@ -36,6 +36,7 @@ const enum Vars { NvsHome = 'NVS_HOME', WindowsNvmHome = 'NVM_HOME', UnixNvmHome = 'NVM_DIR', + UnixFnmHome = 'FNM_DIR', } @injectable() @@ -88,6 +89,17 @@ export class NvmResolver implements INvmResolver { } } + if (!directory) { + const fnmDir = + this.platform === 'win32' + ? path.join(this.env['APPDATA'] || '', 'fnm') + : this.env[Vars.UnixFnmHome] || path.join(this.homedir, '.fnm'); + if (await this.fsUtils.exists(fnmDir)) { + directory = await this.resolveFnm(version, fnmDir); + versionManagers.push('fnm'); + } + } + if (!versionManagers.length) { throw new ProtocolError(nvmNotFound()); } @@ -152,6 +164,15 @@ export class NvmResolver implements INvmResolver { return directory ? path.join(directory, 'bin') : undefined; } + private async resolveFnm(version: string, fnmHome: string) { + const directory = this.findBinFolderForVersion( + path.join(fnmHome, 'node-versions'), + `v${version}`, + ); + + return directory ? path.join(directory, 'installation', 'bin') : undefined; + } + private async resolveWindowsNvm(version: string) { const nvmHome = this.env[Vars.WindowsNvmHome]; if (!nvmHome) { diff --git a/src/test/node/runtimeVersion.test.ts b/src/test/node/runtimeVersion.test.ts index 1aab9a076..a23dea4c2 100644 --- a/src/test/node/runtimeVersion.test.ts +++ b/src/test/node/runtimeVersion.test.ts @@ -30,11 +30,16 @@ describe('runtimeVersion', () => { 'nvs/node/13.12.0/x64/bin/node': '', 'nvs/node/13.11.0/x86/bin/node': '', 'nvm/versions/node/v13.11.0/bin/node': '', + 'fnm/node-versions/v13.10.0/instalation/bin/node': '', }); resolver = new NvmResolver( fsUtils, - { NVS_HOME: path.join(testFixturesDir, 'nvs'), NVM_DIR: path.join(testFixturesDir, 'nvm') }, + { + NVS_HOME: path.join(testFixturesDir, 'nvs'), + NVM_DIR: path.join(testFixturesDir, 'nvm'), + FNM_DIR: path.join(testFixturesDir, 'fnm'), + }, 'x64', 'linux', testWorkspace, @@ -48,9 +53,12 @@ describe('runtimeVersion', () => { const { directory: b } = await resolver.resolveNvmVersionPath('13.11'); expect(b).to.equal(path.join(testFixturesDir, 'nvm/versions/node/v13.11.0/bin')); + const { directory: c } = await resolver.resolveNvmVersionPath('13.10'); + expect(c).to.equal(path.join(testFixturesDir, 'fnm/node-versions/v13.11.0/instalation/bin')); + await expect(resolver.resolveNvmVersionPath('14')).to.eventually.be.rejectedWith( ProtocolError, - /not installed using version manager nvs\/nvm/, + /not installed using version manager nvs\/nvm\/fnm/, ); }); @@ -229,4 +237,44 @@ describe('runtimeVersion', () => { ); }); }); + + describe('fnm', () => { + beforeEach(() => { + createFileTree(testFixturesDir, { + 'node-versions/v13.12.0/instalation/bin/node': '', + 'node-versions/node/v13.3.0/instalation/bin/node': '', + 'node-versions/node/v13.invalid/instalation/bin/node': '', + }); + + resolver = new NvmResolver( + fsUtils, + { FNM_DIR: testFixturesDir }, + 'x64', + 'linux', + testWorkspace, + ); + }); + + it('gets an exact match', async () => { + const { directory, binary } = await resolver.resolveNvmVersionPath('13.3.0'); + expect(directory).to.equal( + path.join(testFixturesDir, 'node-versions/node/v13.3.0/instalation/bin'), + ); + expect(binary).to.equal('node'); + }); + + it('gets the best matching version', async () => { + const { directory } = await resolver.resolveNvmVersionPath('13'); + expect(directory).to.equal( + path.join(testFixturesDir, 'node-versions/v13.12.0/instalation/bin'), + ); + }); + + it('throws if no version match', async () => { + await expect(resolver.resolveNvmVersionPath('14')).to.eventually.be.rejectedWith( + ProtocolError, + /not installed/, + ); + }); + }); }); From 8420e2ecf2b348f722b4a7463f2625ca0e969a25 Mon Sep 17 00:00:00 2001 From: Thales Maciel Date: Sat, 24 Jun 2023 19:13:49 -0300 Subject: [PATCH 3/4] fix tests maybe --- src/test/node/runtimeVersion.test.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/test/node/runtimeVersion.test.ts b/src/test/node/runtimeVersion.test.ts index a23dea4c2..da6db7bc9 100644 --- a/src/test/node/runtimeVersion.test.ts +++ b/src/test/node/runtimeVersion.test.ts @@ -30,7 +30,7 @@ describe('runtimeVersion', () => { 'nvs/node/13.12.0/x64/bin/node': '', 'nvs/node/13.11.0/x86/bin/node': '', 'nvm/versions/node/v13.11.0/bin/node': '', - 'fnm/node-versions/v13.10.0/instalation/bin/node': '', + 'fnm/node-versions/v13.10.0/installation/bin/node': '', }); resolver = new NvmResolver( @@ -54,7 +54,7 @@ describe('runtimeVersion', () => { expect(b).to.equal(path.join(testFixturesDir, 'nvm/versions/node/v13.11.0/bin')); const { directory: c } = await resolver.resolveNvmVersionPath('13.10'); - expect(c).to.equal(path.join(testFixturesDir, 'fnm/node-versions/v13.11.0/instalation/bin')); + expect(c).to.equal(path.join(testFixturesDir, 'fnm/node-versions/v13.10.0/installation/bin')); await expect(resolver.resolveNvmVersionPath('14')).to.eventually.be.rejectedWith( ProtocolError, @@ -241,9 +241,9 @@ describe('runtimeVersion', () => { describe('fnm', () => { beforeEach(() => { createFileTree(testFixturesDir, { - 'node-versions/v13.12.0/instalation/bin/node': '', - 'node-versions/node/v13.3.0/instalation/bin/node': '', - 'node-versions/node/v13.invalid/instalation/bin/node': '', + 'node-versions/v13.12.0/installation/bin/node': '', + 'node-versions/v13.3.0/installation/bin/node': '', + 'node-versions/v13.invalid/installation/bin/node': '', }); resolver = new NvmResolver( @@ -258,7 +258,7 @@ describe('runtimeVersion', () => { it('gets an exact match', async () => { const { directory, binary } = await resolver.resolveNvmVersionPath('13.3.0'); expect(directory).to.equal( - path.join(testFixturesDir, 'node-versions/node/v13.3.0/instalation/bin'), + path.join(testFixturesDir, 'node-versions/v13.3.0/installation/bin'), ); expect(binary).to.equal('node'); }); @@ -266,7 +266,7 @@ describe('runtimeVersion', () => { it('gets the best matching version', async () => { const { directory } = await resolver.resolveNvmVersionPath('13'); expect(directory).to.equal( - path.join(testFixturesDir, 'node-versions/v13.12.0/instalation/bin'), + path.join(testFixturesDir, 'node-versions/v13.12.0/installation/bin'), ); }); From 64d9bab039e2298c1b2bcaff74fac7d624cff973 Mon Sep 17 00:00:00 2001 From: Thales Maciel Date: Fri, 30 Jun 2023 21:24:00 -0300 Subject: [PATCH 4/4] fix: fnm windows path --- src/targets/node/nvmResolver.ts | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/targets/node/nvmResolver.ts b/src/targets/node/nvmResolver.ts index 8b1b82a2e..eafe4a378 100644 --- a/src/targets/node/nvmResolver.ts +++ b/src/targets/node/nvmResolver.ts @@ -36,7 +36,7 @@ const enum Vars { NvsHome = 'NVS_HOME', WindowsNvmHome = 'NVM_HOME', UnixNvmHome = 'NVM_DIR', - UnixFnmHome = 'FNM_DIR', + FnmHome = 'FNM_DIR', } @injectable() @@ -92,8 +92,8 @@ export class NvmResolver implements INvmResolver { if (!directory) { const fnmDir = this.platform === 'win32' - ? path.join(this.env['APPDATA'] || '', 'fnm') - : this.env[Vars.UnixFnmHome] || path.join(this.homedir, '.fnm'); + ? this.env[Vars.FnmHome] || path.join(this.env['APPDATA'] || '', 'fnm') + : this.env[Vars.FnmHome] || path.join(this.homedir, '.fnm'); if (await this.fsUtils.exists(fnmDir)) { directory = await this.resolveFnm(version, fnmDir); versionManagers.push('fnm'); @@ -164,15 +164,6 @@ export class NvmResolver implements INvmResolver { return directory ? path.join(directory, 'bin') : undefined; } - private async resolveFnm(version: string, fnmHome: string) { - const directory = this.findBinFolderForVersion( - path.join(fnmHome, 'node-versions'), - `v${version}`, - ); - - return directory ? path.join(directory, 'installation', 'bin') : undefined; - } - private async resolveWindowsNvm(version: string) { const nvmHome = this.env[Vars.WindowsNvmHome]; if (!nvmHome) { @@ -182,6 +173,19 @@ export class NvmResolver implements INvmResolver { return this.findBinFolderForVersion(nvmHome, `v${version}`); } + private async resolveFnm(version: string, fnmHome: string) { + const directory = this.findBinFolderForVersion( + path.join(fnmHome, 'node-versions'), + `v${version}`, + ); + + if (!directory) return; + + return this.platform === 'win32' + ? path.join(directory, 'installation') + : path.join(directory, 'installation', 'bin'); + } + private findBinFolderForVersion( dir: string, version: string,