From a5839f25417c97a99262985b43ef6eb99a9655c9 Mon Sep 17 00:00:00 2001 From: Steve Clarke Date: Sat, 17 Jan 2026 16:45:13 -0330 Subject: [PATCH] feat: Add multi-root workspace support Each workspace folder now gets its own language server with its own Standard Ruby configuration. This fixes false positives in monorepos where different folders have different configs (e.g., Rails app with standard-rails alongside a Ruby library with plain standard). Changes: - Extract ClientManager class to manage per-folder language clients - Add workspace folder change listener (start/stop servers on add/remove) - Scope document selectors, diagnostics, and file watchers per folder - Fix resource leak: file watchers now properly disposed on server stop - Fix ${cwd} resolution inconsistency in command paths - Align engines.vscode with @types/vscode (^1.102.0) Closes #9 --- package.json | 2 +- src/clientManager.ts | 291 +++++++++++++++ src/extension.ts | 295 +++++++-------- src/test/suite/clientManager.test.ts | 240 +++++++++++++ src/test/suite/index.test.ts | 12 +- test-fixtures/multi-root-demo/.gitignore | 2 + test-fixtures/multi-root-demo/README.md | 87 +++++ .../multi-root-demo/app-rails/.standard.yml | 2 + .../multi-root-demo/app-rails/Gemfile | 8 + .../multi-root-demo/app-rails/Gemfile.lock | 339 ++++++++++++++++++ .../app/controllers/users_controller.rb | 11 + .../multi-root-demo.code-workspace | 60 ++++ .../multi-root-demo/rails-output-error.png | Bin 0 -> 131629 bytes .../multi-root-demo/ruby-lib/.standard.yml | 3 + .../multi-root-demo/ruby-lib/Gemfile | 5 + .../multi-root-demo/ruby-lib/Gemfile.lock | 80 +++++ .../ruby-lib/lib/string_utils.rb | 6 + 17 files changed, 1290 insertions(+), 153 deletions(-) create mode 100644 src/clientManager.ts create mode 100644 src/test/suite/clientManager.test.ts create mode 100644 test-fixtures/multi-root-demo/.gitignore create mode 100644 test-fixtures/multi-root-demo/README.md create mode 100644 test-fixtures/multi-root-demo/app-rails/.standard.yml create mode 100644 test-fixtures/multi-root-demo/app-rails/Gemfile create mode 100644 test-fixtures/multi-root-demo/app-rails/Gemfile.lock create mode 100644 test-fixtures/multi-root-demo/app-rails/app/controllers/users_controller.rb create mode 100644 test-fixtures/multi-root-demo/multi-root-demo.code-workspace create mode 100644 test-fixtures/multi-root-demo/rails-output-error.png create mode 100644 test-fixtures/multi-root-demo/ruby-lib/.standard.yml create mode 100644 test-fixtures/multi-root-demo/ruby-lib/Gemfile create mode 100644 test-fixtures/multi-root-demo/ruby-lib/Gemfile.lock create mode 100644 test-fixtures/multi-root-demo/ruby-lib/lib/string_utils.rb diff --git a/package.json b/package.json index 5186039..f6e6ed7 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,7 @@ }, "packageManager": "yarn@1.22.19", "engines": { - "vscode": "^1.75.0" + "vscode": "^1.102.0" }, "categories": [ "Formatters", diff --git a/src/clientManager.ts b/src/clientManager.ts new file mode 100644 index 0000000..667ec72 --- /dev/null +++ b/src/clientManager.ts @@ -0,0 +1,291 @@ +import { + Diagnostic, + TextDocument, + WorkspaceFolder, + workspace +} from 'vscode' +import { + DidOpenTextDocumentNotification, + Disposable, + LanguageClient +} from 'vscode-languageclient/node' + +export interface ClientManagerOptions { + log: (message: string) => void + createClient: (folder: WorkspaceFolder) => Promise + shouldEnableForFolder: (folder: WorkspaceFolder) => Promise + onError: (message: string, folder: WorkspaceFolder) => Promise + onStatusUpdate: () => void + supportedLanguage: (languageId: string) => boolean +} + +/** + * Manages multiple language clients for multi-root workspace support. + * + * VS Code multi-root workspaces can contain folders with different Standard Ruby + * configurations (e.g., one folder using standard-rails plugin, another using plain + * standard). This class ensures each folder gets its own language server instance + * running with the correct configuration. + */ +export class ClientManager { + // One language client per workspace folder, keyed by folder URI + private readonly clients: Map = new Map() + + // Diagnostic cache per folder - used by status bar and middleware + private readonly diagnosticCaches: Map> = new Map() + + // Track file system watchers per folder so we can dispose them when stopping servers + private readonly watchers: Map = new Map() + + // Track folders with server start in progress to prevent race conditions + private readonly pendingStarts: Set = new Set() + + private readonly options: ClientManagerOptions + + constructor (options: ClientManagerOptions) { + this.options = options + } + + /** + * Get the language client for a document's workspace folder. + */ + getClient (document: TextDocument): LanguageClient | undefined { + const folder = workspace.getWorkspaceFolder(document.uri) + if (folder == null) return undefined + return this.clients.get(this.getFolderKey(folder)) + } + + /** + * Get the first available client. + */ + getFirstClient (): LanguageClient | null { + return this.clients.values().next().value ?? null + } + + /** + * Get the number of active clients. + */ + get size (): number { + return this.clients.size + } + + /** + * Iterate over all clients. + */ + values (): IterableIterator { + return this.clients.values() + } + + /** + * Get diagnostics for a document from its folder's cache. + */ + getDiagnostics (document: TextDocument): Diagnostic[] | undefined { + const folder = workspace.getWorkspaceFolder(document.uri) + if (folder == null) return undefined + return this.diagnosticCaches.get(this.getFolderKey(folder))?.get(document.uri.toString()) + } + + /** + * Get the diagnostic cache for a folder. + */ + getDiagnosticCacheForFolder (folder: WorkspaceFolder): Map { + const key = this.getFolderKey(folder) + let cache = this.diagnosticCaches.get(key) + if (cache == null) { + cache = new Map() + this.diagnosticCaches.set(key, cache) + } + return cache + } + + /** + * Register file system watchers for a folder. + * + * Watchers are tracked here so they can be properly disposed when a folder's + * language server is stopped, preventing resource leaks. + */ + registerWatchers (folder: WorkspaceFolder, watcherDisposables: Disposable[]): void { + this.watchers.set(this.getFolderKey(folder), watcherDisposables) + } + + /** + * Start the language server for a specific workspace folder. + */ + async startForFolder (folder: WorkspaceFolder): Promise { + const key = this.getFolderKey(folder) + + // Already running for this folder + if (this.clients.has(key)) return + + // Prevent race condition: startForFolder can be called multiple times concurrently + // (e.g., from workspace folder listener and manual start command). Without this + // guard, we could end up with duplicate servers for the same folder. + if (this.pendingStarts.has(key)) return + this.pendingStarts.add(key) + + try { + if (!(await this.options.shouldEnableForFolder(folder))) { + this.options.log(`Skipping workspace folder "${folder.name}" - extension disabled or not applicable`) + return + } + + const client = await this.options.createClient(folder) + if (client != null) { + this.clients.set(key, client) + await client.start() + await this.afterStart(client, folder) + this.options.log(`Language server started for "${folder.name}"`) + } + } catch (error) { + // Clean up partial state on failure + this.clients.delete(key) + this.cleanupWatchers(key) + this.options.log(`Failed to start language server for "${folder.name}": ${String(error)}`) + await this.options.onError(`Failed to start Standard Ruby Language Server for "${folder.name}"`, folder) + } finally { + this.pendingStarts.delete(key) + } + } + + /** + * Stop the language server for a specific workspace folder. + */ + async stopForFolder (folder: WorkspaceFolder): Promise { + const key = this.getFolderKey(folder) + const client = this.clients.get(key) + if (client == null) return + + this.options.log(`Stopping language server for "${folder.name}"...`) + await client.stop() + this.clients.delete(key) + this.diagnosticCaches.delete(key) + this.cleanupWatchers(key) + } + + /** + * Start language servers for all workspace folders. + */ + async startAll (): Promise { + for (const folder of workspace.workspaceFolders ?? []) { + await this.startForFolder(folder) + } + } + + /** + * Stop all language servers. + */ + async stopAll (): Promise { + this.options.log('Stopping all language servers...') + for (const client of this.clients.values()) { + await client.stop() + } + this.clients.clear() + this.diagnosticCaches.clear() + this.cleanupAllWatchers() + } + + /** + * Restart all language servers. + */ + async restartAll (): Promise { + this.options.log('Restarting all language servers...') + await this.stopAll() + await this.startAll() + } + + /** + * Create a disposable that handles workspace folder changes. + */ + createWorkspaceFolderListener (): Disposable { + return workspace.onDidChangeWorkspaceFolders(async event => { + for (const folder of event.removed) { + await this.stopForFolder(folder) + } + for (const folder of event.added) { + await this.startForFolder(folder) + } + }) + } + + /** + * Send a document open notification if needed. + * + * When the user switches to a document that the language server hasn't seen yet + * (not in the diagnostic cache), we notify the server so it can provide diagnostics. + * This handles the case where documents were opened before the server started. + */ + async notifyDocumentOpenIfNeeded (document: TextDocument): Promise { + if (!this.options.supportedLanguage(document.languageId)) return + + const folder = workspace.getWorkspaceFolder(document.uri) + if (folder == null) return + + const client = this.clients.get(this.getFolderKey(folder)) + if (client == null) return + + // If we haven't received diagnostics for this document, the server doesn't know + // about it yet. Send an open notification so the server can lint it. + const cache = this.getDiagnosticCacheForFolder(folder) + if (!cache.has(document.uri.toString())) { + await client.sendNotification( + DidOpenTextDocumentNotification.type, + client.code2ProtocolConverter.asOpenTextDocumentParams(document) + ) + } + } + + private getFolderKey (folder: WorkspaceFolder): string { + return folder.uri.toString() + } + + private async afterStart (client: LanguageClient, folder: WorkspaceFolder): Promise { + this.diagnosticCaches.set(this.getFolderKey(folder), new Map()) + await this.syncOpenDocuments(client, folder) + this.options.onStatusUpdate() + } + + /** + * Notify the language server about all documents that are already open in this folder. + * + * When a language server starts, it doesn't know about documents that were opened + * before it was running. This method sends open notifications for all such documents + * so the server can provide immediate diagnostics without waiting for the user to + * edit or switch tabs. + */ + private async syncOpenDocuments (client: LanguageClient, folder: WorkspaceFolder): Promise { + const key = this.getFolderKey(folder) + for (const doc of workspace.textDocuments) { + if (!this.options.supportedLanguage(doc.languageId)) continue + const docFolder = workspace.getWorkspaceFolder(doc.uri) + if (docFolder == null || this.getFolderKey(docFolder) !== key) continue + + await client.sendNotification( + DidOpenTextDocumentNotification.type, + client.code2ProtocolConverter.asOpenTextDocumentParams(doc) + ) + } + } + + private cleanupWatchers (key: string): void { + this.watchers.get(key)?.forEach(w => w.dispose()) + this.watchers.delete(key) + } + + private cleanupAllWatchers (): void { + for (const watcherList of this.watchers.values()) { + watcherList.forEach(w => w.dispose()) + } + this.watchers.clear() + } +} + +/** + * Normalize path for glob patterns. + * + * Windows uses backslashes in file paths (C:\Users\...) but glob patterns require + * forward slashes to work correctly. This function converts backslashes to forward + * slashes so globs work cross-platform. + */ +export function normalizePathForGlob (fsPath: string): string { + return fsPath.replace(/\\/g, '/') +} diff --git a/src/extension.ts b/src/extension.ts index ebb71b5..1b4b30d 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -3,10 +3,10 @@ import { homedir } from 'os' import * as path from 'path' import { satisfies } from 'semver' import { - Diagnostic, DiagnosticSeverity, ExtensionContext, OutputChannel, + WorkspaceFolder, commands, window, workspace, @@ -18,7 +18,6 @@ import { StatusBarItem } from 'vscode' import { - DidOpenTextDocumentNotification, Disposable, Executable, ExecuteCommandRequest, @@ -26,6 +25,7 @@ import { LanguageClientOptions, RevealOutputChannelOn } from 'vscode-languageclient/node' +import { ClientManager, normalizePathForGlob } from './clientManager' class ExecError extends Error { command: string @@ -54,7 +54,7 @@ class ExecError extends Error { } } -const promiseExec = async function (command: string, options = { cwd: getCwd() }): Promise<{ stdout: string, stderr: string }> { +const promiseExec = async function (command: string, options: { cwd: string }): Promise<{ stdout: string, stderr: string }> { return await new Promise((resolve, reject) => { exec(command, options, (error, stdout, stderr) => { stdout = stdout.toString().trim() @@ -68,13 +68,18 @@ const promiseExec = async function (command: string, options = { cwd: getCwd() } }) } -export let languageClient: LanguageClient | null = null +// Multi-root workspace support via ClientManager +let clientManager: ClientManager | null = null let outputChannel: OutputChannel | undefined let statusBarItem: StatusBarItem | undefined -let diagnosticCache: Map = new Map() -function getCwd (): string { - return workspace.workspaceFolders?.[0]?.uri?.fsPath ?? process.cwd() +// Public API for accessing language clients +export function getLanguageClient (): LanguageClient | null { + return clientManager?.getFirstClient() ?? null +} +export const languageClients = { + get size (): number { return clientManager?.size ?? 0 }, + values (): IterableIterator { return clientManager?.values() ?? [].values() } } function log (s: string): void { @@ -91,22 +96,26 @@ function supportedLanguage (languageId: string): boolean { function registerCommands (): Disposable[] { return [ - commands.registerCommand('standardRuby.start', startLanguageServer), - commands.registerCommand('standardRuby.stop', stopLanguageServer), - commands.registerCommand('standardRuby.restart', restartLanguageServer), + commands.registerCommand('standardRuby.start', async () => await clientManager?.startAll()), + commands.registerCommand('standardRuby.stop', async () => await clientManager?.stopAll()), + commands.registerCommand('standardRuby.restart', async () => await clientManager?.restartAll()), commands.registerCommand('standardRuby.showOutputChannel', () => outputChannel?.show()), commands.registerCommand('standardRuby.formatAutoFixes', formatAutoFixes) ] } function registerWorkspaceListeners (): Disposable[] { - return [ + const listeners: Disposable[] = [ workspace.onDidChangeConfiguration(async event => { if (event.affectsConfiguration('standardRuby')) { - await restartLanguageServer() + await clientManager?.restartAll() } }) ] + if (clientManager != null) { + listeners.push(clientManager.createWorkspaceFolderListener()) + } + return listeners } export enum BundleStatus { @@ -121,34 +130,34 @@ export enum StandardBundleStatus { errored = 2 } -async function displayBundlerError (e: ExecError): Promise { +async function displayBundlerError (e: ExecError, folder: WorkspaceFolder): Promise { e.log() - log('Failed to invoke Bundler in the current workspace. After resolving the issue, run the command `Standard Ruby: Start Language Server`') + log(`Failed to invoke Bundler in workspace folder "${folder.name}". After resolving the issue, run the command \`Standard Ruby: Start Language Server\``) if (getConfig('mode') !== 'enableUnconditionally') { - await displayError('Failed to run Bundler while initializing Standard Ruby', ['Show Output']) + await displayError(`Failed to run Bundler in "${folder.name}" while initializing Standard Ruby`, ['Show Output']) } } -async function isValidBundlerProject (): Promise { +async function isValidBundlerProject (folder: WorkspaceFolder): Promise { try { - await promiseExec('bundle list --name-only', { cwd: getCwd() }) + await promiseExec('bundle list --name-only', { cwd: folder.uri.fsPath }) return BundleStatus.valid } catch (e) { if (!(e instanceof ExecError)) return BundleStatus.errored if (e.stderr.startsWith('Could not locate Gemfile')) { - log('No Gemfile found in the current workspace') + log(`No Gemfile found in workspace folder "${folder.name}"`) return BundleStatus.missing } else { - await displayBundlerError(e) + await displayBundlerError(e, folder) return BundleStatus.errored } } } -async function isInBundle (): Promise { +async function isInBundle (folder: WorkspaceFolder): Promise { try { - await promiseExec('bundle show standard', { cwd: getCwd() }) + await promiseExec('bundle show standard', { cwd: folder.uri.fsPath }) return StandardBundleStatus.included } catch (e) { if (!(e instanceof ExecError)) return StandardBundleStatus.errored @@ -156,34 +165,34 @@ async function isInBundle (): Promise { if (e.stderr.startsWith('Could not locate Gemfile') || e.stderr === 'Could not find gem \'standard\'.') { return StandardBundleStatus.excluded } else { - await displayBundlerError(e) + await displayBundlerError(e, folder) return StandardBundleStatus.errored } } } -async function shouldEnableIfBundleIncludesStandard (): Promise { - const standardStatus = await isInBundle() +async function shouldEnableIfBundleIncludesStandard (folder: WorkspaceFolder): Promise { + const standardStatus = await isInBundle(folder) if (standardStatus === StandardBundleStatus.excluded) { - log('Disabling Standard Ruby extension, because standard isn\'t included in the bundle') + log(`Skipping workspace folder "${folder.name}" - standard gem not in bundle`) } return standardStatus === StandardBundleStatus.included } -async function shouldEnableExtension (): Promise { +async function shouldEnableForFolder (folder: WorkspaceFolder): Promise { let bundleStatus switch (getConfig('mode')) { case 'enableUnconditionally': return true case 'enableViaGemfileOrMissingGemfile': - bundleStatus = await isValidBundlerProject() + bundleStatus = await isValidBundlerProject(folder) if (bundleStatus === BundleStatus.valid) { - return await shouldEnableIfBundleIncludesStandard() + return await shouldEnableIfBundleIncludesStandard(folder) } else { return bundleStatus === BundleStatus.missing } case 'enableViaGemfile': - return await shouldEnableIfBundleIncludesStandard() + return await shouldEnableIfBundleIncludesStandard(folder) case 'onlyRunGlobally': return true case 'disable': @@ -200,13 +209,13 @@ function hasCustomizedCommandPath (): boolean { } const variablePattern = /\$\{([^}]*)\}/ -function resolveCommandPath (): string { +function resolveCommandPath (folder: WorkspaceFolder): string { let customCommandPath = getConfig('commandPath') ?? '' for (let match = variablePattern.exec(customCommandPath); match != null; match = variablePattern.exec(customCommandPath)) { switch (match[1]) { case 'cwd': - customCommandPath = customCommandPath.replace(match[0], process.cwd()) + customCommandPath = customCommandPath.replace(match[0], folder.uri.fsPath) break case 'pathSeparator': customCommandPath = customCommandPath.replace(match[0], path.sep) @@ -220,10 +229,10 @@ function resolveCommandPath (): string { return customCommandPath } -async function getCommand (): Promise { +async function getCommand (folder: WorkspaceFolder): Promise { if (hasCustomizedCommandPath()) { - return resolveCommandPath() - } else if (getConfig('mode') !== 'onlyRunGlobally' && await isInBundle() === StandardBundleStatus.included) { + return resolveCommandPath(folder) + } else if (getConfig('mode') !== 'onlyRunGlobally' && await isInBundle(folder) === StandardBundleStatus.included) { return 'bundle exec standardrb' } else { return 'standardrb' @@ -231,57 +240,70 @@ async function getCommand (): Promise { } const requiredGemVersion = '>= 1.24.3' -async function supportedVersionOfStandard (command: string): Promise { +async function supportedVersionOfStandard (command: string, folder: WorkspaceFolder): Promise { try { - const { stdout } = await promiseExec(`${command} -v`) + const { stdout } = await promiseExec(`${command} -v`, { cwd: folder.uri.fsPath }) const version = stdout.trim() if (satisfies(version, requiredGemVersion)) { return true } else { - log('Disabling because the extension does not support this version of the standard gem.') + log(`Disabling for "${folder.name}" - unsupported standard version.`) log(` Version reported by \`${command} -v\`: ${version} (${requiredGemVersion} required)`) - await displayError(`Unsupported standard version: ${version} (${requiredGemVersion} required)`, ['Show Output']) + await displayError(`Unsupported standard version in "${folder.name}": ${version} (${requiredGemVersion} required)`, ['Show Output']) return false } } catch (e) { if (e instanceof ExecError) e.log() - log('Failed to verify the version of standard installed, proceeding anyway…') + log(`Failed to verify the version of standard in "${folder.name}", proceeding anyway…`) return true } } -async function buildExecutable (): Promise { - const command = await getCommand() +async function buildExecutable (folder: WorkspaceFolder): Promise { + const command = await getCommand(folder) if (command == null) { - await displayError('Could not find Standard Ruby executable', ['Show Output', 'View Settings']) - } else if (await supportedVersionOfStandard(command)) { + await displayError(`Could not find Standard Ruby executable for "${folder.name}"`, ['Show Output', 'View Settings']) + } else if (await supportedVersionOfStandard(command, folder)) { const [exe, ...args] = (command).split(' ') return { command: exe, - args: args.concat('--lsp') + args: args.concat('--lsp'), + options: { + cwd: folder.uri.fsPath + } } } } -function buildLanguageClientOptions (): LanguageClientOptions { +function buildLanguageClientOptions (folder: WorkspaceFolder): LanguageClientOptions { + const globPath = normalizePathForGlob(folder.uri.fsPath) + + // Create watchers and register them with the client manager + const watchers = [ + workspace.createFileSystemWatcher(`${globPath}/**/.standard.yml`), + workspace.createFileSystemWatcher(`${globPath}/**/.standard_todo.yml`), + workspace.createFileSystemWatcher(`${globPath}/**/Gemfile.lock`) + ] + clientManager?.registerWatchers(folder, watchers) + + // Get the diagnostic cache for this folder + const diagnosticCache = clientManager?.getDiagnosticCacheForFolder(folder) ?? new Map() + return { documentSelector: [ - { scheme: 'file', language: 'ruby' }, - { scheme: 'file', pattern: '**/Gemfile' } + { scheme: 'file', language: 'ruby', pattern: `${globPath}/**/*` }, + { scheme: 'file', pattern: `${globPath}/**/Gemfile` } ], - diagnosticCollectionName: 'standardRuby', + diagnosticCollectionName: `standardRuby-${folder.name}`, + workspaceFolder: folder, initializationFailedHandler: (error) => { - log(`Language server initialization failed: ${String(error)}`) + log(`Language server initialization failed for "${folder.name}": ${String(error)}`) return false }, revealOutputChannelOn: RevealOutputChannelOn.Never, outputChannel, synchronize: { - fileEvents: [ - workspace.createFileSystemWatcher('**/.standard.yml'), - workspace.createFileSystemWatcher('**/.standard_todo.yml'), - workspace.createFileSystemWatcher('**/Gemfile.lock') - ] + fileEvents: watchers }, middleware: { provideDocumentFormattingEdits: (document, options, token, next): ProviderResult => { @@ -298,11 +320,15 @@ function buildLanguageClientOptions (): LanguageClientOptions { } } -async function createLanguageClient (): Promise { - const run = await buildExecutable() +async function createLanguageClient (folder: WorkspaceFolder): Promise { + const run = await buildExecutable(folder) if (run != null) { - log(`Starting language server: ${run.command} ${run.args?.join(' ') ?? ''}`) - return new LanguageClient('Standard Ruby', { run, debug: run }, buildLanguageClientOptions()) + log(`Starting language server for "${folder.name}": ${run.command} ${run.args?.join(' ') ?? ''} (cwd: ${folder.uri.fsPath})`) + return new LanguageClient( + `Standard Ruby (${folder.name})`, + { run, debug: run }, + buildLanguageClientOptions(folder) + ) } else { return null } @@ -312,7 +338,7 @@ async function displayError (message: string, actions: string[]): Promise const action = await window.showErrorMessage(message, ...actions) switch (action) { case 'Restart': - await restartLanguageServer() + await clientManager?.restartAll() break case 'Show Output': outputChannel?.show() @@ -325,72 +351,25 @@ async function displayError (message: string, actions: string[]): Promise } } -async function syncOpenDocumentsWithLanguageServer (languageClient: LanguageClient): Promise { - for (const textDocument of workspace.textDocuments) { - if (supportedLanguage(textDocument.languageId)) { - await languageClient.sendNotification( - DidOpenTextDocumentNotification.type, - languageClient.code2ProtocolConverter.asOpenTextDocumentParams(textDocument) - ) - } - } -} - async function handleActiveTextEditorChange (editor: TextEditor | undefined): Promise { - if (languageClient == null || editor == null) return - - if (supportedLanguage(editor.document.languageId) && !diagnosticCache.has(editor.document.uri.toString())) { - await languageClient.sendNotification( - DidOpenTextDocumentNotification.type, - languageClient.code2ProtocolConverter.asOpenTextDocumentParams(editor.document) - ) + if (clientManager == null || editor == null) { + updateStatusBar() + return } - updateStatusBar() -} -async function afterStartLanguageServer (languageClient: LanguageClient): Promise { - diagnosticCache = new Map() - await syncOpenDocumentsWithLanguageServer(languageClient) + await clientManager.notifyDocumentOpenIfNeeded(editor.document) updateStatusBar() } -async function startLanguageServer (): Promise { - if (languageClient != null || !(await shouldEnableExtension())) return - - try { - languageClient = await createLanguageClient() - if (languageClient != null) { - await languageClient.start() - await afterStartLanguageServer(languageClient) - } - } catch (error) { - languageClient = null - await displayError( - 'Failed to start Standard Ruby Language Server', ['Restart', 'Show Output'] - ) - } -} - -async function stopLanguageServer (): Promise { - if (languageClient == null) return - - log('Stopping language server...') - await languageClient.stop() - languageClient = null -} - -async function restartLanguageServer (): Promise { - log('Restarting language server...') - await stopLanguageServer() - await startLanguageServer() -} - async function formatAutoFixes (): Promise { const editor = window.activeTextEditor - if (editor == null || languageClient == null || !supportedLanguage(editor.document.languageId)) return + if (editor == null || !supportedLanguage(editor.document.languageId)) return + + const client = clientManager?.getClient(editor.document) + if (client == null) return try { - await languageClient.sendRequest(ExecuteCommandRequest.type, { + await client.sendRequest(ExecuteCommandRequest.type, { command: 'standardRuby.formatAutoFixes', arguments: [{ uri: editor.document.uri.toString(), @@ -414,47 +393,68 @@ function updateStatusBar (): void { if (statusBarItem == null) return const editor = window.activeTextEditor - if (languageClient == null || editor == null || !supportedLanguage(editor.document.languageId)) { + if (clientManager == null || editor == null || !supportedLanguage(editor.document.languageId)) { + statusBarItem.hide() + return + } + + const client = clientManager.getClient(editor.document) + if (client == null) { statusBarItem.hide() + return + } + + const diagnostics = clientManager.getDiagnostics(editor.document) + + if (diagnostics == null) { + statusBarItem.tooltip = 'Standard Ruby' + statusBarItem.text = 'Standard $(ruby)' + statusBarItem.color = undefined + statusBarItem.backgroundColor = undefined } else { - const diagnostics = diagnosticCache.get(editor.document.uri.toString()) - if (diagnostics == null) { - statusBarItem.tooltip = 'Standard Ruby' - statusBarItem.text = 'Standard $(ruby)' - statusBarItem.color = undefined + const errorCount = diagnostics.filter((d) => d.severity === DiagnosticSeverity.Error).length + const warningCount = diagnostics.filter((d) => d.severity === DiagnosticSeverity.Warning).length + const otherCount = diagnostics.filter((d) => + d.severity === DiagnosticSeverity.Information || + d.severity === DiagnosticSeverity.Hint + ).length + if (errorCount > 0) { + statusBarItem.tooltip = `Standard Ruby: ${errorCount === 1 ? '1 error' : `${errorCount} errors`}` + statusBarItem.text = 'Standard $(error)' + statusBarItem.backgroundColor = new ThemeColor('statusBarItem.errorBackground') + } else if (warningCount > 0) { + statusBarItem.tooltip = `Standard Ruby: ${warningCount === 1 ? '1 warning' : `${warningCount} warnings`}` + statusBarItem.text = 'Standard $(warning)' + statusBarItem.backgroundColor = new ThemeColor('statusBarItem.warningBackground') + } else if (otherCount > 0) { + statusBarItem.tooltip = `Standard Ruby: ${otherCount === 1 ? '1 hint' : `${otherCount} issues`}` + statusBarItem.text = 'Standard $(info)' statusBarItem.backgroundColor = undefined } else { - const errorCount = diagnostics.filter((d) => d.severity === DiagnosticSeverity.Error).length - const warningCount = diagnostics.filter((d) => d.severity === DiagnosticSeverity.Warning).length - const otherCount = diagnostics.filter((d) => - d.severity === DiagnosticSeverity.Information || - d.severity === DiagnosticSeverity.Hint - ).length - if (errorCount > 0) { - statusBarItem.tooltip = `Standard Ruby: ${errorCount === 1 ? '1 error' : `${errorCount} errors`}` - statusBarItem.text = 'Standard $(error)' - statusBarItem.backgroundColor = new ThemeColor('statusBarItem.errorBackground') - } else if (warningCount > 0) { - statusBarItem.tooltip = `Standard Ruby: ${warningCount === 1 ? '1 warning' : `${errorCount} warnings`}` - statusBarItem.text = 'Standard $(warning)' - statusBarItem.backgroundColor = new ThemeColor('statusBarItem.warningBackground') - } else if (otherCount > 0) { - statusBarItem.tooltip = `Standard Ruby: ${otherCount === 1 ? '1 hint' : `${otherCount} issues`}` - statusBarItem.text = 'Standard $(info)' - statusBarItem.backgroundColor = undefined - } else { - statusBarItem.tooltip = 'Standard Ruby: No issues!' - statusBarItem.text = 'Standard $(ruby)' - statusBarItem.backgroundColor = undefined - } + statusBarItem.tooltip = 'Standard Ruby: No issues!' + statusBarItem.text = 'Standard $(ruby)' + statusBarItem.backgroundColor = undefined } - statusBarItem.show() } + statusBarItem.show() } export async function activate (context: ExtensionContext): Promise { outputChannel = window.createOutputChannel('Standard Ruby') statusBarItem = createStatusBarItem() + + // Initialize client manager for multi-root workspace support + clientManager = new ClientManager({ + log, + createClient: createLanguageClient, + shouldEnableForFolder, + onError: async (message, _folder) => { + await displayError(message, ['Restart', 'Show Output']) + }, + onStatusUpdate: updateStatusBar, + supportedLanguage + }) + window.onDidChangeActiveTextEditor(handleActiveTextEditorChange) context.subscriptions.push( outputChannel, @@ -463,9 +463,10 @@ export async function activate (context: ExtensionContext): Promise { ...registerWorkspaceListeners() ) - await startLanguageServer() + log('Activating Standard Ruby extension with multi-root workspace support') + await clientManager.startAll() } export async function deactivate (): Promise { - await stopLanguageServer() + await clientManager?.stopAll() } diff --git a/src/test/suite/clientManager.test.ts b/src/test/suite/clientManager.test.ts new file mode 100644 index 0000000..d9396bf --- /dev/null +++ b/src/test/suite/clientManager.test.ts @@ -0,0 +1,240 @@ +import * as assert from 'assert' +import { Uri } from 'vscode' +import { ClientManager, ClientManagerOptions, normalizePathForGlob } from '../../clientManager' + +function createMockFolder (name: string, fsPath: string): any { + return { name, uri: Uri.file(fsPath), index: 0 } +} + +function createMockClient (overrides: any = {}): any { + return { + start: async () => {}, + stop: async () => {}, + sendNotification: async () => {}, + code2ProtocolConverter: { + asOpenTextDocumentParams: (doc: any) => ({ textDocument: { uri: doc.uri.toString() } }) + }, + ...overrides + } +} + +function createOptions (overrides: Partial = {}): ClientManagerOptions { + return { + log: () => {}, + createClient: async () => createMockClient(), + shouldEnableForFolder: async () => true, + onError: async () => {}, + onStatusUpdate: () => {}, + supportedLanguage: (id) => id === 'ruby', + ...overrides + } +} + +suite('ClientManager', () => { + suite('normalizePathForGlob', () => { + test('converts Windows backslashes to forward slashes', async () => { + assert.strictEqual( + normalizePathForGlob('C:\\Users\\dev\\project'), + 'C:/Users/dev/project' + ) + }) + + test('leaves Unix paths unchanged', async () => { + assert.strictEqual( + normalizePathForGlob('/Users/dev/project'), + '/Users/dev/project' + ) + }) + + test('handles mixed separators', async () => { + assert.strictEqual( + normalizePathForGlob('C:\\Users/dev\\project'), + 'C:/Users/dev/project' + ) + }) + }) + + suite('client lifecycle', () => { + test('startForFolder creates a client for the folder', async () => { + const folder = createMockFolder('my-app', '/workspace/my-app') + let clientCreated = false + + const manager = new ClientManager(createOptions({ + createClient: async () => { + clientCreated = true + return createMockClient() + } + })) + await manager.startForFolder(folder) + + assert.strictEqual(clientCreated, true) + assert.strictEqual(manager.size, 1) + }) + + test('startForFolder skips when shouldEnableForFolder returns false', async () => { + const folder = createMockFolder('my-app', '/workspace/my-app') + let clientCreated = false + + const manager = new ClientManager(createOptions({ + createClient: async () => { + clientCreated = true + return createMockClient() + }, + shouldEnableForFolder: async () => false + })) + await manager.startForFolder(folder) + + assert.strictEqual(clientCreated, false) + assert.strictEqual(manager.size, 0) + }) + + test('startForFolder does not create duplicate clients', async () => { + const folder = createMockFolder('my-app', '/workspace/my-app') + let createCount = 0 + + const manager = new ClientManager(createOptions({ + createClient: async () => { + createCount++ + return createMockClient() + } + })) + await manager.startForFolder(folder) + await manager.startForFolder(folder) + + assert.strictEqual(createCount, 1) + assert.strictEqual(manager.size, 1) + }) + + test('stopForFolder removes the client', async () => { + const folder = createMockFolder('my-app', '/workspace/my-app') + let stopCalled = false + + const manager = new ClientManager(createOptions({ + createClient: async () => createMockClient({ stop: async () => { stopCalled = true } }) + })) + await manager.startForFolder(folder) + assert.strictEqual(manager.size, 1) + + await manager.stopForFolder(folder) + assert.strictEqual(stopCalled, true) + assert.strictEqual(manager.size, 0) + }) + }) + + suite('race condition prevention', () => { + test('concurrent startForFolder calls only create one client', async () => { + const folder = createMockFolder('my-app', '/workspace/my-app') + let createCount = 0 + + const manager = new ClientManager(createOptions({ + createClient: async () => { + createCount++ + await new Promise(resolve => setTimeout(resolve, 10)) + return createMockClient() + } + })) + + await Promise.all([ + manager.startForFolder(folder), + manager.startForFolder(folder) + ]) + + assert.strictEqual(createCount, 1) + assert.strictEqual(manager.size, 1) + }) + }) + + suite('multiple folders', () => { + test('manages separate clients for different folders', async () => { + const folder1 = createMockFolder('rails-app', '/workspace/rails-app') + const folder2 = createMockFolder('cli-tool', '/workspace/cli-tool') + let clientCount = 0 + + const manager = new ClientManager(createOptions({ + createClient: async () => { + clientCount++ + return createMockClient() + } + })) + await manager.startForFolder(folder1) + await manager.startForFolder(folder2) + + assert.strictEqual(manager.size, 2) + assert.strictEqual(clientCount, 2) + }) + + test('stopAll stops all clients', async () => { + const folder1 = createMockFolder('rails-app', '/workspace/rails-app') + const folder2 = createMockFolder('cli-tool', '/workspace/cli-tool') + let stopCount = 0 + + const manager = new ClientManager(createOptions({ + createClient: async () => createMockClient({ stop: async () => { stopCount++ } }) + })) + await manager.startForFolder(folder1) + await manager.startForFolder(folder2) + assert.strictEqual(manager.size, 2) + + await manager.stopAll() + assert.strictEqual(stopCount, 2) + assert.strictEqual(manager.size, 0) + }) + }) + + suite('diagnostic cache', () => { + test('getDiagnosticCacheForFolder returns consistent cache', async () => { + const folder = createMockFolder('my-app', '/workspace/my-app') + const manager = new ClientManager(createOptions()) + + const cache1 = manager.getDiagnosticCacheForFolder(folder) + const cache2 = manager.getDiagnosticCacheForFolder(folder) + + assert.strictEqual(cache1, cache2) + }) + }) + + suite('watcher cleanup', () => { + test('stopForFolder disposes watchers', async () => { + const folder = createMockFolder('my-app', '/workspace/my-app') + let watcherDisposed = false + + const manager = new ClientManager(createOptions()) + await manager.startForFolder(folder) + manager.registerWatchers(folder, [{ dispose: () => { watcherDisposed = true } }]) + + await manager.stopForFolder(folder) + assert.strictEqual(watcherDisposed, true) + }) + }) + + suite('error handling', () => { + test('startForFolder calls onError when client creation fails', async () => { + const folder = createMockFolder('my-app', '/workspace/my-app') + let errorMessage = '' + + const manager = new ClientManager(createOptions({ + createClient: async () => { throw new Error('Connection failed') }, + onError: async (message) => { errorMessage = message } + })) + await manager.startForFolder(folder) + + assert.ok(errorMessage.includes('my-app')) + assert.strictEqual(manager.size, 0) + }) + + test('startForFolder cleans up on failure', async () => { + const folder = createMockFolder('my-app', '/workspace/my-app') + let watcherDisposed = false + + const manager = new ClientManager(createOptions({ + createClient: async () => { throw new Error('Connection failed') } + })) + manager.registerWatchers(folder, [{ dispose: () => { watcherDisposed = true } }]) + + await manager.startForFolder(folder) + + assert.strictEqual(watcherDisposed, true) + assert.strictEqual(manager.size, 0) + }) + }) +}) diff --git a/src/test/suite/index.test.ts b/src/test/suite/index.test.ts index f075dcb..83ba736 100644 --- a/src/test/suite/index.test.ts +++ b/src/test/suite/index.test.ts @@ -25,20 +25,22 @@ suite('Standard Ruby', () => { suite('lifecycle commands', () => { test('start', async () => { await auto.start() - assert.notEqual(extension.languageClient, null) - assert.equal(extension.languageClient?.state, State.Running) + const client = extension.getLanguageClient() + assert.notEqual(client, null) + assert.equal(client?.state, State.Running) }) test('stop', async () => { await auto.start() await auto.stop() - assert.equal(extension.languageClient, null) + assert.equal(extension.languageClients.size, 0) }) test('restart', async () => { await auto.restart() - assert.notEqual(extension.languageClient, null) - assert.equal(extension.languageClient?.state, State.Running) + const client = extension.getLanguageClient() + assert.notEqual(client, null) + assert.equal(client?.state, State.Running) }) }) diff --git a/test-fixtures/multi-root-demo/.gitignore b/test-fixtures/multi-root-demo/.gitignore new file mode 100644 index 0000000..c7798fd --- /dev/null +++ b/test-fixtures/multi-root-demo/.gitignore @@ -0,0 +1,2 @@ +# Auto-generated by Ruby LSP +.ruby-lsp/ diff --git a/test-fixtures/multi-root-demo/README.md b/test-fixtures/multi-root-demo/README.md new file mode 100644 index 0000000..e6336c2 --- /dev/null +++ b/test-fixtures/multi-root-demo/README.md @@ -0,0 +1,87 @@ +# Multi-Root Workspace Test Fixture + +This fixture demonstrates and tests multi-root workspace support for the Standard Ruby extension. + +## The Problem This Solves + +Without multi-root support, the extension uses the **first** workspace folder's Standard Ruby configuration for **all** files. This causes false positives when different folders have different configurations. + +In this example: +- `app-rails/` uses `standard-rails` (which includes Rails-specific cops like `Rails/Output`) +- `ruby-lib/` uses plain `standard` (no Rails cops) + +The Rails folder is named `app-rails` so it comes first alphabetically. This is important because without multi-root support, the **first** folder's config is used for all files. + +## How to Test + +### Setup + +Install dependencies in both folders: + +```bash +cd test-fixtures/multi-root-demo +cd app-rails && bundle install +cd ../ruby-lib && bundle install +``` + +### Step 1: See the Bug (Published Extension) + +First, verify the bug exists with the current published extension: + +1. Open this workspace in VS Code (not Extension Development Host): + - File > Open Workspace from File... + - Select `test-fixtures/multi-root-demo/multi-root-demo.code-workspace` + +2. Open `ruby-lib/lib/string_utils.rb` + +3. You should see `Rails/Output: Do not write to stdout` errors on the `puts` statement - this is the bug. The Rails config from `app-rails` is being incorrectly applied to `ruby-lib`. + +![Rails/Output error shown incorrectly on ruby-lib](rails-output-error.png) + +### Step 2: Verify the Fix (Extension Development Host) + +Now verify the fix works: + +1. Open the vscode-standard-ruby project in VS Code +2. Press F5 to launch the Extension Development Host +3. In the Extension Development Host, open this workspace: + - File > Open Workspace from File... + - Select `test-fixtures/multi-root-demo/multi-root-demo.code-workspace` + +4. Check the Output panel (View > Output > Standard Ruby): + - You should see TWO language servers starting: + ``` + Starting language server for "app-rails": ... + Starting language server for "ruby-lib": ... + ``` + +5. Open `ruby-lib/lib/string_utils.rb`: + - The `puts` statement should have NO errors + - Each folder now gets its own language server with its own config + +### Optional: Test Folder Add/Remove + +- Remove one folder from the workspace +- Verify its language server stops in the Output panel +- Add it back +- Verify its language server restarts + +## File Structure + +``` +multi-root-demo/ +├── multi-root-demo.code-workspace # VS Code workspace file +├── README.md # This file +├── app-rails/ +│ ├── .standard.yml # Uses standard-rails plugin +│ ├── Gemfile +│ └── app/controllers/users_controller.rb +└── ruby-lib/ + ├── .standard.yml # Plain standard (no Rails) + ├── Gemfile + └── lib/string_utils.rb # Has puts statement (valid for a lib) +``` + +## Note on File Location + +The test file must be in `lib/`, `app/`, `config/`, or `db/` for the `Rails/Output` cop to check it. Files in other directories (like `bin/`) are not checked by this cop, so you won't be able to reproduce the issue there. diff --git a/test-fixtures/multi-root-demo/app-rails/.standard.yml b/test-fixtures/multi-root-demo/app-rails/.standard.yml new file mode 100644 index 0000000..fcd095b --- /dev/null +++ b/test-fixtures/multi-root-demo/app-rails/.standard.yml @@ -0,0 +1,2 @@ +plugins: + - standard-rails diff --git a/test-fixtures/multi-root-demo/app-rails/Gemfile b/test-fixtures/multi-root-demo/app-rails/Gemfile new file mode 100644 index 0000000..201b5ae --- /dev/null +++ b/test-fixtures/multi-root-demo/app-rails/Gemfile @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "rails" + +gem "standard", require: false +gem "standard-rails", require: false diff --git a/test-fixtures/multi-root-demo/app-rails/Gemfile.lock b/test-fixtures/multi-root-demo/app-rails/Gemfile.lock new file mode 100644 index 0000000..d9c5ea1 --- /dev/null +++ b/test-fixtures/multi-root-demo/app-rails/Gemfile.lock @@ -0,0 +1,339 @@ +GEM + remote: https://rubygems.org/ + specs: + action_text-trix (2.1.16) + railties + actioncable (8.1.2) + actionpack (= 8.1.2) + activesupport (= 8.1.2) + nio4r (~> 2.0) + websocket-driver (>= 0.6.1) + zeitwerk (~> 2.6) + actionmailbox (8.1.2) + actionpack (= 8.1.2) + activejob (= 8.1.2) + activerecord (= 8.1.2) + activestorage (= 8.1.2) + activesupport (= 8.1.2) + mail (>= 2.8.0) + actionmailer (8.1.2) + actionpack (= 8.1.2) + actionview (= 8.1.2) + activejob (= 8.1.2) + activesupport (= 8.1.2) + mail (>= 2.8.0) + rails-dom-testing (~> 2.2) + actionpack (8.1.2) + actionview (= 8.1.2) + activesupport (= 8.1.2) + nokogiri (>= 1.8.5) + rack (>= 2.2.4) + rack-session (>= 1.0.1) + rack-test (>= 0.6.3) + rails-dom-testing (~> 2.2) + rails-html-sanitizer (~> 1.6) + useragent (~> 0.16) + actiontext (8.1.2) + action_text-trix (~> 2.1.15) + actionpack (= 8.1.2) + activerecord (= 8.1.2) + activestorage (= 8.1.2) + activesupport (= 8.1.2) + globalid (>= 0.6.0) + nokogiri (>= 1.8.5) + actionview (8.1.2) + activesupport (= 8.1.2) + builder (~> 3.1) + erubi (~> 1.11) + rails-dom-testing (~> 2.2) + rails-html-sanitizer (~> 1.6) + activejob (8.1.2) + activesupport (= 8.1.2) + globalid (>= 0.3.6) + activemodel (8.1.2) + activesupport (= 8.1.2) + activerecord (8.1.2) + activemodel (= 8.1.2) + activesupport (= 8.1.2) + timeout (>= 0.4.0) + activestorage (8.1.2) + actionpack (= 8.1.2) + activejob (= 8.1.2) + activerecord (= 8.1.2) + activesupport (= 8.1.2) + marcel (~> 1.0) + activesupport (8.1.2) + base64 + bigdecimal + concurrent-ruby (~> 1.0, >= 1.3.1) + connection_pool (>= 2.2.5) + drb + i18n (>= 1.6, < 2) + json + logger (>= 1.4.2) + minitest (>= 5.1) + securerandom (>= 0.3) + tzinfo (~> 2.0, >= 2.0.5) + uri (>= 0.13.1) + ast (2.4.3) + base64 (0.3.0) + bigdecimal (4.0.1) + builder (3.3.0) + concurrent-ruby (1.3.6) + connection_pool (3.0.2) + crass (1.0.6) + date (3.5.1) + drb (2.2.3) + erb (6.0.1) + erubi (1.13.1) + globalid (1.3.0) + activesupport (>= 6.1) + i18n (1.14.8) + concurrent-ruby (~> 1.0) + io-console (0.8.2) + irb (1.16.0) + pp (>= 0.6.0) + rdoc (>= 4.0.0) + reline (>= 0.4.2) + json (2.18.0) + language_server-protocol (3.17.0.5) + lint_roller (1.1.0) + logger (1.7.0) + loofah (2.25.0) + crass (~> 1.0.2) + nokogiri (>= 1.12.0) + mail (2.9.0) + logger + mini_mime (>= 0.1.1) + net-imap + net-pop + net-smtp + marcel (1.1.0) + mini_mime (1.1.5) + minitest (6.0.1) + prism (~> 1.5) + net-imap (0.6.2) + date + net-protocol + net-pop (0.1.2) + net-protocol + net-protocol (0.2.2) + timeout + net-smtp (0.5.1) + net-protocol + nio4r (2.7.5) + nokogiri (1.19.0-arm64-darwin) + racc (~> 1.4) + parallel (1.27.0) + parser (3.3.10.1) + ast (~> 2.4.1) + racc + pp (0.6.3) + prettyprint + prettyprint (0.2.0) + prism (1.8.0) + psych (5.3.1) + date + stringio + racc (1.8.1) + rack (3.2.4) + rack-session (2.1.1) + base64 (>= 0.1.0) + rack (>= 3.0.0) + rack-test (2.2.0) + rack (>= 1.3) + rackup (2.3.1) + rack (>= 3) + rails (8.1.2) + actioncable (= 8.1.2) + actionmailbox (= 8.1.2) + actionmailer (= 8.1.2) + actionpack (= 8.1.2) + actiontext (= 8.1.2) + actionview (= 8.1.2) + activejob (= 8.1.2) + activemodel (= 8.1.2) + activerecord (= 8.1.2) + activestorage (= 8.1.2) + activesupport (= 8.1.2) + bundler (>= 1.15.0) + railties (= 8.1.2) + rails-dom-testing (2.3.0) + activesupport (>= 5.0.0) + minitest + nokogiri (>= 1.6) + rails-html-sanitizer (1.6.2) + loofah (~> 2.21) + nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0) + railties (8.1.2) + actionpack (= 8.1.2) + activesupport (= 8.1.2) + irb (~> 1.13) + rackup (>= 1.0.0) + rake (>= 12.2) + thor (~> 1.0, >= 1.2.2) + tsort (>= 0.2) + zeitwerk (~> 2.6) + rainbow (3.1.1) + rake (13.3.1) + rdoc (7.1.0) + erb + psych (>= 4.0.0) + tsort + regexp_parser (2.11.3) + reline (0.6.3) + io-console (~> 0.5) + rubocop (1.82.1) + json (~> 2.3) + language_server-protocol (~> 3.17.0.2) + lint_roller (~> 1.1.0) + parallel (~> 1.10) + parser (>= 3.3.0.2) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 2.9.3, < 3.0) + rubocop-ast (>= 1.48.0, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 2.4.0, < 4.0) + rubocop-ast (1.49.0) + parser (>= 3.3.7.2) + prism (~> 1.7) + rubocop-performance (1.26.1) + lint_roller (~> 1.1) + rubocop (>= 1.75.0, < 2.0) + rubocop-ast (>= 1.47.1, < 2.0) + rubocop-rails (2.34.3) + activesupport (>= 4.2.0) + lint_roller (~> 1.1) + rack (>= 1.1) + rubocop (>= 1.75.0, < 2.0) + rubocop-ast (>= 1.44.0, < 2.0) + ruby-progressbar (1.13.0) + securerandom (0.4.1) + standard (1.53.0) + language_server-protocol (~> 3.17.0.2) + lint_roller (~> 1.0) + rubocop (~> 1.82.0) + standard-custom (~> 1.0.0) + standard-performance (~> 1.8) + standard-custom (1.0.2) + lint_roller (~> 1.0) + rubocop (~> 1.50) + standard-performance (1.9.0) + lint_roller (~> 1.1) + rubocop-performance (~> 1.26.0) + standard-rails (1.6.0) + lint_roller (~> 1.0) + rubocop-rails (~> 2.34.0) + stringio (3.2.0) + thor (1.5.0) + timeout (0.6.0) + tsort (0.2.0) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) + unicode-display_width (3.2.0) + unicode-emoji (~> 4.1) + unicode-emoji (4.2.0) + uri (1.1.1) + useragent (0.16.11) + websocket-driver (0.8.0) + base64 + websocket-extensions (>= 0.1.0) + websocket-extensions (0.1.5) + zeitwerk (2.7.4) + +PLATFORMS + arm64-darwin + +DEPENDENCIES + rails + standard + standard-rails + +CHECKSUMS + action_text-trix (2.1.16) sha256=f645a2c21821b8449fd1d6770708f4031c91a2eedf9ef476e9be93c64e703a8a + actioncable (8.1.2) sha256=dc31efc34cca9cdefc5c691ddb8b4b214c0ea5cd1372108cbc1377767fb91969 + actionmailbox (8.1.2) sha256=058b2fb1980e5d5a894f675475fcfa45c62631103d5a2596d9610ec81581889b + actionmailer (8.1.2) sha256=f4c1d2060f653bfe908aa7fdc5a61c0e5279670de992146582f2e36f8b9175e9 + actionpack (8.1.2) sha256=ced74147a1f0daafaa4bab7f677513fd4d3add574c7839958f7b4f1de44f8423 + actiontext (8.1.2) sha256=0bf57da22a9c19d970779c3ce24a56be31b51c7640f2763ec64aa72e358d2d2d + actionview (8.1.2) sha256=80455b2588911c9b72cec22d240edacb7c150e800ef2234821269b2b2c3e2e5b + activejob (8.1.2) sha256=908dab3713b101859536375819f4156b07bdf4c232cc645e7538adb9e302f825 + activemodel (8.1.2) sha256=e21358c11ce68aed3f9838b7e464977bc007b4446c6e4059781e1d5c03bcf33e + activerecord (8.1.2) sha256=acfbe0cadfcc50fa208011fe6f4eb01cae682ebae0ef57145ba45380c74bcc44 + activestorage (8.1.2) sha256=8a63a48c3999caeee26a59441f813f94681fc35cc41aba7ce1f836add04fba76 + activesupport (8.1.2) sha256=88842578ccd0d40f658289b0e8c842acfe9af751afee2e0744a7873f50b6fdae + ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 + base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b + bigdecimal (4.0.1) sha256=8b07d3d065a9f921c80ceaea7c9d4ae596697295b584c296fe599dd0ad01c4a7 + builder (3.3.0) sha256=497918d2f9dca528fdca4b88d84e4ef4387256d984b8154e9d5d3fe5a9c8835f + concurrent-ruby (1.3.6) sha256=6b56837e1e7e5292f9864f34b69c5a2cbc75c0cf5338f1ce9903d10fa762d5ab + connection_pool (3.0.2) sha256=33fff5ba71a12d2aa26cb72b1db8bba2a1a01823559fb01d29eb74c286e62e0a + crass (1.0.6) sha256=dc516022a56e7b3b156099abc81b6d2b08ea1ed12676ac7a5657617f012bd45d + date (3.5.1) sha256=750d06384d7b9c15d562c76291407d89e368dda4d4fff957eb94962d325a0dc0 + drb (2.2.3) sha256=0b00d6fdb50995fe4a45dea13663493c841112e4068656854646f418fda13373 + erb (6.0.1) sha256=28ecdd99c5472aebd5674d6061e3c6b0a45c049578b071e5a52c2a7f13c197e5 + erubi (1.13.1) sha256=a082103b0885dbc5ecf1172fede897f9ebdb745a4b97a5e8dc63953db1ee4ad9 + globalid (1.3.0) sha256=05c639ad6eb4594522a0b07983022f04aa7254626ab69445a0e493aa3786ff11 + i18n (1.14.8) sha256=285778639134865c5e0f6269e0b818256017e8cde89993fdfcbfb64d088824a5 + io-console (0.8.2) sha256=d6e3ae7a7cc7574f4b8893b4fca2162e57a825b223a177b7afa236c5ef9814cc + irb (1.16.0) sha256=2abe56c9ac947cdcb2f150572904ba798c1e93c890c256f8429981a7675b0806 + json (2.18.0) sha256=b10506aee4183f5cf49e0efc48073d7b75843ce3782c68dbeb763351c08fd505 + language_server-protocol (3.17.0.5) sha256=fd1e39a51a28bf3eec959379985a72e296e9f9acfce46f6a79d31ca8760803cc + lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87 + logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203 + loofah (2.25.0) sha256=df5ed7ac3bac6a4ec802df3877ee5cc86d027299f8952e6243b3dac446b060e6 + mail (2.9.0) sha256=6fa6673ecd71c60c2d996260f9ee3dd387d4673b8169b502134659ece6d34941 + marcel (1.1.0) sha256=fdcfcfa33cc52e93c4308d40e4090a5d4ea279e160a7f6af988260fa970e0bee + mini_mime (1.1.5) sha256=8681b7e2e4215f2a159f9400b5816d85e9d8c6c6b491e96a12797e798f8bccef + minitest (6.0.1) sha256=7854c74f48e2e975969062833adc4013f249a4b212f5e7b9d5c040bf838d54bb + net-imap (0.6.2) sha256=08caacad486853c61676cca0c0c47df93db02abc4a8239a8b67eb0981428acc6 + net-pop (0.1.2) sha256=848b4e982013c15b2f0382792268763b748cce91c9e91e36b0f27ed26420dff3 + net-protocol (0.2.2) sha256=aa73e0cba6a125369de9837b8d8ef82a61849360eba0521900e2c3713aa162a8 + net-smtp (0.5.1) sha256=ed96a0af63c524fceb4b29b0d352195c30d82dd916a42f03c62a3a70e5b70736 + nio4r (2.7.5) sha256=6c90168e48fb5f8e768419c93abb94ba2b892a1d0602cb06eef16d8b7df1dca1 + nokogiri (1.19.0-arm64-darwin) sha256=0811dfd936d5f6dd3f6d32ef790568bf29b2b7bead9ba68866847b33c9cf5810 + parallel (1.27.0) sha256=4ac151e1806b755fb4e2dc2332cbf0e54f2e24ba821ff2d3dcf86bf6dc4ae130 + parser (3.3.10.1) sha256=06f6a725d2cd91e5e7f2b7c32ba143631e1f7c8ae2fb918fc4cebec187e6a688 + pp (0.6.3) sha256=2951d514450b93ccfeb1df7d021cae0da16e0a7f95ee1e2273719669d0ab9df6 + prettyprint (0.2.0) sha256=2bc9e15581a94742064a3cc8b0fb9d45aae3d03a1baa6ef80922627a0766f193 + prism (1.8.0) sha256=84453a16ef5530ea62c5f03ec16b52a459575ad4e7b9c2b360fd8ce2c39c1254 + psych (5.3.1) sha256=eb7a57cef10c9d70173ff74e739d843ac3b2c019a003de48447b2963d81b1974 + racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f + rack (3.2.4) sha256=5d74b6f75082a643f43c1e76b419c40f0e5527fcfee1e669ac1e6b73c0ccb6f6 + rack-session (2.1.1) sha256=0b6dc07dea7e4b583f58a48e8b806d4c9f1c6c9214ebc202ec94562cbea2e4e9 + rack-test (2.2.0) sha256=005a36692c306ac0b4a9350355ee080fd09ddef1148a5f8b2ac636c720f5c463 + rackup (2.3.1) sha256=6c79c26753778e90983761d677a48937ee3192b3ffef6bc963c0950f94688868 + rails (8.1.2) sha256=5069061b23dfa8706b9f0159ae8b9d35727359103178a26962b868a680ba7d95 + rails-dom-testing (2.3.0) sha256=8acc7953a7b911ca44588bf08737bc16719f431a1cc3091a292bca7317925c1d + rails-html-sanitizer (1.6.2) sha256=35fce2ca8242da8775c83b6ba9c1bcaad6751d9eb73c1abaa8403475ab89a560 + railties (8.1.2) sha256=1289ece76b4f7668fc46d07e55cc992b5b8751f2ad85548b7da351b8c59f8055 + rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a + rake (13.3.1) sha256=8c9e89d09f66a26a01264e7e3480ec0607f0c497a861ef16063604b1b08eb19c + rdoc (7.1.0) sha256=494899df0706c178596ca6e1d50f1b7eb285a9b2aae715be5abd742734f17363 + regexp_parser (2.11.3) sha256=ca13f381a173b7a93450e53459075c9b76a10433caadcb2f1180f2c741fc55a4 + reline (0.6.3) sha256=1198b04973565b36ec0f11542ab3f5cfeeec34823f4e54cebde90968092b1835 + rubocop (1.82.1) sha256=09f1a6a654a960eda767aebea33e47603080f8e9c9a3f019bf9b94c9cab5e273 + rubocop-ast (1.49.0) sha256=49c3676d3123a0923d333e20c6c2dbaaae2d2287b475273fddee0c61da9f71fd + rubocop-performance (1.26.1) sha256=cd19b936ff196df85829d264b522fd4f98b6c89ad271fa52744a8c11b8f71834 + rubocop-rails (2.34.3) sha256=10d37989024865ecda8199f311f3faca990143fbac967de943f88aca11eb9ad2 + ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 + securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1 + standard (1.53.0) sha256=f3c9493385db7079d0abce6f7582f553122156997b81258cd361d3480eeacf9c + standard-custom (1.0.2) sha256=424adc84179a074f1a2a309bb9cf7cd6bfdb2b6541f20c6bf9436c0ba22a652b + standard-performance (1.9.0) sha256=49483d31be448292951d80e5e67cdcb576c2502103c7b40aec6f1b6e9c88e3f2 + standard-rails (1.6.0) sha256=8f1d19a402491901ee8148adb431682012838a73bb7d3b0e95aa339ea872497a + stringio (3.2.0) sha256=c37cb2e58b4ffbd33fe5cd948c05934af997b36e0b6ca6fdf43afa234cf222e1 + thor (1.5.0) sha256=e3a9e55fe857e44859ce104a84675ab6e8cd59c650a49106a05f55f136425e73 + timeout (0.6.0) sha256=6d722ad619f96ee383a0c557ec6eb8c4ecb08af3af62098a0be5057bf00de1af + tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f + tzinfo (2.0.6) sha256=8daf828cc77bcf7d63b0e3bdb6caa47e2272dcfaf4fbfe46f8c3a9df087a829b + unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42 + unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f + uri (1.1.1) sha256=379fa58d27ffb1387eaada68c749d1426738bd0f654d812fcc07e7568f5c57c6 + useragent (0.16.11) sha256=700e6413ad4bb954bb63547fa098dddf7b0ebe75b40cc6f93b8d54255b173844 + websocket-driver (0.8.0) sha256=ed0dba4b943c22f17f9a734817e808bc84cdce6a7e22045f5315aa57676d4962 + websocket-extensions (0.1.5) sha256=1c6ba63092cda343eb53fc657110c71c754c56484aad42578495227d717a8241 + zeitwerk (2.7.4) sha256=2bef90f356bdafe9a6c2bd32bcd804f83a4f9b8bc27f3600fff051eb3edcec8b + +BUNDLED WITH + 4.0.4 diff --git a/test-fixtures/multi-root-demo/app-rails/app/controllers/users_controller.rb b/test-fixtures/multi-root-demo/app-rails/app/controllers/users_controller.rb new file mode 100644 index 0000000..f2e631e --- /dev/null +++ b/test-fixtures/multi-root-demo/app-rails/app/controllers/users_controller.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +class UsersController < ApplicationController + def index + @users = User.all + end + + def show + @user = User.find(params[:id]) + end +end diff --git a/test-fixtures/multi-root-demo/multi-root-demo.code-workspace b/test-fixtures/multi-root-demo/multi-root-demo.code-workspace new file mode 100644 index 0000000..365c83b --- /dev/null +++ b/test-fixtures/multi-root-demo/multi-root-demo.code-workspace @@ -0,0 +1,60 @@ +{ + "folders": [ + { + "name": "app-rails", + "path": "app-rails" + }, + { + "name": "ruby-lib", + "path": "ruby-lib" + } + ], + + "settings": { + // Ruby Formatting + // Using Standard Ruby extension for formatting + "[ruby]": { + "editor.formatOnSave": true, + "editor.defaultFormatter": "testdouble.vscode-standard-ruby" + }, + + // Gemfile Formatting + "[Gemfile]": { + "editor.formatOnSave": true + }, + + // Ruby LSP Configuration + // Tells Ruby LSP to use Standard for diagnostics/linting + "rubyLsp.formatter": "standard", + "rubyLsp.linters": ["standard"], + + // Enable Ruby LSP IDE features + // (diagnostics and formatting intentionally disabled) + "rubyLsp.enabledFeatures": { + "codeActions": true, + "diagnostics": false, + "documentHighlights": true, + "documentLink": true, + "documentSymbols": true, + "foldingRanges": true, + "formatting": false, + "hover": true, + "inlayHint": true, + "onTypeFormatting": true, + "selectionRanges": true, + "semanticHighlighting": true, + "completion": true, + "codeLens": true, + "definition": true, + "workspaceSymbol": true, + "signatureHelp": true + } + }, + + "extensions": { + "recommendations": [ + "shopify.ruby-lsp", + "testdouble.vscode-standard-ruby" + ] + } +} diff --git a/test-fixtures/multi-root-demo/rails-output-error.png b/test-fixtures/multi-root-demo/rails-output-error.png new file mode 100644 index 0000000000000000000000000000000000000000..188f8ea4875ff9a11fac739ce88281dbb83d6d98 GIT binary patch literal 131629 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

