diff --git a/src/client.ts b/src/client.ts index 96d6930f..5de2226e 100644 --- a/src/client.ts +++ b/src/client.ts @@ -22,6 +22,7 @@ import { Telemetry, RequestEvent } from "./telemetry"; import { Ruby } from "./ruby"; import { StatusItems, Command, ServerState, ClientInterface } from "./status"; import { TestController } from "./testController"; +import { LOG_CHANNEL } from "./common"; const LSP_NAME = "Ruby LSP"; const asyncExec = promisify(exec); @@ -37,7 +38,6 @@ export default class Client implements ClientInterface { private readonly workingFolder: string; private readonly telemetry: Telemetry; private readonly statusItems: StatusItems; - private readonly outputChannel: vscode.OutputChannel; private readonly testController: TestController; private readonly customBundleGemfile: string = vscode.workspace .getConfiguration("rubyLsp") @@ -56,7 +56,6 @@ export default class Client implements ClientInterface { telemetry: Telemetry, ruby: Ruby, testController: TestController, - outputChannel: vscode.OutputChannel, workingFolder = vscode.workspace.workspaceFolders![0].uri.fsPath, ) { this.workingFolder = workingFolder; @@ -65,7 +64,6 @@ export default class Client implements ClientInterface { this.testController = testController; this.#context = context; this.#ruby = ruby; - this.outputChannel = outputChannel; this.#formatter = ""; this.statusItems = new StatusItems(this); this.registerCommands(); @@ -111,7 +109,7 @@ export default class Client implements ClientInterface { const clientOptions: LanguageClientOptions = { documentSelector: [{ language: "ruby" }], diagnosticCollectionName: LSP_NAME, - outputChannel: this.outputChannel, + outputChannel: LOG_CHANNEL, revealOutputChannelOn: RevealOutputChannelOn.Never, diagnosticPullOptions: this.diagnosticPullOptions(), initializationOptions: { @@ -231,9 +229,7 @@ export default class Client implements ClientInterface { await this.client.start(); } catch (error: any) { this.state = ServerState.Error; - this.outputChannel.appendLine( - `Error restarting the server: ${error.message}`, - ); + LOG_CHANNEL.error(`Error restarting the server: ${error.message}`); return; } @@ -274,16 +270,12 @@ export default class Client implements ClientInterface { } } catch (error: any) { this.state = ServerState.Error; - - this.outputChannel.appendLine( - `Error restarting the server: ${error.message}`, - ); + LOG_CHANNEL.error(`Error restarting the server: ${error.message}`); } } dispose() { this.client?.dispose(); - this.outputChannel.dispose(); } get ruby(): Ruby { @@ -461,9 +453,7 @@ export default class Client implements ClientInterface { this.context.workspaceState.update("rubyLsp.lastGemUpdate", Date.now()); } catch (error) { // If we fail to update the global installation of `ruby-lsp`, we don't want to prevent the server from starting - this.outputChannel.appendLine( - `Failed to update global ruby-lsp gem: ${error}`, - ); + LOG_CHANNEL.error(`Failed to update global ruby-lsp gem: ${error}`); } } } diff --git a/src/common.ts b/src/common.ts index 93135768..c0e4507d 100644 --- a/src/common.ts +++ b/src/common.ts @@ -2,7 +2,12 @@ import fs from "fs/promises"; import { exec } from "child_process"; import { promisify } from "util"; +import * as vscode from "vscode"; + export const asyncExec = promisify(exec); +export const LOG_CHANNEL = vscode.window.createOutputChannel("Ruby LSP", { + log: true, +}); export async function pathExists( path: string, diff --git a/src/debugger.ts b/src/debugger.ts index 72f64fc6..89c045a4 100644 --- a/src/debugger.ts +++ b/src/debugger.ts @@ -5,6 +5,7 @@ import { ChildProcessWithoutNullStreams, spawn } from "child_process"; import * as vscode from "vscode"; import { Ruby } from "./ruby"; +import { LOG_CHANNEL } from "./common"; export class Debugger implements @@ -16,16 +17,13 @@ export class Debugger private debugProcess?: ChildProcessWithoutNullStreams; private readonly console = vscode.debug.activeDebugConsole; private readonly subscriptions: vscode.Disposable[]; - private readonly outputChannel: vscode.OutputChannel; constructor( context: vscode.ExtensionContext, ruby: Ruby, - outputChannel: vscode.OutputChannel, workingFolder = vscode.workspace.workspaceFolders![0].uri.fsPath, ) { this.ruby = ruby; - this.outputChannel = outputChannel; this.subscriptions = [ vscode.debug.registerDebugConfigurationProvider("ruby_lsp", this), vscode.debug.registerDebugAdapterDescriptorFactory("ruby_lsp", this), @@ -183,15 +181,9 @@ export class Debugger configuration.program, ]; - this.outputChannel.appendLine( - `Ruby LSP> Spawning debugger in directory ${this.workingFolder}`, - ); - this.outputChannel.appendLine( - `Ruby LSP> Command bundle ${args.join(" ")}`, - ); - this.outputChannel.appendLine( - `Ruby LSP> Environment ${JSON.stringify(configuration.env)}`, - ); + LOG_CHANNEL.info(`Spawning debugger in directory ${this.workingFolder}`); + LOG_CHANNEL.info(` Command bundle ${args.join(" ")}`); + LOG_CHANNEL.info(` Environment ${JSON.stringify(configuration.env)}`); this.debugProcess = spawn("bundle", args, { shell: true, @@ -236,7 +228,7 @@ export class Debugger if (code) { const message = `Debugger exited with status ${code}. Check the output channel for more information.`; this.console.append(message); - this.outputChannel.show(); + LOG_CHANNEL.show(); reject(new Error(message)); } }); diff --git a/src/extension.ts b/src/extension.ts index 789838dd..21424610 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -12,10 +12,8 @@ let debug: Debugger | undefined; let testController: TestController | undefined; export async function activate(context: vscode.ExtensionContext) { - const outputChannel = vscode.window.createOutputChannel("Ruby LSP"); const ruby = new Ruby( context, - outputChannel, vscode.workspace.workspaceFolders![0].uri.fsPath, ); await ruby.activateRuby(); @@ -30,10 +28,10 @@ export async function activate(context: vscode.ExtensionContext) { telemetry, ); - client = new Client(context, telemetry, ruby, testController, outputChannel); + client = new Client(context, telemetry, ruby, testController); await client.start(); - debug = new Debugger(context, ruby, outputChannel); + debug = new Debugger(context, ruby); vscode.workspace.registerTextDocumentContentProvider( "ruby-lsp", diff --git a/src/ruby.ts b/src/ruby.ts index 341ca63e..4f5f3c71 100644 --- a/src/ruby.ts +++ b/src/ruby.ts @@ -3,7 +3,7 @@ import fs from "fs/promises"; import * as vscode from "vscode"; -import { asyncExec, pathExists } from "./common"; +import { asyncExec, pathExists, LOG_CHANNEL } from "./common"; export enum VersionManager { Asdf = "asdf", @@ -29,16 +29,10 @@ export class Ruby { private readonly context: vscode.ExtensionContext; private readonly customBundleGemfile?: string; private readonly cwd: string; - private readonly outputChannel: vscode.OutputChannel; - constructor( - context: vscode.ExtensionContext, - outputChannel: vscode.OutputChannel, - workingFolder: string, - ) { + constructor(context: vscode.ExtensionContext, workingFolder: string) { this.context = context; this.workingFolder = workingFolder; - this.outputChannel = outputChannel; const customBundleGemfile: string = vscode.workspace .getConfiguration("rubyLsp") @@ -81,9 +75,7 @@ export class Ruby { // If the version manager is auto, discover the actual manager before trying to activate anything if (this.versionManager === VersionManager.Auto) { await this.discoverVersionManager(); - this.outputChannel.appendLine( - `Ruby LSP> Discovered version manager ${this.versionManager}`, - ); + LOG_CHANNEL.info(`Discovered version manager ${this.versionManager}`); } try { @@ -189,8 +181,8 @@ export class Ruby { command += "'"; } - this.outputChannel.appendLine( - `Ruby LSP> Trying to activate Ruby environment with command: ${command} inside directory: ${this.cwd}`, + LOG_CHANNEL.info( + `Trying to activate Ruby environment with command: ${command} inside directory: ${this.cwd}`, ); const result = await asyncExec(command, { cwd: this.cwd }); @@ -323,8 +315,8 @@ export class Ruby { command += "'"; } - this.outputChannel.appendLine( - `Ruby LSP> Checking if ${tool} is available on the path with command: ${command}`, + LOG_CHANNEL.info( + `Checking if ${tool} is available on the path with command: ${command}`, ); await asyncExec(command, { cwd: this.workingFolder, timeout: 1000 }); diff --git a/src/test/suite/client.test.ts b/src/test/suite/client.test.ts index 9a75a488..507d76db 100644 --- a/src/test/suite/client.test.ts +++ b/src/test/suite/client.test.ts @@ -28,7 +28,6 @@ class FakeApi implements TelemetryApi { suite("Client", () => { let client: Client | undefined; let testController: TestController | undefined; - const outputChannel = vscode.window.createOutputChannel("Ruby LSP"); const managerConfig = vscode.workspace.getConfiguration("rubyLsp"); const currentManager = managerConfig.get("rubyVersionManager"); const tmpPath = fs.mkdtempSync(path.join(os.tmpdir(), "ruby-lsp-test-")); @@ -67,7 +66,7 @@ suite("Client", () => { }, } as unknown as vscode.ExtensionContext; - const ruby = new Ruby(context, outputChannel, tmpPath); + const ruby = new Ruby(context, tmpPath); await ruby.activateRuby(); const telemetry = new Telemetry(context, new FakeApi()); @@ -84,7 +83,6 @@ suite("Client", () => { telemetry, ruby, testController, - outputChannel, tmpPath, ); await client.start(); diff --git a/src/test/suite/debugger.test.ts b/src/test/suite/debugger.test.ts index e7e391bf..626b06a7 100644 --- a/src/test/suite/debugger.test.ts +++ b/src/test/suite/debugger.test.ts @@ -9,12 +9,10 @@ import { Debugger } from "../../debugger"; import { Ruby } from "../../ruby"; suite("Debugger", () => { - const outputChannel = vscode.window.createOutputChannel("Ruby LSP"); - test("Provide debug configurations returns the default configs", () => { const context = { subscriptions: [] } as unknown as vscode.ExtensionContext; const ruby = { env: {} } as Ruby; - const debug = new Debugger(context, ruby, outputChannel, "fake"); + const debug = new Debugger(context, ruby, "fake"); const configs = debug.provideDebugConfigurations!(undefined); assert.deepEqual( [ @@ -47,7 +45,7 @@ suite("Debugger", () => { test("Resolve configuration injects Ruby environment", () => { const context = { subscriptions: [] } as unknown as vscode.ExtensionContext; const ruby = { env: { bogus: "hello!" } } as unknown as Ruby; - const debug = new Debugger(context, ruby, outputChannel, "fake"); + const debug = new Debugger(context, ruby, "fake"); const configs: any = debug.resolveDebugConfiguration!(undefined, { type: "ruby_lsp", name: "Debug", @@ -63,7 +61,7 @@ suite("Debugger", () => { test("Resolve configuration injects Ruby environment and allows users custom environment", () => { const context = { subscriptions: [] } as unknown as vscode.ExtensionContext; const ruby = { env: { bogus: "hello!" } } as unknown as Ruby; - const debug = new Debugger(context, ruby, outputChannel, "fake"); + const debug = new Debugger(context, ruby, "fake"); const configs: any = debug.resolveDebugConfiguration!(undefined, { type: "ruby_lsp", name: "Debug", @@ -84,7 +82,7 @@ suite("Debugger", () => { const context = { subscriptions: [] } as unknown as vscode.ExtensionContext; const ruby = { env: { bogus: "hello!" } } as unknown as Ruby; - const debug = new Debugger(context, ruby, outputChannel, tmpPath); + const debug = new Debugger(context, ruby, tmpPath); const configs: any = debug.resolveDebugConfiguration!(undefined, { type: "ruby_lsp", name: "Debug", diff --git a/src/test/suite/ruby.test.ts b/src/test/suite/ruby.test.ts index a84982a9..aa0efc87 100644 --- a/src/test/suite/ruby.test.ts +++ b/src/test/suite/ruby.test.ts @@ -21,11 +21,7 @@ suite("Ruby environment activation", () => { extensionMode: vscode.ExtensionMode.Test, } as vscode.ExtensionContext; - ruby = new Ruby( - context, - vscode.window.createOutputChannel("Ruby LSP"), - tmpPath, - ); + ruby = new Ruby(context, tmpPath); await ruby.activateRuby( // eslint-disable-next-line no-process-env process.env.CI ? VersionManager.None : VersionManager.Chruby,