@@ -68,3 +68,66 @@ let skip_subtree ~globs =
68
68
, skip_subtree )
69
69
]
70
70
;;
71
+
72
+ let error_message_cleanup_pattern =
73
+ lazy (Re.Perl. compile_pat {|^ (?: [^/ ]* [/ ])* ([^/ ]* )\.ml\.([^. ]* )\.[^: ]*: (.* )$| })
74
+ ;;
75
+
76
+ let clean_up_error_message str =
77
+ let pattern = Lazy. force error_message_cleanup_pattern in
78
+ match Re. exec_opt pattern str with
79
+ | None -> str
80
+ | Some match_info ->
81
+ let basename = Re.Group. get match_info 1 in
82
+ let module_name = Re.Group. get match_info 2 in
83
+ let rest = Re.Group. get match_info 3 in
84
+ Printf. sprintf " %s.%s:%s" basename module_name rest
85
+ ;;
86
+
87
+ let loc_of_parsexp_range ~filename (range : Parsexp.Positions.range ) =
88
+ let source_code_position ({ line; col; offset } : Parsexp.Positions.pos ) =
89
+ { Lexing. pos_fname = filename
90
+ ; pos_lnum = line
91
+ ; pos_cnum = offset
92
+ ; pos_bol = offset - col
93
+ }
94
+ in
95
+ Loc. create (source_code_position range.start_pos, source_code_position range.end_pos)
96
+ ;;
97
+
98
+ let load_config_exn ~filename =
99
+ let contents = In_channel. read_all filename in
100
+ match Parsexp.Single_and_positions. parse_string contents with
101
+ | Error parse_error ->
102
+ let position = Parsexp.Parse_error. position parse_error in
103
+ let message = Parsexp.Parse_error. message parse_error in
104
+ let loc =
105
+ loc_of_parsexp_range ~filename { start_pos = position; end_pos = position }
106
+ in
107
+ Err. raise ~loc [ Pp. text message ]
108
+ | Ok (sexp , positions ) ->
109
+ (match Parsexp.Conv_single. conv (sexp, positions) Dunolint.Config. t_of_sexp with
110
+ | Ok t -> t
111
+ | Error of_sexp_error ->
112
+ let range =
113
+ match Parsexp.Of_sexp_error. location of_sexp_error with
114
+ | Some _ as range -> range
115
+ | None ->
116
+ (let sub = Parsexp.Of_sexp_error. sub_sexp of_sexp_error in
117
+ (match Parsexp.Positions. find_sub_sexp_phys positions sexp ~sub with
118
+ | Some _ as range -> range
119
+ | None -> None ))
120
+ [@ coverage off]
121
+ in
122
+ let loc =
123
+ match range with
124
+ | Some range -> loc_of_parsexp_range ~filename range
125
+ | None -> Loc. of_file ~path: (Fpath. v filename) [@ coverage off]
126
+ in
127
+ let message =
128
+ match Parsexp.Of_sexp_error. user_exn of_sexp_error with
129
+ | Failure str -> clean_up_error_message str
130
+ | exn -> Exn. to_string exn [@ coverage off]
131
+ in
132
+ Err. raise ~loc [ Pp. text message ])
133
+ ;;
0 commit comments