Skip to content

Commit 441959d

Browse files
authored
Merge pull request #1160 from nojaf/taigua-windows
Fix rewatch lockfile detection on Windows
2 parents a1b41a7 + 894205f commit 441959d

File tree

3 files changed

+80
-23
lines changed

3 files changed

+80
-23
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212
1313
## [Unreleased]
1414

15+
#### :bug: Bug fix
16+
17+
- Fix rewatch lockfile detection on Windows. https://github.com/rescript-lang/rescript-vscode/pull/1160
18+
1519
#### :nail_care: Polish
1620

1721
- Resolve symlinks when finding platform binaries. https://github.com/rescript-lang/rescript-vscode/pull/1154

server/src/incrementalCompilation.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ function triggerIncrementalCompilationOfFile(
277277
const foundRewatchLockfileInProjectRoot =
278278
computedWorkspaceRoot == null &&
279279
projectRootPath != null &&
280-
utils.findProjectRootOfFile(projectRootPath, true) != null;
280+
utils.findProjectRootOfDir(projectRootPath) != null;
281281

282282
if (foundRewatchLockfileInProjectRoot && debug()) {
283283
console.log(

server/src/utils.ts

Lines changed: 75 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,9 @@ export let createFileInTempDir = (extension = ""): NormalizedPath => {
8282
return path.join(os.tmpdir(), tempFileName) as NormalizedPath;
8383
};
8484

85-
let findProjectRootOfFileInDir = (
85+
function findProjectRootOfFileInDir(
8686
source: NormalizedPath,
87-
): NormalizedPath | null => {
87+
): NormalizedPath | null {
8888
const dir = normalizePath(path.dirname(source));
8989
if (dir == null) {
9090
return null;
@@ -102,18 +102,20 @@ let findProjectRootOfFileInDir = (
102102
return findProjectRootOfFileInDir(dir);
103103
}
104104
}
105-
};
105+
}
106106

107-
// TODO: races here?
108-
export let findProjectRootOfFile = (
107+
/**
108+
* Searches for a project root path in projectsFiles that contains the given file path.
109+
* Excludes exact matches - the source must be a file inside a project, not the project root itself.
110+
*/
111+
function findProjectRootContainingFile(
109112
source: NormalizedPath,
110-
allowDir?: boolean,
111-
): NormalizedPath | null => {
112-
// First look in project files (keys are already normalized)
113+
): NormalizedPath | null {
113114
let foundRootFromProjectFiles: NormalizedPath | null = null;
114115
for (const rootPath of projectsFiles.keys()) {
115116
// Both are normalized, so direct comparison works
116-
if (source.startsWith(rootPath) && (!allowDir || source !== rootPath)) {
117+
// For files, we exclude exact matches (source !== rootPath)
118+
if (source.startsWith(rootPath) && source !== rootPath) {
117119
// Prefer the longest path (most nested)
118120
if (
119121
foundRootFromProjectFiles == null ||
@@ -124,20 +126,71 @@ export let findProjectRootOfFile = (
124126
}
125127
}
126128

127-
if (foundRootFromProjectFiles != null) {
128-
return foundRootFromProjectFiles;
129-
} else {
130-
const isDir = path.extname(source) === "";
131-
const searchPath =
132-
isDir && !allowDir ? path.join(source, "dummy.res") : source;
133-
const normalizedSearchPath = normalizePath(searchPath);
134-
if (normalizedSearchPath == null) {
135-
return null;
129+
return foundRootFromProjectFiles;
130+
}
131+
132+
/**
133+
* Searches for a project root path in projectsFiles that matches the given directory path.
134+
* Allows exact matches - the source can be the project root directory itself.
135+
*/
136+
function findProjectRootMatchingDir(
137+
source: NormalizedPath,
138+
): NormalizedPath | null {
139+
let foundRootFromProjectFiles: NormalizedPath | null = null;
140+
for (const rootPath of projectsFiles.keys()) {
141+
// Both are normalized, so direct comparison works
142+
// For directories, we allow exact matches
143+
if (source.startsWith(rootPath)) {
144+
// Prefer the longest path (most nested)
145+
if (
146+
foundRootFromProjectFiles == null ||
147+
rootPath.length > foundRootFromProjectFiles.length
148+
) {
149+
foundRootFromProjectFiles = rootPath;
150+
}
136151
}
137-
const foundPath = findProjectRootOfFileInDir(normalizedSearchPath);
138-
return foundPath;
139152
}
140-
};
153+
154+
return foundRootFromProjectFiles;
155+
}
156+
157+
/**
158+
* Finds the project root for a given file path.
159+
* This is the main function used throughout the codebase for finding project roots.
160+
*/
161+
export function findProjectRootOfFile(
162+
source: NormalizedPath,
163+
): NormalizedPath | null {
164+
// First look in project files - exclude exact matches since we're looking for a file
165+
let foundRoot = findProjectRootContainingFile(source);
166+
167+
if (foundRoot != null) {
168+
return foundRoot;
169+
}
170+
171+
// Fallback: search the filesystem
172+
const foundPath = findProjectRootOfFileInDir(source);
173+
return foundPath;
174+
}
175+
176+
/**
177+
* Finds the project root for a given directory path.
178+
* This allows exact matches and is used for workspace/lockfile detection.
179+
*/
180+
export function findProjectRootOfDir(
181+
source: NormalizedPath,
182+
): NormalizedPath | null {
183+
// First look in project files - allow exact matches since we're looking for a directory
184+
let foundRoot = findProjectRootMatchingDir(source);
185+
186+
if (foundRoot != null) {
187+
return foundRoot;
188+
}
189+
190+
// Fallback: search the filesystem
191+
const foundPath = findProjectRootOfFileInDir(source);
192+
return foundPath;
193+
}
141194

142195
/**
143196
* Gets the project file for a given project root path.
@@ -500,7 +553,7 @@ export function computeWorkspaceRootPathFromLockfile(
500553
// if we find a rewatch.lock in the project root, it's a compilation of a local package
501554
// in the workspace.
502555
return !foundRewatchLockfileInProjectRoot
503-
? findProjectRootOfFile(projectRootPath, true)
556+
? findProjectRootOfDir(projectRootPath)
504557
: null;
505558
}
506559

0 commit comments

Comments
 (0)