Skip to content

Commit aae6374

Browse files
committed
Fix finding the standard library for pnpm
1 parent d70c7fa commit aae6374

File tree

1 file changed

+57
-16
lines changed

1 file changed

+57
-16
lines changed

compiler/ext/config.ml

Lines changed: 57 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,64 @@
11
let version = "4.06.1+BS"
22

3-
(* FIXME: Unreliable resolution *)
3+
exception Cannot_find_standard_library of string
4+
45
let standard_library =
6+
(* This resolves the location of the standard library starting from the location of bsc.exe.
7+
Unfortunately it is rather hacky, as we have to detect and handle several cases here:
8+
1.) Local development in the `rescript` repo
9+
2.) Packages installed via npm
10+
3.) Packages installed via pnpm *)
11+
let bin_dir = Filename.dirname Sys.executable_name in
12+
let dir_sep = Filename.dir_sep in
513
let ( // ) = Filename.concat in
6-
let exe_path = Sys.executable_name in
7-
if Ext_string.contain_substring exe_path ("node_modules" // "@rescript") then
8-
(* node_modules/@rescript/{platform}/bin *)
9-
Filename.dirname exe_path // Filename.parent_dir_name
10-
// Filename.parent_dir_name // Filename.parent_dir_name // "rescript"
11-
// "lib" // "ocaml"
12-
else if Ext_string.contain_substring exe_path ("node_modules" // "rescript")
13-
then
14-
(* node_modules/rescript/{platform} *)
15-
Filename.dirname exe_path // Filename.parent_dir_name // "lib" // "ocaml"
16-
else
17-
(* git repo: rescript/packages/@rescript/{platform}/bin *)
18-
Filename.dirname exe_path // Filename.parent_dir_name
19-
// Filename.parent_dir_name // Filename.parent_dir_name
20-
// Filename.parent_dir_name // "lib" // "ocaml"
14+
15+
(* Find position of /node_modules/ in bin_dir *)
16+
match Ext_string.find ~sub:(dir_sep ^ "node_modules" ^ dir_sep) bin_dir with
17+
| -1 ->
18+
(* 1. Not installed in node_modules => local development in the `rescript` repo
19+
- bin: <repo>/packages/@rescript/{platform}/bin
20+
- stdlib: <repo>/lib/ocaml
21+
*)
22+
let up = Filename.parent_dir_name in
23+
bin_dir // up // up // up // up // "lib" // "ocaml"
24+
| i -> (
25+
(* to account for the / before node_modules *)
26+
let i = i + 1 in
27+
let project_path = String.sub bin_dir 0 i in
28+
let subpath = String.sub bin_dir i (String.length bin_dir - i) in
29+
30+
match subpath |> String.split_on_char dir_sep.[0] with
31+
(* 2. Packages installed via npm
32+
- bin: node_modules/@rescript/{platform}/bin
33+
- stdlib: node_modules/rescript/lib/ocaml
34+
*)
35+
| ["node_modules"; "@rescript"; _platform; "bin"] ->
36+
project_path // "node_modules" // "rescript" // "lib" // "ocaml"
37+
(* 3. Packages installed via pnpm
38+
- bin: node_modules/.pnpm/@[email protected]/node_modules/@rescript/darwin-arm64/bin
39+
- stdlib: node_modules/.pnpm/[email protected]/node_modules/rescript/lib/ocaml
40+
*)
41+
| [
42+
"node_modules";
43+
".pnpm";
44+
platform_package;
45+
"node_modules";
46+
"@rescript";
47+
_platform;
48+
"bin";
49+
] -> (
50+
match platform_package |> String.split_on_char '@' with
51+
| [""; _prefix; version] ->
52+
project_path // "node_modules" // ".pnpm" // ("rescript@" ^ version)
53+
// "node_modules" // "rescript" // "lib" // "ocaml"
54+
| _ ->
55+
raise
56+
(Cannot_find_standard_library
57+
("Cannot parse pnpm platform package: " ^ platform_package)))
58+
| _ ->
59+
raise
60+
(Cannot_find_standard_library
61+
("Unrecognized node_modules structure: " ^ subpath)))
2162

2263
let standard_library_default = standard_library
2364

0 commit comments

Comments
 (0)