|
1 | 1 | let version = "4.06.1+BS"
|
2 | 2 |
|
3 |
| -(* FIXME: Unreliable resolution *) |
| 3 | +exception Cannot_find_standard_library of string |
| 4 | + |
4 | 5 | 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 |
5 | 13 | 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))) |
21 | 62 |
|
22 | 63 | let standard_library_default = standard_library
|
23 | 64 |
|
|
0 commit comments