Skip to content

Commit a689f2e

Browse files
authored
Merge pull request #112 from mbarbin/fix-dune-version-parsing-error
Fix dune version parsing error
2 parents bee5a8d + 5cf4ca3 commit a689f2e

File tree

13 files changed

+116
-98
lines changed

13 files changed

+116
-98
lines changed

lib/dune_project_linter/src/dune_lang_version.ml

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,18 +28,28 @@ let create ~dune_lang_version = { dune_lang_version }
2828
let dune_lang_version t = t.dune_lang_version
2929
let set_dune_lang_version t ~dune_lang_version = t.dune_lang_version <- dune_lang_version
3030

31-
let read ~sexps_rewriter:_ ~field =
31+
let read ~sexps_rewriter ~field =
3232
match field with
33-
| Sexp.List [ Sexp.Atom "lang"; Sexp.Atom "dune"; Sexp.Atom version_string ] ->
33+
| Sexp.List [ Sexp.Atom "lang"; Sexp.Atom "dune"; (Sexp.Atom version_string as atom) ]
34+
->
3435
(* Parse version string like "3.17" into tuple (3, 17) *)
3536
(match String.split version_string ~on:'.' with
3637
| [ major_str; minor_str ] ->
3738
(match Int.of_string major_str, Int.of_string minor_str with
3839
| major, minor ->
3940
{ dune_lang_version = Dune_project.Dune_lang_version.create (major, minor) }
40-
| exception _ -> failwith ("Invalid version format: " ^ version_string))
41-
| _ -> failwith ("Expected VERSION.MINOR format, got: " ^ version_string))
42-
| _ -> failwith "Expected (lang dune VERSION) format"
41+
| exception _ ->
42+
Err.raise
43+
~loc:(Sexps_rewriter.loc sexps_rewriter atom)
44+
[ Pp.textf "Invalid version format: %S." version_string ])
45+
| _ ->
46+
Err.raise
47+
~loc:(Sexps_rewriter.loc sexps_rewriter atom)
48+
[ Pp.textf "Expected VERSION.MINOR format, got: %S." version_string ])
49+
| _ ->
50+
Err.raise
51+
~loc:(Sexps_rewriter.loc sexps_rewriter field)
52+
[ Pp.text "Expected (lang dune VERSION) format." ]
4353
;;
4454

4555
let write t =

lib/dune_project_linter/test/test__dune_lang_version.ml

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,23 +39,23 @@ let%expect_test "read/write" =
3939
test {| (lang dune 3.INVALID) |};
4040
[%expect
4141
{|
42-
Internal Error: Failure("Invalid version format: 3.INVALID")
43-
<backtrace disabled in tests>
44-
[125]
42+
File "dune-project", line 1, characters 12-21:
43+
Error: Invalid version format: "3.INVALID".
44+
[123]
4545
|}];
4646
test {| (lang dune invalid) |};
4747
[%expect
4848
{|
49-
Internal Error: Failure("Expected VERSION.MINOR format, got: invalid")
50-
<backtrace disabled in tests>
51-
[125]
49+
File "dune-project", line 1, characters 12-19:
50+
Error: Expected VERSION.MINOR format, got: "invalid".
51+
[123]
5252
|}];
5353
test {| (lang invalid 3.20) |};
5454
[%expect
5555
{|
56-
Internal Error: Failure("Expected (lang dune VERSION) format")
57-
<backtrace disabled in tests>
58-
[125]
56+
File "dune-project", line 1, characters 1-20:
57+
Error: Expected (lang dune VERSION) format.
58+
[123]
5959
|}];
6060
()
6161
;;

