diff --git a/CHANGELOG.md b/CHANGELOG.md index 543e509e0..d43b4b5e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,9 @@ #### :bug: Bug fix -- Fix Code Analyzer binary lookup for ReScript v12+ projects. +- Fix Code Analyzer cwd/binary lookup in monorepos (run from workspace root). +- Fix monorepo build detection by only watching the workspace root `.compiler.log`. +- Fix Start Build for ReScript v12+ projects by preferring `rescript.exe`. - Take namespace into account for incremental cleanup. https://github.com/rescript-lang/rescript-vscode/pull/1164 - Potential race condition in incremental compilation. https://github.com/rescript-lang/rescript-vscode/pull/1167 - Fix extension crash triggered by incremental compilation. https://github.com/rescript-lang/rescript-vscode/pull/1169 diff --git a/client/src/commands/code_analysis.ts b/client/src/commands/code_analysis.ts index 559f89c67..ed9feafd0 100644 --- a/client/src/commands/code_analysis.ts +++ b/client/src/commands/code_analysis.ts @@ -213,9 +213,14 @@ export const runCodeAnalysisWithReanalyze = ( let currentDocument = window.activeTextEditor.document; let cwd = targetDir ?? path.dirname(currentDocument.uri.fsPath); + // Resolve the project root from `cwd` (which is the workspace root when code analysis is started), + // rather than from the currently-open file (which may be in a subpackage). let projectRootPath: NormalizedPath | null = findProjectRootOfFileInDir( - currentDocument.uri.fsPath, + path.join(cwd, "bsconfig.json"), ); + if (projectRootPath == null) { + projectRootPath = findProjectRootOfFileInDir(currentDocument.uri.fsPath); + } // Try v12+ path first: @rescript/{platform}-{arch}/bin/rescript-tools.exe // Then fall back to legacy paths via getBinaryPath diff --git a/client/src/extension.ts b/client/src/extension.ts index c31a8d170..41e7ecc66 100644 --- a/client/src/extension.ts +++ b/client/src/extension.ts @@ -442,12 +442,11 @@ export function activate(context: ExtensionContext) { inCodeAnalysisState.active = true; - // Pointing reanalyze to the dir of the current file path is fine, because - // reanalyze will walk upwards looking for a bsconfig.json in order to find - // the correct project root. - inCodeAnalysisState.activatedFromDirectory = path.dirname( - currentDocument.uri.fsPath, - ); + // Run reanalyze from the workspace root (so monorepos consistently analyze the root project), + // instead of from whatever file happened to be active when analysis was started. + const wsFolder = workspace.getWorkspaceFolder(currentDocument.uri); + inCodeAnalysisState.activatedFromDirectory = + wsFolder?.uri.fsPath ?? path.dirname(currentDocument.uri.fsPath); codeAnalysisRunningStatusBarItem.command = "rescript-vscode.stop_code_analysis"; diff --git a/server/src/server.ts b/server/src/server.ts index b4445f68a..8dad29ea8 100644 --- a/server/src/server.ts +++ b/server/src/server.ts @@ -118,16 +118,28 @@ let findRescriptBinary = async ( ): Promise => { if ( config.extensionConfiguration.binaryPath != null && - fs.existsSync( - path.join(config.extensionConfiguration.binaryPath, "rescript"), - ) + (fs.existsSync( + path.join(config.extensionConfiguration.binaryPath, "rescript.exe"), + ) || + fs.existsSync( + path.join(config.extensionConfiguration.binaryPath, "rescript"), + )) ) { return utils.normalizePath( - path.join(config.extensionConfiguration.binaryPath, "rescript"), + fs.existsSync( + path.join(config.extensionConfiguration.binaryPath, "rescript.exe"), + ) + ? path.join(config.extensionConfiguration.binaryPath, "rescript.exe") + : path.join(config.extensionConfiguration.binaryPath, "rescript"), ); } - return utils.findRescriptBinary(projectRootPath); + // Prefer the native rescript.exe (v12+) for spawning `build -w`. + // Fall back to the legacy/JS wrapper `rescript` path if needed. + return ( + (await utils.findRescriptExeBinary(projectRootPath)) ?? + (await utils.findRescriptBinary(projectRootPath)) + ); }; let createInterfaceRequest = new v.RequestType< @@ -1388,11 +1400,10 @@ async function onMessage(msg: p.Message) { const watchers = Array.from(workspaceFolders).flatMap( (projectRootPath) => [ { - globPattern: path.join( - projectRootPath, - "**", - c.compilerLogPartialPath, - ), + // Only watch the root compiler log for each workspace folder. + // In monorepos, `**/lib/bs/.compiler.log` matches every package and dependency, + // causing a burst of events per save. + globPattern: path.join(projectRootPath, c.compilerLogPartialPath), kind: p.WatchKind.Change | p.WatchKind.Create | p.WatchKind.Delete, }, {