Source file write_corrected_file.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
open! Base
open Types
module Patch_with_file_contents = struct
type 'a t = original_file_contents:string -> 'a -> (Compact_loc.t * string) list
end
let rewrite_corrections ~original_file_contents ~corrections =
let corrections =
List.sort
~compare:(Comparable.lift Compact_loc.compare_character_range ~f:fst)
corrections
in
let l_pos, strs =
List.fold_map
corrections
~init:0
~f:(fun l_pos ({ start_pos; end_pos; start_bol = _ }, correction) ->
let code_chunk =
String.sub original_file_contents ~pos:l_pos ~len:(start_pos - l_pos)
in
end_pos, [ code_chunk; correction ])
in
let result = List.concat strs |> String.concat in
let rest = String.subo original_file_contents ~pos:l_pos in
result ^ rest
;;
let f ~use_color ~in_place ~diff_command ~diff_path_prefix ~filename ~with_ corrections
: Ppx_inline_test_lib.Test_result.t
=
let dot_corrected = filename ^ ".corrected" in
let original_file_contents =
let in_channel = Stdlib.open_in_bin filename in
let contents =
Stdlib.really_input_string in_channel (Stdlib.in_channel_length in_channel)
in
Stdlib.close_in in_channel;
contents
in
let remove file = if Stdlib.Sys.file_exists file then Stdlib.Sys.remove file in
let corrections = with_ ~original_file_contents corrections in
let next_contents = rewrite_corrections ~original_file_contents ~corrections in
match in_place with
| true ->
if not (String.equal original_file_contents next_contents)
then Stdio.Out_channel.write_all filename ~data:next_contents;
remove dot_corrected;
Success
| false ->
(match diff_command with
| Some "-" ->
Stdio.Out_channel.write_all dot_corrected ~data:next_contents;
Success
| _ ->
let tmp_corrected =
Stdlib.Filename.temp_file
(Stdlib.Filename.basename filename)
".corrected.tmp"
~temp_dir:(Stdlib.Filename.dirname filename)
in
(match
Make_corrected_file.f
~use_color
?diff_command
?diff_path_prefix
~corrected_path:tmp_corrected
~next_contents
~path:filename
()
with
| Ok _ ->
remove dot_corrected;
remove tmp_corrected;
Success
| Error _ ->
Stdlib.Sys.rename tmp_corrected dot_corrected;
Failure))
;;