Skip to content

Commit aa1034d

Browse files
shannonzhufacebook-github-bot
authored andcommitted
Support module-based search paths in backend
Summary: Support inclusion of toplevel module site packages in backend. Reviewed By: dkgi Differential Revision: D32599884 fbshipit-source-id: 79c875de3ccc19df26fe40cb8a05bd61d20237fe
1 parent 89b2a18 commit aa1034d

File tree

4 files changed

+59
-12
lines changed

4 files changed

+59
-12
lines changed

source/searchPath.ml

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ type t =
1414
root: Path.t;
1515
subdirectory: string;
1616
}
17+
| Submodule of {
18+
root: Path.t;
19+
submodule: string;
20+
}
1721
[@@deriving sexp, compare, hash]
1822

1923
type search_result = {
@@ -26,27 +30,35 @@ let equal = [%compare.equal: t]
2630
let get_root path =
2731
match path with
2832
| Root root -> root
29-
| Subdirectory { root; _ } -> root
33+
| Subdirectory { root; _ }
34+
| Submodule { root; _ } ->
35+
root
3036

3137

3238
let to_path path =
3339
match path with
3440
| Root root -> root
35-
| Subdirectory { root; subdirectory } -> Path.create_relative ~root ~relative:subdirectory
41+
| Subdirectory { root; subdirectory = relative }
42+
| Submodule { root; submodule = relative } ->
43+
Path.create_relative ~root ~relative
3644

3745

3846
let pp formatter = function
3947
| Root root -> Path.pp formatter root
40-
| Subdirectory { root; subdirectory } ->
41-
Format.fprintf formatter "%a$%s" Path.pp root subdirectory
48+
| Subdirectory { root; subdirectory = relative }
49+
| Submodule { root; submodule = relative } ->
50+
Format.fprintf formatter "%a$%s" Path.pp root relative
4251

4352

4453
let show path = Format.asprintf "%a" pp path
4554

4655
let create serialized =
4756
match String.split serialized ~on:'$' with
4857
| [root] -> Root (Path.create_absolute root)
49-
| [root; subdirectory] -> Subdirectory { root = Path.create_absolute root; subdirectory }
58+
| [root; path] -> (
59+
match String.split path ~on:'.' with
60+
| [subdirectory] -> Subdirectory { root = Path.create_absolute root; subdirectory }
61+
| _ -> Submodule { root = Path.create_absolute root; submodule = path })
5062
| _ -> failwith (Format.asprintf "Unable to create search path from %s" serialized)
5163

5264

@@ -58,14 +70,22 @@ let normalize = function
5870
root = Path.create_absolute ~follow_symbolic_links:true (Path.absolute root);
5971
subdirectory;
6072
}
73+
| Submodule { root; submodule } ->
74+
Submodule
75+
{ root = Path.create_absolute ~follow_symbolic_links:true (Path.absolute root); submodule }
6176

6277

6378
let create_normalized serialized = create serialized |> normalize
6479

6580
let search_for_path ~search_paths path =
6681
let under_root search_path =
6782
let open Option in
68-
if Path.directory_contains ~directory:(to_path search_path) path then
83+
let found =
84+
match search_path with
85+
| Submodule _ -> Path.equal (to_path search_path) path
86+
| _ -> Path.directory_contains ~directory:(to_path search_path) path
87+
in
88+
if found then
6989
let root = get_root search_path in
7090
Path.get_relative_to_root ~root ~path
7191
>>| (fun relative -> Path.create_relative ~root ~relative)

source/searchPath.mli

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ type t =
1313
root: Path.t;
1414
subdirectory: string;
1515
}
16+
| Submodule of {
17+
root: Path.t;
18+
submodule: string;
19+
}
1620
[@@deriving sexp, compare, hash, show, eq]
1721