lib/dunolint_cli/src/cmd__lint.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ let main =
2323
Command.make
2424
~summary:"Lint project."
2525
(let open Command.Std in
26-
let+ dunolint_engine_config = Dunolint_engine.Config.arg
26+
let+ running_mode = Dunolint_engine.Running_mode.arg
2727
and+ () = Log_cli.set_config ()
2828
and+ config =
2929
Arg.named_opt [ "config" ] Param.file ~doc:"Path to dunolint config file."
@@ -39,7 +39,7 @@ let main =
3939
let config =
4040
Common_helpers.load_config_opt_exn ~config ~append_extra_rules:enforce
4141
in
42-
Dunolint_engine.run ~config:dunolint_engine_config
42+
Dunolint_engine.run ~running_mode
4343
@@ fun dunolint_engine ->
4444
Dunolint_engine.visit
4545
dunolint_engine

lib/dunolint_cli/src/linter.mli

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,6 @@ val lint_stanza
2727
-> return:[> `skip_subtree ] With_return.return
2828
-> unit
2929

30-
module Visitor_decision : sig
31-
type t =
32-
| Continue
33-
| Skip_subtree
34-
end
35-
3630
val visit_directory
3731
: dunolint_engine:Dunolint_engine.t
3832
-> config:Dunolint.Config.t

lib/dunolint_engine/src/dunolint_engine.ml

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ module Unix = UnixLabels
2424

2525
let src = Logs.Src.create "dunolint" ~doc:"dunolint"
2626

27-
module Config = Config
2827
module File_kind = File_kind
28+
module Running_mode = Running_mode
2929

3030
module Edited_file = struct
3131
(* Edited files are indexed by their path relative to the root_path provided
@@ -38,11 +38,13 @@ module Edited_file = struct
3838
end
3939

4040
type t =
41-
{ config : Config.t
41+
{ running_mode : Running_mode.t
4242
; edited_files : Edited_file.t Hashtbl.M(Relative_path).t
4343
}
4444

45-
let create ~config = { config; edited_files = Hashtbl.create (module Relative_path) }
45+
let create ~running_mode () =
46+
{ running_mode; edited_files = Hashtbl.create (module Relative_path) }
47+
;;
4648

4749
let file_exists ~path =
4850
match (Unix.stat (Relative_path.to_string path)).st_kind with
@@ -246,7 +248,7 @@ let rec mkdirs path =
246248
;;
247249

248250
let materialize t =
249-
let running_mode = Config.running_mode t.config in
251+
let running_mode = t.running_mode in
250252
let edited_files =
251253
Hashtbl.to_alist t.edited_files
252254
|> List.sort ~compare:(fun (p1, _) (p2, _) -> Relative_path.compare p1 p2)
@@ -425,12 +427,12 @@ let visit ?below (_ : t) ~f =
425427
visit [ [ root_path ] ]
426428
;;
427429
428-
let run ~config f =
429-
let t = create ~config in
430+
let run ~running_mode f =
431+
let t = create ~running_mode () in
430432
let result = f t in
431433
materialize t;
432434
let () =
433-
match Config.running_mode config with
435+
match running_mode with
434436
| Dry_run | Force_yes | Interactive -> ()
435437
| Check ->
436438
if not (Hashtbl.is_empty t.edited_files)

lib/dunolint_engine/src/dunolint_engine.mli

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
(*_ <http://www.gnu.org/licenses/> and <https://spdx.org>, respectively. *)
2020
(*_********************************************************************************)
2121

22-
module Config = Config
2322
module File_kind = File_kind
23+
module Running_mode = Running_mode
2424

2525
type t
2626

@@ -91,8 +91,8 @@ val lint_file
9191
val format_dune_file : new_contents:string -> string
9292

9393
(** This calls [f] once, registers all requests enqueued during the execution of
94-
[f], and then depending on the config, either do a dry-run, or actually
95-
perform the desired transformations.
94+
[f], and then depending on the running mode, either do a dry-run, or
95+
actually perform the desired transformations.
9696
9797
The intended use is for [f] to contain one or several calls to a function
9898
that uses [t] to perform some dunolint linting, such as [visit],
@@ -104,11 +104,11 @@ val format_dune_file : new_contents:string -> string
104104
In addition to enqueuing debug messages and errors, this function outputs
105105
messages regarding I/O actions executed during linting. These messages are
106106
produced onto [stdout]. *)
107-
val run : config:Config.t -> (t -> 'a) -> 'a
107+
val run : running_mode:Running_mode.t -> (t -> 'a) -> 'a
108108

109109
(** {1 Step by step API} *)
110110

111-
val create : config:Config.t -> t
111+
val create : running_mode:Running_mode.t -> unit -> t
112112

113113
(** Apply all the changes that have been saved into [t] to the file system, or
114114
merely print them if we're in dry-run mode. *)

lib/dunolint_engine/src/config.ml renamed to lib/dunolint_engine/src/running_mode.ml

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,26 +19,20 @@
1919
(* <http://www.gnu.org/licenses/> and <https://spdx.org>, respectively. *)
2020
(*********************************************************************************)
2121

22-
module Running_mode = struct
23-
type t =
24-
| Dry_run
25-
| Check
26-
| Force_yes
27-
| Interactive
28-
[@@deriving compare, equal, sexp_of]
29-
end
22+
type t =
23+
| Dry_run
24+
| Check
25+
| Force_yes
26+
| Interactive
27+
[@@deriving compare, equal, sexp_of]
3028

31-
type t = { running_mode : Running_mode.t } [@@deriving sexp_of]
32-
33-
let default = { running_mode = Interactive }
34-
let running_mode t = t.running_mode
35-
let create ~running_mode = { running_mode }
29+
let default = Interactive
3630

3731
let arg =
3832
let open Command.Std in
3933
let running_mode
4034
((switch :: _ : _ Command.Nonempty_list.t) as switches)
41-
~(running_mode : Running_mode.t)
35+
~(running_mode : t)
4236
~doc
4337
=
4438
Arg.flag switches ~doc
@@ -74,7 +68,7 @@ let arg =
7468
Exit with a non-zero exit code in case some linting changes are required. This \
7569
execution mode is meant for scripts and CI pipelines."
7670
in
77-
let running_mode : Running_mode.t =
71+
let running_mode : t =
7872
match List.filter_opt [ dry_run; interactive; yes; check ] with
7973
| [] -> if Unix.isatty Unix.stdout then Interactive [@coverage off] else Force_yes
8074
| [ (_, mode) ] -> mode
@@ -90,5 +84,5 @@ let arg =
9084
(* [@coverage off] is due to out edge instrumentation, but this
9185
case is exercised during the tests. *)
9286
in
93-
{ running_mode }
87+
running_mode
9488
;;

lib/dunolint_engine/src/config.mli renamed to lib/dunolint_engine/src/running_mode.mli

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,12 @@
1919
(*_ <http://www.gnu.org/licenses/> and <https://spdx.org>, respectively. *)
2020
(*_********************************************************************************)
2121

22-
type t [@@deriving sexp_of]
22+
type t =
23+
| Dry_run
24+
| Check
25+
| Force_yes
26+
| Interactive
27+
[@@deriving compare, equal, sexp_of]
2328

2429
val default : t
2530
val arg : t Cmdlang.Command.Arg.t
26-
27-
(** {1 Getters} *)
28-
29-
module Running_mode : sig
30-
type t =
31-
| Dry_run
32-
| Check
33-
| Force_yes
34-
| Interactive
35-
[@@deriving compare, equal, sexp_of]
36-
end
37-
38-
val running_mode : t -> Running_mode.t
39-
40-
(** {1 Create} *)
41-
42-
val create : running_mode:Running_mode.t -> t

lib/dunolint_engine/test/test__dunolint_engine.ml

Lines changed: 6 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,7 @@ open Dunolint.Config.Std
2323
module Unix = UnixLabels
2424

2525
let%expect_test "lint" =
26-
let t =
27-
Dunolint_engine.create ~config:(Dunolint_engine.Config.create ~running_mode:Dry_run)
28-
in
26+
let t = Dunolint_engine.create ~running_mode:Dry_run () in
2927
Out_channel.write_all
3028
"dune-project"
3129
~data:
@@ -149,9 +147,7 @@ let%expect_test "format_dune_file" =
149147

150148
let%expect_test "create-files" =
151149
(* The engine may be used to create files where they are not initially present. *)
152-
let t =
153-
Dunolint_engine.create ~config:(Dunolint_engine.Config.create ~running_mode:Force_yes)
154-
in
150+
let t = Dunolint_engine.create ~running_mode:Force_yes () in
155151
Dunolint_engine.lint_file t ~path:(Relative_path.v "lib/a/dune") ~create_file:(fun () ->
156152
let library = Dune_linter.Library.create ~name:(Dune.Library.Name.v "my-lib") () in
157153
Sexp.to_string_mach (Dune_linter.Library.write library));
@@ -208,9 +204,7 @@ let%expect_test "create-files" =
208204

209205
let%expect_test "lint-absent-files" =
210206
(* By default, [lint-file] will not create a file if no initializer is supplied. *)
211-
let t =
212-
Dunolint_engine.create ~config:(Dunolint_engine.Config.create ~running_mode:Force_yes)
213-
in
207+
let t = Dunolint_engine.create ~running_mode:Force_yes () in
214208
Dunolint_engine.lint_file t ~path:(Relative_path.v "absent/file/dune");
215209
[%expect {||}];
216210
Err.For_test.protect (fun () -> Dunolint_engine.materialize t);
@@ -237,9 +231,7 @@ let%expect_test "invalid files" =
237231
(* When encountering invalid files during linting, errors are reported, but
238232
the execution continues so other valid files are still linted. *)
239233
Err.For_test.protect (fun () ->
240-
let t =
241-
Dunolint_engine.create ~config:(Dunolint_engine.Config.create ~running_mode:Dry_run)
242-
in
234+
let t = Dunolint_engine.create ~running_mode:Dry_run () in
243235
Unix.mkdir "invalid" ~perm:0o755;
244236
Out_channel.write_all
245237
"dune-project"
@@ -295,9 +287,7 @@ let%expect_test "invalid files" =
295287

296288
let%expect_test "file errors" =
297289
Unix.mkdir "tempdir" ~perm:0o755;
298-
let t =
299-
Dunolint_engine.create ~config:(Dunolint_engine.Config.create ~running_mode:Force_yes)
300-
in
290+
let t = Dunolint_engine.create ~running_mode:Force_yes () in
301291
(* If you are trying to lint a path that is not a regular file, you get an
302292
error right away rather than during [materialize]. *)
303293
Err.For_test.protect (fun () ->
@@ -314,9 +304,7 @@ let%expect_test "file errors" =
314304
;;
315305

316306
let%expect_test "file-system errors" =
317-
let t =
318-
Dunolint_engine.create ~config:(Dunolint_engine.Config.create ~running_mode:Force_yes)
319-
in
307+
let t = Dunolint_engine.create ~running_mode:Force_yes () in
320308
Dunolint_engine.lint_file t ~path:(Relative_path.v "foo/file") ~create_file:(fun () ->
321309
"Hello File");
322310
(* Let's say [foo] gets created as a regular file in the interval. *)

lib/dunolint_engine/test/test__config.ml renamed to lib/dunolint_engine/test/test__running_mode.ml

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,12 @@
2121

2222
let eval_args args =
2323
let command =
24-
Cmdlang.Command.make Dunolint_engine.Config.arg ~summary:"Test eval-stdlib-runner."
24+
Cmdlang.Command.make
25+
Dunolint_engine.Running_mode.arg
26+
~summary:"Test eval-stdlib-runner."
2527
in
2628
match Cmdlang_stdlib_runner.eval command ~argv:(Array.of_list ("dunolint" :: args)) with
27-
| Ok t -> print_s [%sexp (t : Dunolint_engine.Config.t)]
29+
| Ok t -> print_s [%sexp (t : Dunolint_engine.Running_mode.t)]
2830
| Error (`Help msg) -> print_endline msg [@coverage off]
2931
| Error (`Bad msg) ->
3032
(Stdlib.print_string msg;
@@ -40,15 +42,15 @@ let%expect_test "running modes" =
4042
This is indeed what happens during the expect-test, because it is run in a
4143
context where stdout is not a tty. *)
4244
eval_args [];
43-
[%expect {| ((running_mode Force_yes)) |}];
45+
[%expect {| Force_yes |}];
4446
(* The interactive mode can be forced. *)
4547
eval_args [ "--interactive" ];
46-
[%expect {| ((running_mode Interactive)) |}];
48+
[%expect {| Interactive |}];
4749
(* There are other running modes available. *)
4850
eval_args [ "--check" ];
49-
[%expect {| ((running_mode Check)) |}];
51+
[%expect {| Check |}];
5052
eval_args [ "--dry-run" ];
51-
[%expect {| ((running_mode Dry_run)) |}];
53+
[%expect {| Dry_run |}];
5254
(* But they are mutually exclusive. *)
5355
eval_args [ "--check"; "--dry-run" ];
5456
[%expect
@@ -61,8 +63,8 @@ let%expect_test "running modes" =
6163

6264
let%expect_test "create" =
6365
(* The API lets you create config programmatically. *)
64-
let t = Dunolint_engine.Config.create ~running_mode:Dry_run in
65-
print_s [%sexp (t : Dunolint_engine.Config.t)];
66-
[%expect {| ((running_mode Dry_run)) |}];
66+
let t = Dunolint_engine.Running_mode.Dry_run in
67+
print_s [%sexp (t : Dunolint_engine.Running_mode.t)];
68+
[%expect {| Dry_run |}];
6769
()
6870
;;

0 commit comments

Comments
 (0)