Improve path handling when starting processes (#575)

`editorPath.godot3/4` setting and `editor_path` debug configuration now correctly handle paths with spaces or surrounded with quotes.
This commit is contained in:
Daelon Suzuka
2024-01-24 21:14:39 -05:00
committed by GitHub
parent ccfd30755e
commit e2f2dc4b93
9 changed files with 129 additions and 43 deletions

View File

@@ -138,6 +138,17 @@ export class GodotDebugger implements DebugAdapterDescriptorFactory, DebugConfig
config.project = "${workspaceFolder}";
}
}
if (typeof config.port !== "number" || config.port < -1 || config.port > 65535) {
window.showErrorMessage("Can't launch debug session: 'port' must be a number between -1 and 65535.", "Ok");
return undefined;
}
if (config.address.includes("://")) {
window.showErrorMessage("Can't launch debug session: 'address' cannot include a protocol.", "Ok");
return undefined;
}
return config;
}

View File

@@ -101,26 +101,62 @@ export class ServerController {
private async start_game(args: LaunchRequestArguments) {
log.info("Starting game process");
const settingName = "editorPath.godot3";
const godotPath: string = get_configuration(settingName);
log.info(`Verifying version of '${godotPath}'`);
const result = verify_godot_version(godotPath, "3");
let godotPath: string;
let result;
if (args.editor_path) {
log.info("Using 'editor_path' variable from launch.json");
log.info("Got version string:", result);
switch (result.status) {
case "WRONG_VERSION": {
const projectVersion = await get_project_version();
const message = `Cannot launch debug session: The current project uses Godot v${projectVersion}, but the specified Godot executable is v${result.version}`;
log.warn(message);
prompt_for_godot_executable(message, settingName);
return;
godotPath = args.editor_path.replace(/^"/, "").replace(/"$/, "");
log.info(`Verifying version of '${godotPath}'`);
result = verify_godot_version(godotPath, "3");
log.info(`Verification result: ${result.status}, version: "${result.version}"`);
switch (result.status) {
case "WRONG_VERSION": {
const projectVersion = await get_project_version();
const message = `Cannot launch debug session: The current project uses Godot v${projectVersion}, but the specified Godot executable is v${result.version}`;
log.warn(message);
window.showErrorMessage(message, "Ok");
this.abort();
return;
}
case "INVALID_EXE": {
const message = `Cannot launch debug session: '${godotPath}' is not a valid Godot executable`;
log.warn(message);
window.showErrorMessage(message, "Ok");
this.abort();
return;
}
}
case "INVALID_EXE": {
const message = `Cannot launch debug session: '${godotPath}' is not a valid Godot executable`;
log.warn(message);
prompt_for_godot_executable(message, settingName);
return;
} else {
log.info("Using 'editorPath.godot3' from settings");
const settingName = "editorPath.godot3";
godotPath = get_configuration(settingName).replace(/^"/, "").replace(/"$/, "");
log.info(`Verifying version of '${godotPath}'`);
result = verify_godot_version(godotPath, "3");
log.info(`Verification result: ${result.status}, version: "${result.version}"`);
switch (result.status) {
case "WRONG_VERSION": {
const projectVersion = await get_project_version();
const message = `Cannot launch debug session: The current project uses Godot v${projectVersion}, but the specified Godot executable is v${result.version}`;
log.warn(message);
prompt_for_godot_executable(message, settingName);
this.abort();
return;
}
case "INVALID_EXE": {
const message = `Cannot launch debug session: '${godotPath}' is not a valid Godot executable`;
log.warn(message);
prompt_for_godot_executable(message, settingName);
this.abort();
return;
}
}
}

View File

@@ -102,26 +102,62 @@ export class ServerController {
private async start_game(args: LaunchRequestArguments) {
log.info("Starting game process");
const settingName = "editorPath.godot4";
const godotPath: string = get_configuration(settingName);
log.info(`Verifying version of '${godotPath}'`);
const result = verify_godot_version(godotPath, "4");
let godotPath: string;
let result;
if (args.editor_path) {
log.info("Using 'editor_path' variable from launch.json");
log.info("Got version string:", result);
switch (result.status) {
case "WRONG_VERSION": {
const projectVersion = await get_project_version();
const message = `Cannot launch debug session: The current project uses Godot v${projectVersion}, but the specified Godot executable is v${result.version}`;
log.warn(message);
prompt_for_godot_executable(message, settingName);
return;
godotPath = args.editor_path.replace(/^"/, "").replace(/"$/, "");
log.info(`Verifying version of '${godotPath}'`);
result = verify_godot_version(godotPath, "4");
log.info(`Verification result: ${result.status}, version: "${result.version}"`);
switch (result.status) {
case "WRONG_VERSION": {
const projectVersion = await get_project_version();
const message = `Cannot launch debug session: The current project uses Godot v${projectVersion}, but the specified Godot executable is v${result.version}`;
log.warn(message);
window.showErrorMessage(message, "Ok");
this.abort();
return;
}
case "INVALID_EXE": {
const message = `Cannot launch debug session: '${godotPath}' is not a valid Godot executable`;
log.warn(message);
window.showErrorMessage(message, "Ok");
this.abort();
return;
}
}
case "INVALID_EXE": {
const message = `Cannot launch debug session: '${godotPath}' is not a valid Godot executable`;
log.warn(message);
prompt_for_godot_executable(message, settingName);
return;
} else {
log.info("Using 'editorPath.godot4' from settings");
const settingName = "editorPath.godot4";
godotPath = get_configuration(settingName).replace(/^"/, "").replace(/"$/, "");
log.info(`Verifying version of '${godotPath}'`);
result = verify_godot_version(godotPath, "4");
log.info(`Verification result: ${result.status}, version: "${result.version}"`);
switch (result.status) {
case "WRONG_VERSION": {
const projectVersion = await get_project_version();
const message = `Cannot launch debug session: The current project uses Godot v${projectVersion}, but the specified Godot executable is v${result.version}`;
log.warn(message);
prompt_for_godot_executable(message, settingName);
this.abort();
return;
}
case "INVALID_EXE": {
const message = `Cannot launch debug session: '${godotPath}' is not a valid Godot executable`;
log.warn(message);
prompt_for_godot_executable(message, settingName);
this.abort();
return;
}
}
}
@@ -482,7 +518,7 @@ export class ServerController {
private send_command(command: string, parameters?: any[]) {
const commandArray: any[] = [command];
log.debug("send_command", this.connectedVersion);
// log.debug("send_command", this.connectedVersion);
if (this.connectedVersion[2] >= "2") {
commandArray.push(this.threadId);
}

View File

@@ -152,12 +152,12 @@ async function open_workspace_with_editor() {
const projectVersion = await get_project_version();
const settingName = `editorPath.godot${projectVersion[0]}`;
const godotPath = get_configuration(settingName);
const godotPath = get_configuration(settingName).replace(/^"/, "").replace(/"$/, "");
const result = verify_godot_version(godotPath, projectVersion[0]);
switch (result.status) {
case "SUCCESS": {
let command = `${godotPath} --path "${projectDir}" -e`;
let command = `"${godotPath}" --path "${projectDir}" -e`;
if (get_configuration("editor.verbose")) {
command += " -v";
}

View File

@@ -30,7 +30,7 @@ const registry = new vsctm.Registry({
if (scopeName === "source.gdscript") {
return readFile(grammarPath).then(data => vsctm.parseRawGrammar(data.toString(), grammarPath));
}
console.log(`Unknown scope name: ${scopeName}`);
// console.log(`Unknown scope name: ${scopeName}`);
return null;
}
});

View File

@@ -105,7 +105,7 @@ export class ClientConnectionManager {
targetVersion = "4.2";
}
const settingName = `editorPath.godot${projectVersion[0]}`;
const godotPath = get_configuration(settingName);
const godotPath = get_configuration(settingName).replace(/^"/, "").replace(/"$/, "");
const result = verify_godot_version(godotPath, projectVersion[0]);
switch (result.status) {
@@ -142,7 +142,7 @@ export class ClientConnectionManager {
log.info(`starting headless LSP on port ${this.client.port}`);
const headlessFlags = "--headless --no-window";
const command = `${godotPath} --path "${projectDir}" --editor ${headlessFlags} --lsp-port ${this.client.port}`;
const command = `"${godotPath}" --path "${projectDir}" --editor ${headlessFlags} --lsp-port ${this.client.port}`;
const lspProcess = subProcess("LSP", command, { shell: true, detached: true });
const lspStdout = createLogger("lsp.stdout");

View File

@@ -80,7 +80,7 @@ type VERIFY_RESULT = {
export function verify_godot_version(godotPath: string, expectedVersion: "3" | "4" | string): VERIFY_RESULT {
try {
const output = execSync(`${godotPath} -h`).toString().trim();
const output = execSync(`"${godotPath}" -h`).toString().trim();
const pattern = /^Godot Engine v(([34])\.([0-9]+)(?:\.[0-9]+)?)/;
const match = output.match(pattern);
if (!match) {