Skip to content

Commit 6000edb

Browse files
committed
refactor(vscode): detection and running of python from vscode
1 parent 4e2939e commit 6000edb

File tree

5 files changed

+90
-49
lines changed

5 files changed

+90
-49
lines changed

bundled/tool/utils/check_robot_version.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ def update_sys_path(path_to_add: str, strategy: str) -> None:
2121
os.fspath(pathlib.Path(__file__).parent.parent.parent / "libs"),
2222
os.getenv("LS_IMPORT_STRATEGY", "useBundled"),
2323
)
24+
try:
25+
__import__("robot")
26+
except ModuleNotFoundError:
27+
print("Robot Framework not installed", file=sys.stderr)
28+
sys.exit(1)
2429

2530
from robotcode.robot.utils import get_robot_version
2631

packages/language_server/src/robotcode/language_server/robotframework/diagnostics/library_doc.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1759,7 +1759,7 @@ def get_test_library(
17591759
from robot.libdocpkg.datatypes import TypeDoc as RobotTypeDoc
17601760
from robot.running.arguments.argumentspec import TypeInfo
17611761

1762-
def _yield_type_info(info: TypeInfo) -> TypeInfo:
1762+
def _yield_type_info(info: TypeInfo) -> Iterable[TypeInfo]:
17631763
if not info.is_union:
17641764
yield info
17651765
for nested in info.nested:

packages/robot/src/robotcode/robot/utils.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,17 @@
22

33
from robotcode.core.utils.version import Version, create_version_from_str
44

5+
import robot.version
6+
57
_robot_version: Optional[Version] = None
68

79

810
def get_robot_version() -> Version:
911
global _robot_version
1012
if _robot_version is None:
11-
import robot.version
12-
1313
_robot_version = create_version_from_str(robot.version.get_version())
1414
return _robot_version
15+
16+
17+
def get_robot_version_str() -> str:
18+
return str(robot.version.get_version())

vscode-client/languageclientsmanger.ts

Lines changed: 68 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -86,14 +86,16 @@ interface DiscoverInfoResult {
8686
system_version?: string;
8787
[key: string]: string | undefined;
8888
}
89+
8990
export class LanguageClientsManager {
9091
private clientsMutex = new Mutex();
92+
private _pythonValidPythonAndRobotEnvMutex = new Mutex();
9193

9294
public readonly clients: Map<string, LanguageClient> = new Map();
9395
public readonly outputChannels: Map<string, vscode.OutputChannel> = new Map();
9496

9597
private _disposables: vscode.Disposable;
96-
private _pythonValidPythonAndRobotEnv = new WeakMap<vscode.WorkspaceFolder, boolean>();
98+
public _pythonValidPythonAndRobotEnv = new WeakMap<vscode.WorkspaceFolder, boolean>();
9799
private _workspaceFolderDiscoverInfo = new WeakMap<vscode.WorkspaceFolder, DiscoverInfoResult>();
98100

99101
private readonly _onClientStateChangedEmitter = new vscode.EventEmitter<ClientStateChangedEvent>();
@@ -236,64 +238,84 @@ export class LanguageClientsManager {
236238
});
237239
}
238240

