Skip to content

Commit 4af5bd7

Browse files
committed
Create async version of utils.findBinary
1 parent 0b1fc72 commit 4af5bd7

File tree

1 file changed

+97
-43
lines changed

1 file changed

+97
-43
lines changed

server/src/utils.ts

Lines changed: 97 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ import {
77
ResponseMessage,
88
} from "vscode-languageserver-protocol";
99
import fs from "fs";
10+
import fsAsync from "fs/promises";
1011
import * as os from "os";
12+
import semver from "semver";
1113

1214
import * as codeActions from "./codeActions";
1315
import * as c from "./constants";
@@ -90,6 +92,101 @@ export let findBinary = (
9092
}
9193
};
9294

95+
let findPlatformPath = (projectRootPath: p.DocumentUri | null) => {
96+
if (config.extensionConfiguration.platformPath != null) {
97+
return config.extensionConfiguration.platformPath;
98+
}
99+
100+
let rescriptDir = lookup.findFilePathFromProjectRoot(
101+
projectRootPath,
102+
path.join("node_modules", "rescript")
103+
);
104+
if (rescriptDir == null) {
105+
return null;
106+
}
107+
108+
let platformPath = path.join(rescriptDir, c.platformDir);
109+
110+
// Binaries have been split into optional platform-specific dependencies
111+
// since v12.0.0-alpha.13
112+
if (!fs.existsSync(platformPath)) {
113+
platformPath = path.join(
114+
rescriptDir,
115+
"..",
116+
`@rescript/${process.platform}-${process.arch}/bin`
117+
)
118+
}
119+
120+
// Workaround for darwinarm64 which has no folder yet in ReScript <= 9.1.4
121+
if (
122+
process.platform == "darwin" &&
123+
process.arch == "arm64" &&
124+
!fs.existsSync(platformPath)
125+
) {
126+
platformPath = path.join(rescriptDir, process.platform);
127+
}
128+
129+
return platformPath;
130+
};
131+
132+
export let findBscExeBinary = (projectRootPath: p.DocumentUri | null) =>
133+
findBinary(findPlatformPath(projectRootPath), c.bscExeName);
134+
135+
export let findEditorAnalysisBinary = (projectRootPath: p.DocumentUri | null) =>
136+
findBinary(findPlatformPath(projectRootPath), c.editorAnalysisName);
137+
138+
// If ReScript < 12.0.0-alpha.13, then we want `{project_root}/node_modules/rescript/{c.platformDir}/{binary}`.
139+
// Otherwise, we want to dynamically import `{project_root}/node_modules/rescript` and from `binPaths` get the relevant binary.
140+
// We won't know which version is in the project root until we read and parse `{project_root}/node_modules/rescript/package.json`
141+
let findBinaryAsync = async (
142+
projectRootPath: p.DocumentUri | null,
143+
binary: "bsc.exe" | "rescript-editor-analysis.exe"
144+
) => {
145+
if (config.extensionConfiguration.platformPath != null) {
146+
return path.join(config.extensionConfiguration.platformPath, binary);
147+
}
148+
149+
const rescriptDir = lookup.findFilePathFromProjectRoot(
150+
projectRootPath,
151+
path.join("node_modules", "rescript")
152+
);
153+
if (rescriptDir == null) {
154+
return null;
155+
}
156+
157+
let rescriptVersion = null;
158+
try {
159+
const rescriptPackageJSONPath = path.join(rescriptDir, "package.json");
160+
const rescriptPackageJSON = JSON.parse(await fsAsync.readFile(rescriptPackageJSONPath, "utf-8"));
161+
rescriptVersion = rescriptPackageJSON.version
162+
} catch (error) {
163+
return null
164+
}
165+
166+
let binaryPath: string | null = null
167+
if (semver.gte(rescriptVersion, "12.0.0-alpha.13")) {
168+
// TODO: export `binPaths` from `rescript` package so that we don't need to
169+
// copy the logic for figuring out `target`.
170+
const target = `${process.platform}-${process.arch}`;
171+
const targetPackagePath = path.join(rescriptDir, "..", `@rescript/${target}`)
172+
const { binPaths } = await import(targetPackagePath);
173+
174+
if (binary == "bsc.exe") {
175+
binaryPath = binPaths.bsc_exe
176+
} else if (binary == "rescript-editor-analysis.exe") {
177+
binaryPath = binPaths.rescript_editor_analysis_exe
178+
}
179+
} else {
180+
binaryPath = path.join(rescriptDir, c.platformDir, binary)
181+
}
182+
183+
if (binaryPath != null && fs.existsSync(binaryPath)) {
184+
return binaryPath
185+
} else {
186+
return null
187+
}
188+
}
189+
93190
type execResult =
94191
| {
95192
kind: "success";
@@ -723,46 +820,3 @@ export let rangeContainsRange = (
723820
}
724821
return true;
725822
};
726-
727-
let findPlatformPath = (projectRootPath: p.DocumentUri | null) => {
728-
if (config.extensionConfiguration.platformPath != null) {
729-
return config.extensionConfiguration.platformPath;
730-
}
731-
732-
let rescriptDir = lookup.findFilePathFromProjectRoot(
733-
projectRootPath,
734-
path.join("node_modules", "rescript")
735-
);
736-
if (rescriptDir == null) {
737-
return null;
738-
}
739-
740-
let platformPath = path.join(rescriptDir, c.platformDir);
741-
742-
// Binaries have been split into optional platform-specific dependencies
743-
// since v12.0.0-alpha.13
744-
if (!fs.existsSync(platformPath)) {
745-
platformPath = path.join(
746-
rescriptDir,
747-
"..",
748-
`@rescript/${process.platform}-${process.arch}/bin`
749-
)
750-
}
751-
752-
// Workaround for darwinarm64 which has no folder yet in ReScript <= 9.1.4
753-
if (
754-
process.platform == "darwin" &&
755-
process.arch == "arm64" &&
756-
!fs.existsSync(platformPath)
757-
) {
758-
platformPath = path.join(rescriptDir, process.platform);
759-
}
760-
761-
return platformPath;
762-
};
763-
764-
export let findBscExeBinary = (projectRootPath: p.DocumentUri | null) =>
765-
findBinary(findPlatformPath(projectRootPath), c.bscExeName);
766-
767-
export let findEditorAnalysisBinary = (projectRootPath: p.DocumentUri | null) =>
768-
findBinary(findPlatformPath(projectRootPath), c.editorAnalysisName);

0 commit comments

Comments
 (0)