diff --git a/jscomp/bsb/bsb_pkg.ml b/jscomp/bsb/bsb_pkg.ml index ddbb169255..3da622e649 100644 --- a/jscomp/bsb/bsb_pkg.ml +++ b/jscomp/bsb/bsb_pkg.ml @@ -32,33 +32,49 @@ type t = Bsb_pkg_types.t when resolving [ppx-flags] *) let make_sub_path (x : t) : string = - Literals.node_modules // Bsb_pkg_types.to_string x - + Literals.node_modules // Bsb_pkg_types.to_string x + +let node_path_delimiter = + if Sys.win32 then + ';' + else + ':' (** It makes sense to have this function raise, when [bsb] could not resolve a package, it used to mean a failure *) let resolve_bs_package_aux ~cwd (pkg : t) = + (* First try to resolve recursively from the current working directory *) let sub_path = make_sub_path pkg in let rec aux cwd = - let abs_marker = cwd // sub_path in - if Sys.file_exists abs_marker then abs_marker + let abs_marker = cwd // sub_path in + if Sys.file_exists abs_marker then Some(abs_marker) else let another_cwd = Filename.dirname cwd in (* TODO: may non-terminating when see symlinks *) if String.length another_cwd < String.length cwd then - aux another_cwd - else (* To the end try other possiblilities *) - begin match Sys.getenv "npm_config_prefix" - // "lib" // sub_path with - | abs_marker when Sys.file_exists abs_marker -> - abs_marker - | _ -> - Bsb_exception.package_not_found ~pkg ~json:None - | exception Not_found -> - Bsb_exception.package_not_found ~pkg ~json:None - end + aux another_cwd + else + None in - aux cwd + match aux cwd with + | Some(package_dir) -> package_dir + (* If the package can not be resolved then check if NODE_PATH is set and if set then search there*) + | None -> + let node_path = + match Sys.getenv "NODE_PATH" with + | node_path -> + Ext_string.split node_path node_path_delimiter + | exception Not_found -> + Bsb_exception.package_not_found ~pkg ~json:None + in + let check_dir dir = + match Sys.file_exists dir with + | true -> Some(dir) + | false -> None + in + match Ext_list.find_opt node_path (fun dir -> check_dir (dir // Bsb_pkg_types.to_string pkg)) with + | Some(resolved_dir) -> resolved_dir + | None -> Bsb_exception.package_not_found ~pkg ~json:None module Coll = Hashtbl_make.Make(struct type nonrec t = t diff --git a/jscomp/build_tests/bs_dependencies_node_path_override/.gitignore b/jscomp/build_tests/bs_dependencies_node_path_override/.gitignore new file mode 100644 index 0000000000..71c60460d7 --- /dev/null +++ b/jscomp/build_tests/bs_dependencies_node_path_override/.gitignore @@ -0,0 +1,29 @@ +*.exe +*.obj +*.out +*.compile +*.native +*.byte +*.cmo +*.annot +*.cmi +*.cmx +*.cmt +*.cmti +*.cma +*.a +*.cmxa +*.obj +*~ +*.annot +*.cmj +*.bak +lib/bs +*.mlast +*.mliast +.vscode +.merlin +**/*.js +!node_modules +!input.js +!testcase.js \ No newline at end of file diff --git a/jscomp/build_tests/bs_dependencies_node_path_override/README.md b/jscomp/build_tests/bs_dependencies_node_path_override/README.md new file mode 100644 index 0000000000..1c02d2a072 --- /dev/null +++ b/jscomp/build_tests/bs_dependencies_node_path_override/README.md @@ -0,0 +1,16 @@ + + +# Build +``` +npm run build +``` + +# Watch + +``` +npm run watch +``` + + +# Editor +If you use `vscode`, Press `Windows + Shift + B` it will build automatically \ No newline at end of file diff --git a/jscomp/build_tests/bs_dependencies_node_path_override/bsconfig.json b/jscomp/build_tests/bs_dependencies_node_path_override/bsconfig.json new file mode 100644 index 0000000000..5eb6a09cf2 --- /dev/null +++ b/jscomp/build_tests/bs_dependencies_node_path_override/bsconfig.json @@ -0,0 +1,23 @@ +{ + "name": "bs_dependencies_node_path_override", + "version": "0.1.0", + "sources": [ + { + "dir": "src", + "subdirs" : true + }, + { + "dir": "examples", + "type" : "dev", + "subdirs" : true + } + ], + "package-specs" : { + "module": "commonjs", + "in-source": true + }, + "namespace": true, + "bs-dependencies" : [ + "liba" + ] +} \ No newline at end of file diff --git a/jscomp/build_tests/bs_dependencies_node_path_override/examples/test.ml b/jscomp/build_tests/bs_dependencies_node_path_override/examples/test.ml new file mode 100644 index 0000000000..f5f8f9d8c1 --- /dev/null +++ b/jscomp/build_tests/bs_dependencies_node_path_override/examples/test.ml @@ -0,0 +1 @@ +let v = Demo.name \ No newline at end of file diff --git a/jscomp/build_tests/bs_dependencies_node_path_override/input.js b/jscomp/build_tests/bs_dependencies_node_path_override/input.js new file mode 100644 index 0000000000..cda1016b08 --- /dev/null +++ b/jscomp/build_tests/bs_dependencies_node_path_override/input.js @@ -0,0 +1,5 @@ +//@ts-check +var path = require('path') +var p = require('child_process') +var node_path = path.join(__dirname, "nothing_exists_here") + ":" + path.join(__dirname, "overridden_node_modules") +p.execSync(`NODE_PATH=${node_path} node ./testcase.js`, { cwd: __dirname, shell: true, encoding: 'utf8' }) \ No newline at end of file diff --git a/jscomp/build_tests/bs_dependencies_node_path_override/overridden_node_modules/liba/.gitignore b/jscomp/build_tests/bs_dependencies_node_path_override/overridden_node_modules/liba/.gitignore new file mode 100644 index 0000000000..8f464d0527 --- /dev/null +++ b/jscomp/build_tests/bs_dependencies_node_path_override/overridden_node_modules/liba/.gitignore @@ -0,0 +1,25 @@ +*.exe +*.obj +*.out +*.compile +*.native +*.byte +*.cmo +*.annot +*.cmi +*.cmx +*.cmt +*.cmti +*.cma +*.a +*.cmxa +*.obj +*~ +*.annot +*.cmj +*.bak +lib/bs +*.mlast +*.mliast +.vscode +.merlin \ No newline at end of file diff --git a/jscomp/build_tests/bs_dependencies_node_path_override/overridden_node_modules/liba/README.md b/jscomp/build_tests/bs_dependencies_node_path_override/overridden_node_modules/liba/README.md new file mode 100644 index 0000000000..1c02d2a072 --- /dev/null +++ b/jscomp/build_tests/bs_dependencies_node_path_override/overridden_node_modules/liba/README.md @@ -0,0 +1,16 @@ + + +# Build +``` +npm run build +``` + +# Watch + +``` +npm run watch +``` + + +# Editor +If you use `vscode`, Press `Windows + Shift + B` it will build automatically \ No newline at end of file diff --git a/jscomp/build_tests/bs_dependencies_node_path_override/overridden_node_modules/liba/bsconfig.json b/jscomp/build_tests/bs_dependencies_node_path_override/overridden_node_modules/liba/bsconfig.json new file mode 100644 index 0000000000..f34d7ed09e --- /dev/null +++ b/jscomp/build_tests/bs_dependencies_node_path_override/overridden_node_modules/liba/bsconfig.json @@ -0,0 +1,17 @@ +{ + "name": "liba", + "version": "0.1.0", + "sources": [ + { + "dir": "src", + "subdirs" : true + }, + { + "dir" : "examples", + "type": "dev", + "subdirs" : true + } + ], + "namespace": true + +} \ No newline at end of file diff --git a/jscomp/build_tests/bs_dependencies_node_path_override/overridden_node_modules/liba/examples/xx/test.ml b/jscomp/build_tests/bs_dependencies_node_path_override/overridden_node_modules/liba/examples/xx/test.ml new file mode 100644 index 0000000000..af158a09e6 --- /dev/null +++ b/jscomp/build_tests/bs_dependencies_node_path_override/overridden_node_modules/liba/examples/xx/test.ml @@ -0,0 +1 @@ +let name = __FILE__ + 3 \ No newline at end of file diff --git a/jscomp/build_tests/bs_dependencies_node_path_override/overridden_node_modules/liba/examples/yy.ml b/jscomp/build_tests/bs_dependencies_node_path_override/overridden_node_modules/liba/examples/yy.ml new file mode 100644 index 0000000000..d32a6d0646 --- /dev/null +++ b/jscomp/build_tests/bs_dependencies_node_path_override/overridden_node_modules/liba/examples/yy.ml @@ -0,0 +1 @@ +let name = __FILE__ \ No newline at end of file diff --git a/jscomp/build_tests/bs_dependencies_node_path_override/overridden_node_modules/liba/package.json b/jscomp/build_tests/bs_dependencies_node_path_override/overridden_node_modules/liba/package.json new file mode 100644 index 0000000000..63c69448e0 --- /dev/null +++ b/jscomp/build_tests/bs_dependencies_node_path_override/overridden_node_modules/liba/package.json @@ -0,0 +1,16 @@ +{ + "name": "liba", + "version": "0.1.0", + "scripts": { + "clean": "bsb -clean-world", + "build": "bsb -make-world", + "watch": "bsb -make-world -w" + }, + "keywords": [ + "BuckleScript" + ], + "license": "MIT", + "devDependencies": { + "bs-platform": "1.9.3" + } +} \ No newline at end of file diff --git a/jscomp/build_tests/bs_dependencies_node_path_override/overridden_node_modules/liba/src/demo.ml b/jscomp/build_tests/bs_dependencies_node_path_override/overridden_node_modules/liba/src/demo.ml new file mode 100644 index 0000000000..ca8c589c96 --- /dev/null +++ b/jscomp/build_tests/bs_dependencies_node_path_override/overridden_node_modules/liba/src/demo.ml @@ -0,0 +1,3 @@ + + +let name = __FILE__ \ No newline at end of file diff --git a/jscomp/build_tests/bs_dependencies_node_path_override/overridden_node_modules/liba/src/hi/fib.ml b/jscomp/build_tests/bs_dependencies_node_path_override/overridden_node_modules/liba/src/hi/fib.ml new file mode 100644 index 0000000000..d32a6d0646 --- /dev/null +++ b/jscomp/build_tests/bs_dependencies_node_path_override/overridden_node_modules/liba/src/hi/fib.ml @@ -0,0 +1 @@ +let name = __FILE__ \ No newline at end of file diff --git a/jscomp/build_tests/bs_dependencies_node_path_override/package.json b/jscomp/build_tests/bs_dependencies_node_path_override/package.json new file mode 100644 index 0000000000..8d24a775bb --- /dev/null +++ b/jscomp/build_tests/bs_dependencies_node_path_override/package.json @@ -0,0 +1,16 @@ +{ + "name": "bs_dependencies_node_path_override", + "version": "0.1.0", + "scripts": { + "clean": "bsb -clean-world", + "build": "bsb -make-world", + "watch": "bsb -make-world -w" + }, + "keywords": [ + "BuckleScript" + ], + "license": "MIT", + "devDependencies": { + "bs-platform": "^5.1.0-dev.3" + } +} \ No newline at end of file diff --git a/jscomp/build_tests/bs_dependencies_node_path_override/src/demo.ml b/jscomp/build_tests/bs_dependencies_node_path_override/src/demo.ml new file mode 100644 index 0000000000..1b2a37152f --- /dev/null +++ b/jscomp/build_tests/bs_dependencies_node_path_override/src/demo.ml @@ -0,0 +1,3 @@ + + +let name = __FILE__ ^ Liba.Demo.name \ No newline at end of file diff --git a/jscomp/build_tests/bs_dependencies_node_path_override/testcase.js b/jscomp/build_tests/bs_dependencies_node_path_override/testcase.js new file mode 100644 index 0000000000..798d8f2165 --- /dev/null +++ b/jscomp/build_tests/bs_dependencies_node_path_override/testcase.js @@ -0,0 +1,7 @@ +//@ts-check +var assert = require('assert') +var path = require('path') +var p = require('child_process') +p.execSync(`bsb -make-world`, { cwd: __dirname, shell: true, encoding: 'utf8' }) +var u = require("./examples/test.js") +assert.equal(path.basename(u.v), 'demo.mldemo.ml') \ No newline at end of file diff --git a/lib/4.02.3/bsb.ml b/lib/4.02.3/bsb.ml index aba61b5860..0f8b63e312 100644 --- a/lib/4.02.3/bsb.ml +++ b/lib/4.02.3/bsb.ml @@ -5214,33 +5214,49 @@ type t = Bsb_pkg_types.t when resolving [ppx-flags] *) let make_sub_path (x : t) : string = - Literals.node_modules // Bsb_pkg_types.to_string x - + Literals.node_modules // Bsb_pkg_types.to_string x + +let node_path_delimiter = + if Sys.win32 then + ';' + else + ':' (** It makes sense to have this function raise, when [bsb] could not resolve a package, it used to mean a failure *) let resolve_bs_package_aux ~cwd (pkg : t) = + (* First try to resolve recursively from the current working directory *) let sub_path = make_sub_path pkg in let rec aux cwd = - let abs_marker = cwd // sub_path in - if Sys.file_exists abs_marker then abs_marker + let abs_marker = cwd // sub_path in + if Sys.file_exists abs_marker then Some(abs_marker) else let another_cwd = Filename.dirname cwd in (* TODO: may non-terminating when see symlinks *) if String.length another_cwd < String.length cwd then - aux another_cwd - else (* To the end try other possiblilities *) - begin match Sys.getenv "npm_config_prefix" - // "lib" // sub_path with - | abs_marker when Sys.file_exists abs_marker -> - abs_marker - | _ -> - Bsb_exception.package_not_found ~pkg ~json:None - | exception Not_found -> - Bsb_exception.package_not_found ~pkg ~json:None - end + aux another_cwd + else + None in - aux cwd + match aux cwd with + | Some(package_dir) -> package_dir + (* If the package can not be resolved then check if NODE_PATH is set and if set then search there*) + | None -> + let node_path = + match Sys.getenv "NODE_PATH" with + | node_path -> + Ext_string.split node_path node_path_delimiter + | exception Not_found -> + Bsb_exception.package_not_found ~pkg ~json:None + in + let check_dir dir = + match Sys.file_exists dir with + | true -> Some(dir) + | false -> None + in + match Ext_list.find_opt node_path (fun dir -> check_dir (dir // Bsb_pkg_types.to_string pkg)) with + | Some(resolved_dir) -> resolved_dir + | None -> Bsb_exception.package_not_found ~pkg ~json:None module Coll = Hashtbl_make.Make(struct type nonrec t = t diff --git a/lib/4.02.3/unstable/bsb_native.ml b/lib/4.02.3/unstable/bsb_native.ml index 58a0abdc96..2faafd9808 100644 --- a/lib/4.02.3/unstable/bsb_native.ml +++ b/lib/4.02.3/unstable/bsb_native.ml @@ -5214,33 +5214,49 @@ type t = Bsb_pkg_types.t when resolving [ppx-flags] *) let make_sub_path (x : t) : string = - Literals.node_modules // Bsb_pkg_types.to_string x - + Literals.node_modules // Bsb_pkg_types.to_string x + +let node_path_delimiter = + if Sys.win32 then + ';' + else + ':' (** It makes sense to have this function raise, when [bsb] could not resolve a package, it used to mean a failure *) let resolve_bs_package_aux ~cwd (pkg : t) = + (* First try to resolve recursively from the current working directory *) let sub_path = make_sub_path pkg in let rec aux cwd = - let abs_marker = cwd // sub_path in - if Sys.file_exists abs_marker then abs_marker + let abs_marker = cwd // sub_path in + if Sys.file_exists abs_marker then Some(abs_marker) else let another_cwd = Filename.dirname cwd in (* TODO: may non-terminating when see symlinks *) if String.length another_cwd < String.length cwd then - aux another_cwd - else (* To the end try other possiblilities *) - begin match Sys.getenv "npm_config_prefix" - // "lib" // sub_path with - | abs_marker when Sys.file_exists abs_marker -> - abs_marker - | _ -> - Bsb_exception.package_not_found ~pkg ~json:None - | exception Not_found -> - Bsb_exception.package_not_found ~pkg ~json:None - end + aux another_cwd + else + None in - aux cwd + match aux cwd with + | Some(package_dir) -> package_dir + (* If the package can not be resolved then check if NODE_PATH is set and if set then search there*) + | None -> + let node_path = + match Sys.getenv "NODE_PATH" with + | node_path -> + Ext_string.split node_path node_path_delimiter + | exception Not_found -> + Bsb_exception.package_not_found ~pkg ~json:None + in + let check_dir dir = + match Sys.file_exists dir with + | true -> Some(dir) + | false -> None + in + match Ext_list.find_opt node_path (fun dir -> check_dir (dir // Bsb_pkg_types.to_string pkg)) with + | Some(resolved_dir) -> resolved_dir + | None -> Bsb_exception.package_not_found ~pkg ~json:None module Coll = Hashtbl_make.Make(struct type nonrec t = t