&S$iOv5cjCZB~70RKRTWio<<+<2$IMnM) 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

2&;Bf-9-(s~RB$eh2IDqiNz#di{j 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 J+t@Ake*o!gYhM5W literal 0 HcmV?d00001 diff --git a/test-fixtures/multi-root-demo/ruby-lib/.standard.yml b/test-fixtures/multi-root-demo/ruby-lib/.standard.yml new file mode 100644 index 0000000..081ed83 --- /dev/null +++ b/test-fixtures/multi-root-demo/ruby-lib/.standard.yml @@ -0,0 +1,3 @@ +# https://github.com/standardrb/standard +# No plugins - this is a Ruby library, not Rails +plugins: [] diff --git a/test-fixtures/multi-root-demo/ruby-lib/Gemfile b/test-fixtures/multi-root-demo/ruby-lib/Gemfile new file mode 100644 index 0000000..13179d7 --- /dev/null +++ b/test-fixtures/multi-root-demo/ruby-lib/Gemfile @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +source "https://rubygems.org" + +gem "standard", require: false diff --git a/test-fixtures/multi-root-demo/ruby-lib/Gemfile.lock b/test-fixtures/multi-root-demo/ruby-lib/Gemfile.lock new file mode 100644 index 0000000..df88e1b --- /dev/null +++ b/test-fixtures/multi-root-demo/ruby-lib/Gemfile.lock @@ -0,0 +1,80 @@ +GEM + remote: https://rubygems.org/ + specs: + ast (2.4.3) + json (2.18.0) + language_server-protocol (3.17.0.5) + lint_roller (1.1.0) + parallel (1.27.0) + parser (3.3.10.1) + ast (~> 2.4.1) + racc + prism (1.8.0) + racc (1.8.1) + rainbow (3.1.1) + regexp_parser (2.11.3) + rubocop (1.82.1) + json (~> 2.3) + language_server-protocol (~> 3.17.0.2) + lint_roller (~> 1.1.0) + parallel (~> 1.10) + parser (>= 3.3.0.2) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 2.9.3, < 3.0) + rubocop-ast (>= 1.48.0, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 2.4.0, < 4.0) + rubocop-ast (1.49.0) + parser (>= 3.3.7.2) + prism (~> 1.7) + rubocop-performance (1.26.1) + lint_roller (~> 1.1) + rubocop (>= 1.75.0, < 2.0) + rubocop-ast (>= 1.47.1, < 2.0) + ruby-progressbar (1.13.0) + standard (1.53.0) + language_server-protocol (~> 3.17.0.2) + lint_roller (~> 1.0) + rubocop (~> 1.82.0) + standard-custom (~> 1.0.0) + standard-performance (~> 1.8) + standard-custom (1.0.2) + lint_roller (~> 1.0) + rubocop (~> 1.50) + standard-performance (1.9.0) + lint_roller (~> 1.1) + rubocop-performance (~> 1.26.0) + unicode-display_width (3.2.0) + unicode-emoji (~> 4.1) + unicode-emoji (4.2.0) + +PLATFORMS + arm64-darwin-25 + ruby + +DEPENDENCIES + standard + +CHECKSUMS + ast (2.4.3) sha256=954615157c1d6a382bc27d690d973195e79db7f55e9765ac7c481c60bdb4d383 + json (2.18.0) sha256=b10506aee4183f5cf49e0efc48073d7b75843ce3782c68dbeb763351c08fd505 + language_server-protocol (3.17.0.5) sha256=fd1e39a51a28bf3eec959379985a72e296e9f9acfce46f6a79d31ca8760803cc + lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87 + parallel (1.27.0) sha256=4ac151e1806b755fb4e2dc2332cbf0e54f2e24ba821ff2d3dcf86bf6dc4ae130 + parser (3.3.10.1) sha256=06f6a725d2cd91e5e7f2b7c32ba143631e1f7c8ae2fb918fc4cebec187e6a688 + prism (1.8.0) sha256=84453a16ef5530ea62c5f03ec16b52a459575ad4e7b9c2b360fd8ce2c39c1254 + racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f + rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a + regexp_parser (2.11.3) sha256=ca13f381a173b7a93450e53459075c9b76a10433caadcb2f1180f2c741fc55a4 + rubocop (1.82.1) sha256=09f1a6a654a960eda767aebea33e47603080f8e9c9a3f019bf9b94c9cab5e273 + rubocop-ast (1.49.0) sha256=49c3676d3123a0923d333e20c6c2dbaaae2d2287b475273fddee0c61da9f71fd + rubocop-performance (1.26.1) sha256=cd19b936ff196df85829d264b522fd4f98b6c89ad271fa52744a8c11b8f71834 + ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33 + standard (1.53.0) sha256=f3c9493385db7079d0abce6f7582f553122156997b81258cd361d3480eeacf9c + standard-custom (1.0.2) sha256=424adc84179a074f1a2a309bb9cf7cd6bfdb2b6541f20c6bf9436c0ba22a652b + standard-performance (1.9.0) sha256=49483d31be448292951d80e5e67cdcb576c2502103c7b40aec6f1b6e9c88e3f2 + unicode-display_width (3.2.0) sha256=0cdd96b5681a5949cdbc2c55e7b420facae74c4aaf9a9815eee1087cb1853c42 + unicode-emoji (4.2.0) sha256=519e69150f75652e40bf736106cfbc8f0f73aa3fb6a65afe62fefa7f80b0f80f + +BUNDLED WITH + 4.0.4 diff --git a/test-fixtures/multi-root-demo/ruby-lib/lib/string_utils.rb b/test-fixtures/multi-root-demo/ruby-lib/lib/string_utils.rb new file mode 100644 index 0000000..0f98b63 --- /dev/null +++ b/test-fixtures/multi-root-demo/ruby-lib/lib/string_utils.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +# This puts is fine for a Ruby library using plain 'standard'. +# With 'standard-rails', it would trigger: Rails/Output: Do not write to stdout. + +puts "Hello from Ruby lib"