From de16f02aabe0caf464308aab174e48cd465ae903 Mon Sep 17 00:00:00 2001 From: Ali Caglayan Date: Mon, 15 Dec 2025 11:09:16 +0000 Subject: [PATCH 1/2] test(cram): change >> in continuation test to unit test Signed-off-by: Ali Caglayan --- .../test-cases/cram/conflict-marker-lexer-error.t | 13 ------------- test/expect-tests/dune_rules/cram_parsing_tests.ml | 8 ++++++++ 2 files changed, 8 insertions(+), 13 deletions(-) delete mode 100644 test/blackbox-tests/test-cases/cram/conflict-marker-lexer-error.t diff --git a/test/blackbox-tests/test-cases/cram/conflict-marker-lexer-error.t b/test/blackbox-tests/test-cases/cram/conflict-marker-lexer-error.t deleted file mode 100644 index ac56e79ea9f..00000000000 --- a/test/blackbox-tests/test-cases/cram/conflict-marker-lexer-error.t +++ /dev/null @@ -1,13 +0,0 @@ - - $ cat >dune-project < (lang dune 3.21) - > EOF - - $ cat > t1.t <<'EOF' - > $ echo '>> Hello' - > >> Hello - > EOF - $ dune runtest 2>&1 | grep -i "\(I must not crash\|exn =\)" - { exn = "Failure(\"lexing: empty token\")" }) - I must not crash. Uncertainty is the mind-killer. Exceptions are the - diff --git a/test/expect-tests/dune_rules/cram_parsing_tests.ml b/test/expect-tests/dune_rules/cram_parsing_tests.ml index 5cfe28b1365..3378972622f 100644 --- a/test/expect-tests/dune_rules/cram_parsing_tests.ml +++ b/test/expect-tests/dune_rules/cram_parsing_tests.ml @@ -473,3 +473,11 @@ let%expect_test "single-space comment after output" = } |}] ;; + +(* Test for https://github.com/ocaml/dune/pull/12963: >> in output confused the + lexer *) +let%expect_test "output resembling conflict marker" = + test " $ echo '>> Hello'\n >> Hello"; + [%expect.unreachable] +[@@expect.uncaught_exn {| (Failure "lexing: empty token") |}] +;; From 0491d4d478f7b463ff62d12055c84b0c94fd0874 Mon Sep 17 00:00:00 2001 From: Ali Caglayan Date: Mon, 15 Dec 2025 11:09:16 +0000 Subject: [PATCH 2/2] fix(cram): allow output to begin with >> Signed-off-by: Ali Caglayan --- src/dune_rules/cram/cram_lexer.mll | 8 ++++++-- test/expect-tests/dune_rules/cram_parsing_tests.ml | 14 ++++++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/dune_rules/cram/cram_lexer.mll b/src/dune_rules/cram/cram_lexer.mll index 7ad86800c1d..a88b61243d0 100644 --- a/src/dune_rules/cram/cram_lexer.mll +++ b/src/dune_rules/cram/cram_lexer.mll @@ -135,9 +135,13 @@ and command_cont loc acc = parse | " > " ([^'\n']* as str) { let loc = Loc.set_stop loc (Lexing.lexeme_end_p lexbuf) in eol_then_continue_or_finish loc str acc lexbuf } - | " >" + | " >" '\n' + { let loc = Loc.set_stop loc (pos_before_newline lexbuf) in + Lexing.new_line lexbuf; + command_cont loc ("" :: acc) lexbuf } + | " >" eof { let loc = Loc.set_stop loc (Lexing.lexeme_end_p lexbuf) in - eol_then_continue_or_finish loc "" acc lexbuf } + (loc, Command (List.rev ("" :: acc))) } | "" { (loc, Command (List.rev acc)) } diff --git a/test/expect-tests/dune_rules/cram_parsing_tests.ml b/test/expect-tests/dune_rules/cram_parsing_tests.ml index 3378972622f..0847d048bf2 100644 --- a/test/expect-tests/dune_rules/cram_parsing_tests.ml +++ b/test/expect-tests/dune_rules/cram_parsing_tests.ml @@ -478,6 +478,16 @@ let%expect_test "single-space comment after output" = lexer *) let%expect_test "output resembling conflict marker" = test " $ echo '>> Hello'\n >> Hello"; - [%expect.unreachable] -[@@expect.uncaught_exn {| (Failure "lexing: empty token") |}] + [%expect + {| + File "test.t", line 1, characters 2-19: + 1 | $ echo '>> Hello' + ^^^^^^^^^^^^^^^^^ + + Command [ "echo '>> Hello'" ] + { pos_fname = "test.t" + ; start = { pos_lnum = 1; pos_bol = 0; pos_cnum = 2 } + ; stop = { pos_lnum = 1; pos_bol = 0; pos_cnum = 19 } + } + |}] ;;