1822
type search_result = {

source/service/check.ml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,20 @@ let check
2525
if not (Path.is_directory directory) then
2626
raise (Invalid_argument (Format.asprintf "`%a` is not a directory" Path.pp directory))
2727
in
28+
let check_path_exists path =
29+
if not (Path.file_exists path) then
30+
raise (Invalid_argument (Format.asprintf "`%a` is not a valid path" Path.pp path))
31+
in
32+
let check_search_path_exists search_path =
33+
match search_path with
34+
| SearchPath.Root _
35+
| SearchPath.Subdirectory _ ->
36+
check_directory_exists (SearchPath.to_path search_path)
37+
| SearchPath.Submodule _ -> check_path_exists (SearchPath.to_path search_path)
38+
in
2839
source_paths |> List.map ~f:SearchPath.to_path |> List.iter ~f:check_directory_exists;
2940
check_directory_exists project_root;
30-
search_paths |> List.map ~f:SearchPath.to_path |> List.iter ~f:check_directory_exists;
41+
search_paths |> List.iter ~f:check_search_path_exists;
3142
(* Profiling helper *)
3243
Profiling.track_shared_memory_usage ~name:"Before module tracking" ();
3344

source/test/searchPathTest.ml

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ let test_create_search_path _ =
2323
~cmp:SearchPath.equal
2424
(SearchPath.Subdirectory { root; subdirectory = "subdirectory" })
2525
(SearchPath.create (Path.show root ^ "$subdirectory"));
26+
assert_equal
27+
~cmp:SearchPath.equal
28+
(SearchPath.Submodule { root; submodule = "submodule.py" })
29+
(SearchPath.create (Path.show root ^ "$submodule.py"));
2630
assert_raises (Failure "Unable to create search path from too$many$levels") (fun () ->
2731
SearchPath.create "too$many$levels")
2832

@@ -38,6 +42,8 @@ let test_show_search_path _ =
3842
assert_round_trip (SearchPath.Subdirectory { root = !"/foo"; subdirectory = "bar" });
3943
assert_round_trip (SearchPath.Subdirectory { root = !"/foo/bar"; subdirectory = "baz" });
4044
assert_round_trip (SearchPath.Subdirectory { root = !"/foo"; subdirectory = "bar/baz" });
45+
assert_round_trip (SearchPath.Submodule { root = !"/foo"; submodule = "bar.py" });
46+
assert_round_trip (SearchPath.Submodule { root = !"/foo"; submodule = "bar/baz.py" });
4147
()
4248

4349

@@ -46,11 +52,12 @@ let test_normalize context =
4652
let bad_root = "nonexist/directory" in
4753
let good_subroot = good_root ^ "/subroot" in
4854
Sys_utils.mkdir_no_fail good_subroot;
49-
let create_input ?subdirectory root =
55+
let create_input ?subdirectory ?submodule root =
5056
let search_path =
51-
match subdirectory with
52-
| None -> SearchPath.Root !root
53-
| Some subdirectory -> SearchPath.Subdirectory { root = !root; subdirectory }
57+
match subdirectory, submodule with
58+
| Some subdirectory, _ -> SearchPath.Subdirectory { root = !root; subdirectory }
59+
| _, Some submodule -> SearchPath.Submodule { root = !root; submodule }
60+
| _ -> SearchPath.Root !root
5461
in
5562
SearchPath.show search_path
5663
in
@@ -90,6 +97,7 @@ let test_normalize context =
9097
assert_success ~normalize:false ~expected:true (create_input ~subdirectory:"subroot" good_root);
9198
assert_success ~normalize:false ~expected:true (create_input ~subdirectory:"nosubroot" good_root);
9299
assert_success ~normalize:false ~expected:true (create_input ~subdirectory:"subroot" bad_root);
100+
assert_success ~normalize:false ~expected:true (create_input ~submodule:"subroot" bad_root);
93101

94102
(* Normalized creation depends on filesystem state. *)
95103
assert_success ~normalize:true ~expected:true (create_input good_root);
@@ -98,6 +106,8 @@ let test_normalize context =
98106
assert_success ~normalize:true ~expected:true (create_input ~subdirectory:"subroot" good_root);
99107
assert_success ~normalize:true ~expected:false (create_input ~subdirectory:"nosubroot" good_root);
100108
assert_success ~normalize:true ~expected:false (create_input ~subdirectory:"subroot" bad_root);
109+
assert_success ~normalize:true ~expected:true (create_input ~submodule:"subroot" good_root);
110+
assert_success ~normalize:true ~expected:false (create_input ~submodule:"subroot" bad_root);
101111

102112
()
103113

@@ -116,6 +126,7 @@ let test_search_for_path context =
116126
SearchPath.Subdirectory
117127
{ root = Path.create_relative ~root ~relative:"b"; subdirectory = "c" };
118128
SearchPath.Subdirectory { root; subdirectory = "b" };
129+
SearchPath.Submodule { root; submodule = "b.py" };
119130
]
120131
in
121132
assert_path
@@ -129,7 +140,8 @@ let test_search_for_path context =
129140
assert_path
130141
~search_paths
131142
~path:(Path.create_relative ~root ~relative:"b/other/file.py")
132-
~expected:"b/other/file.py"
143+
~expected:"b/other/file.py";
144+
assert_path ~search_paths ~path:(Path.create_relative ~root ~relative:"b.py") ~expected:"b.py"
133145

134146

135147
let () =

0 commit comments

Comments
 (0)