Skip to content

Commit

Permalink
feat: add support for the fnm version manager
Browse files Browse the repository at this point in the history
* refactor

* feat: implements fnm support

* fix tests maybe

* fix: fnm windows path
  • Loading branch information
connor4312 committed Jul 2, 2023
2 parents 7fe038e + 64d9bab commit 3eb6b8a
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/dap/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
);
Expand Down
32 changes: 29 additions & 3 deletions src/targets/node/nvmResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const enum Vars {
NvsHome = 'NVS_HOME',
WindowsNvmHome = 'NVM_HOME',
UnixNvmHome = 'NVM_DIR',
FnmHome = 'FNM_DIR',
}

@injectable()
Expand All @@ -49,6 +50,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
Expand All @@ -61,9 +66,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) {
Expand All @@ -87,6 +89,17 @@ export class NvmResolver implements INvmResolver {
}
}

if (!directory) {
const fnmDir =
this.platform === 'win32'
? 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');
}
}

if (!versionManagers.length) {
throw new ProtocolError(nvmNotFound());
}
Expand Down Expand Up @@ -160,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,
Expand Down
52 changes: 50 additions & 2 deletions src/test/node/runtimeVersion.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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/installation/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,
Expand All @@ -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.10.0/installation/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/,
);
});

Expand Down Expand Up @@ -229,4 +237,44 @@ describe('runtimeVersion', () => {
);
});
});

describe('fnm', () => {
beforeEach(() => {
createFileTree(testFixturesDir, {
'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(
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/v13.3.0/installation/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/installation/bin'),
);
});

it('throws if no version match', async () => {
await expect(resolver.resolveNvmVersionPath('14')).to.eventually.be.rejectedWith(
ProtocolError,
/not installed/,
);
});
});
});

0 comments on commit 3eb6b8a

Please sign in to comment.