239-
private async getServerOptions(folder: vscode.WorkspaceFolder, mode: string): Promise<ServerOptions | undefined> {
240-
const config = vscode.workspace.getConfiguration(CONFIG_SECTION, folder);
241-
242-
const pythonCommand = this.pythonManager.getPythonCommand(folder);
241+
public async isValidRobotEnvironmentInFolder(
242+
folder: vscode.WorkspaceFolder,
243+
showDialogs?: boolean,
244+
): Promise<boolean> {
245+
return await this._pythonValidPythonAndRobotEnvMutex.dispatch(() => {
246+
if (this._pythonValidPythonAndRobotEnv.has(folder)) {
247+
return this._pythonValidPythonAndRobotEnv.get(folder) ?? false;
248+
}
243249

244-
const envOk = this._pythonValidPythonAndRobotEnv.get(folder);
245-
if (envOk === false) return undefined;
250+
const pythonCommand = this.pythonManager.getPythonCommand(folder);
251+
if (!pythonCommand) {
252+
this._pythonValidPythonAndRobotEnv.set(folder, false);
253+
if (showDialogs) {
254+
this.showErrorWithSelectPythonInterpreter(
255+
`Can't find a valid python executable for workspace folder '${folder.name}'. ` +
256+
"Check if python and the python extension is installed.",
257+
folder,
258+
);
259+
}
246260

247-
if (!pythonCommand) {
248-
this._pythonValidPythonAndRobotEnv.set(folder, false);
261+
return false;
262+
}
249263

250-
this.showErrorWithSelectPythonInterpreter(
251-
`Can't find a valid python executable for workspace folder '${folder.name}'. ` +
252-
"Check if python and the python extension is installed.",
253-
folder,
254-
);
264+
if (!this.pythonManager.checkPythonVersion(pythonCommand)) {
265+
this._pythonValidPythonAndRobotEnv.set(folder, false);
266+
if (showDialogs) {
267+
this.showErrorWithSelectPythonInterpreter(
268+
`Invalid python version for workspace folder '${folder.name}'. Only python version >= 3.8 supported. ` +
269+
"Please update to a newer python version or select a valid python environment.",
270+
folder,
271+
);
272+
}
255273

256-
return undefined;
257-
}
274+
return false;
275+
}
258276

259-
if (!this.pythonManager.checkPythonVersion(pythonCommand)) {
260-
this._pythonValidPythonAndRobotEnv.set(folder, false);
277+
const robotCheck = this.pythonManager.checkRobotVersion(pythonCommand);
278+
if (robotCheck === undefined) {
279+
this._pythonValidPythonAndRobotEnv.set(folder, false);
261280

262-
this.showErrorWithSelectPythonInterpreter(
263-
`Invalid python version for workspace folder '${folder.name}'. Only python version >= 3.8 supported. ` +
264-
"Please update to a newer python version or select a valid python environment.",
265-
folder,
266-
);
281+
if (showDialogs) {
282+
this.showErrorWithSelectPythonInterpreter(
283+
`Robot Framework package not found in workspace folder '${folder.name}'. ` +
284+
"Please install Robot Framework >= version 4.1 to the current python environment or select a valid python environment.",
285+
folder,
286+
);
287+
}
267288

268-
return undefined;
269-
}
289+
return false;
290+
}
270291

271-
const robotCheck = this.pythonManager.checkRobotVersion(pythonCommand);
272-
if (robotCheck === undefined) {
273-
this._pythonValidPythonAndRobotEnv.set(folder, false);
292+
if (robotCheck === false) {
293+
this._pythonValidPythonAndRobotEnv.set(folder, false);
274294

275-
this.showErrorWithSelectPythonInterpreter(
276-
`Robot Framework package not found in workspace folder '${folder.name}'. ` +
277-
"Please install Robot Framework >= Version 4.0 to the current python environment or select a valid python environment.",
278-
folder,
279-
);
295+
if (showDialogs) {
296+
this.showErrorWithSelectPythonInterpreter(
297+
`Robot Framework version in workspace folder '${folder.name}' not supported. Only Robot Framework version >= 4.1 supported. ` +
298+
"Please install or update to Robot Framework >= version 4.1 to the current python environment or select a valid python environment.",
299+
folder,
300+
);
301+
}
280302

281-
return undefined;
282-
}
303+
return false;
304+
}
283305

284-
if (robotCheck === false) {
285-
this._pythonValidPythonAndRobotEnv.set(folder, false);
306+
this._pythonValidPythonAndRobotEnv.set(folder, true);
307+
return true;
308+
});
309+
}
286310

287-
this.showErrorWithSelectPythonInterpreter(
288-
`Robot Framework version in workspace folder '${folder.name}' not supported. Only Robot Framework version >= 4.0.0 supported. ` +
289-
"Please install or update Robot Framework >= Version 4.0 to the current python environment or select a valid python environment.",
290-
folder,
291-
);
311+
private async getServerOptions(folder: vscode.WorkspaceFolder, mode: string): Promise<ServerOptions | undefined> {
312+
const config = vscode.workspace.getConfiguration(CONFIG_SECTION, folder);
292313

293-
return undefined;
294-
}
314+
const envOk = await this.isValidRobotEnvironmentInFolder(folder, true);
315+
if (envOk === false) return undefined;
295316

296-
this._pythonValidPythonAndRobotEnv.set(folder, true);
317+
const pythonCommand = this.pythonManager.getPythonCommand(folder);
318+
if (!pythonCommand) return undefined;
297319

298320
const robotCodeExtraArgs = config.get<string[]>("languageServer.extraArgs", []);
299321

@@ -714,7 +736,7 @@ export class LanguageClientsManager {
714736
try {
715737
const folder = vscode.workspace.getWorkspaceFolder(editor.document.uri);
716738
if (folder) {
717-
if (!this._workspaceFolderDiscoverInfo.has(folder)) {
739+
if (!this._workspaceFolderDiscoverInfo.has(folder) && (await this.isValidRobotEnvironmentInFolder(folder))) {
718740
this._workspaceFolderDiscoverInfo.set(
719741
folder,
720742
(await this.pythonManager.executeRobotCode(folder, ["discover", "info"])) as DiscoverInfoResult,

vscode-client/testcontrollermanager.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,12 @@ export class TestControllerManager {
307307
folder: vscode.WorkspaceFolder,
308308
profiles?: string[],
309309
): Promise<RobotCodeProfilesResult> {
310+
if (!(await this.languageClientsManager.isValidRobotEnvironmentInFolder(folder))) {
311+
return {
312+
profiles: [],
313+
messages: [],
314+
} as RobotCodeProfilesResult;
315+
}
310316
const config = vscode.workspace.getConfiguration(CONFIG_SECTION, folder);
311317
const paths = config.get<string[] | undefined>("robot.paths", undefined);
312318

@@ -523,6 +529,10 @@ export class TestControllerManager {
523529
stdioData?: string,
524530
token?: vscode.CancellationToken,
525531
): Promise<RobotCodeDiscoverResult> {
532+
if (!(await this.languageClientsManager.isValidRobotEnvironmentInFolder(folder))) {
533+
return {};
534+
}
535+
526536
const config = vscode.workspace.getConfiguration(CONFIG_SECTION, folder);
527537
const profiles = config.get<string[]>("profiles", []);
528538
const pythonPath = config.get<string[]>("robot.pythonPath", []);

0 commit comments

Comments
 (0)