Skip to content

Commit 166737b

Browse files
fi3eworkCopilot
andauthored
feat: support customize bin path resolving (#194)
Co-authored-by: Copilot <[email protected]>
1 parent c37d3e5 commit 166737b

File tree

3 files changed

+77
-37
lines changed

3 files changed

+77
-37
lines changed

packages/vscode-extension/package.json

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,37 @@
3232
"contributes": {
3333
"configuration": {
3434
"type": "object",
35-
"title": "rslint",
35+
"title": "Rslint",
3636
"properties": {
3737
"rslint.enable": {
38+
"order": 0,
3839
"type": "boolean",
3940
"default": true,
4041
"description": "Enable/disable rslint"
4142
},
4243
"rslint.binPath": {
44+
"order": 1,
4345
"type": "string",
44-
"description": "Path to rslint executable"
46+
"enum": [
47+
"local",
48+
"built-in",
49+
"custom"
50+
],
51+
"default": "local",
52+
"markdownEnumDescriptions": [
53+
"Use workspace node_modules Rslint binary (may have version incompatibility with extension)",
54+
"Use extension's built-in Rslint binary (may differ from local @rslint/core diagnostics)",
55+
"Customize the path to the Rslint binary, this is useful if you have a global installation of Rslint or if you want to use a specific version of Rslint"
56+
],
57+
"description": "Path to Rslint executable binary"
58+
},
59+
"rslint.customBinPath": {
60+
"order": 2,
61+
"type": "string",
62+
"description": "Custom path to Rslint executable. Only used when `rslint.binPath` is set to `custom`. Requires reloading VS Code to take effect."
4563
},
4664
"rslint.trace.server": {
65+
"order": 3,
4766
"type": "string",
4867
"enum": [
4968
"off",

packages/vscode-extension/src/Rslint.ts

Lines changed: 54 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,8 @@ import {
1616
} from 'vscode-languageclient/node';
1717
import { Logger } from './logger';
1818
import type { Extension } from './Extension';
19-
import { fileExists, PLATFORM_BIN_REQUEST } from './utils';
19+
import { fileExists, PLATFORM_BIN_REQUEST, RslintBinPath } from './utils';
2020
import { dirname } from 'node:path';
21-
import { chmodSync } from 'node:fs';
2221

2322
export class Rslint implements Disposable {
2423
private client: LanguageClient | undefined;
@@ -148,33 +147,35 @@ export class Rslint implements Disposable {
148147
}
149148

150149
private async findBinaryFromUserSettings(): Promise<string | null> {
151-
const binPathConfig = (
152-
workspace.getConfiguration().get('rslint.binPath') as string
153-
).trim();
154-
155-
if (binPathConfig) {
156-
this.logger.debug(
157-
`Try using Rslint binary path from user settings: ${binPathConfig}`,
150+
const customBinPathConfig = workspace
151+
.getConfiguration()
152+
.get<string>('rslint.customBinPath')
153+
?.trim();
154+
155+
if (!customBinPathConfig) {
156+
this.logger.warn(
157+
'rslint.binPath is set to "custom" but rslint.customBinPath is not configured',
158158
);
159-
160-
const exist = await fileExists(Uri.file(binPathConfig));
161-
162-
if (exist) {
163-
this.logger.debug(
164-
`Using Rslint binary from user settings: ${binPathConfig}`,
165-
);
166-
return binPathConfig;
167-
} else {
168-
this.logger.warn(
169-
`Rslint binary path from user settings does not exist: ${binPathConfig}`,
170-
);
171-
}
159+
return null;
172160
}
173161

174162
this.logger.debug(
175-
'No Rslint binary path found in user settings, skip resolving',
163+
`Try using Rslint binary path from user settings: ${customBinPathConfig}`,
176164
);
177-
return null;
165+
166+
const exist = await fileExists(Uri.file(customBinPathConfig));
167+
168+
if (exist) {
169+
this.logger.debug(
170+
`Using Rslint binary from user settings: ${customBinPathConfig}`,
171+
);
172+
return customBinPathConfig;
173+
} else {
174+
this.logger.error(
175+
`Rslint binary path from user settings does not exist: ${customBinPathConfig}`,
176+
);
177+
return null;
178+
}
178179
}
179180

180181
private findBinaryFromNodeModules(): string | null {
@@ -261,19 +262,37 @@ export class Rslint implements Disposable {
261262
return builtInBinPath;
262263
}
263264

264-
// Try resolve Rslint binary path in the following order:
265-
// 1. From workspace settings
266-
// 2. From `node_modules`
267-
// 3. From `node_modules` in PnP mode
268-
// 4. From extension built-in as fallback
269265
private async getBinaryPath(): Promise<string> {
270-
const finalBinPath =
271-
(await this.findBinaryFromUserSettings()) ??
272-
this.findBinaryFromNodeModules() ??
273-
(await this.findBinaryFromPnp()) ??
274-
this.findBinaryFromBuiltIn();
266+
const binPathConfig = workspace
267+
.getConfiguration()
268+
.get<RslintBinPath>('rslint.binPath')!;
269+
270+
let finalBinPath: string | null = null;
271+
if (binPathConfig === 'local') {
272+
// 1. Check if the binary exists in node_modules or PnP
273+
// 2. Fallback to built-in binary if not found
274+
let localBinPath =
275+
this.findBinaryFromNodeModules() ?? (await this.findBinaryFromPnp());
276+
277+
if (localBinPath === null) {
278+
this.logger.info(
279+
'No local Rslint binary found, falling back to built-in binary',
280+
);
281+
}
282+
283+
finalBinPath = localBinPath ?? this.findBinaryFromBuiltIn();
284+
} else if (binPathConfig === 'built-in') {
285+
finalBinPath = this.findBinaryFromBuiltIn();
286+
} else if (binPathConfig === 'custom') {
287+
finalBinPath = await this.findBinaryFromUserSettings();
288+
if (finalBinPath === null) {
289+
throw new Error(
290+
'Customized Rslint binary path is not set or does not exist',
291+
);
292+
}
293+
}
275294

276295
this.logger.debug('Final Rslint binary path:', finalBinPath);
277-
return finalBinPath;
296+
return finalBinPath!;
278297
}
279298
}

packages/vscode-extension/src/utils.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,5 @@ export const fileExists = async (uri: Uri): Promise<boolean> => {
2323

2424
export const PLATFORM_KEY = `${process.platform}-${arch()}`;
2525
export const PLATFORM_BIN_REQUEST = `@rslint/${PLATFORM_KEY}/rslint`;
26+
27+
export type RslintBinPath = 'local' | 'built-in' | 'custom';

0 commit comments

Comments
 (0)