From cdcf09e9b54b788778a0960abb1512b895b604c6 Mon Sep 17 00:00:00 2001 From: Ali Caglayan Date: Thu, 23 Oct 2025 10:25:02 +0200 Subject: [PATCH 1/2] test: repro case for #8075 Signed-off-by: Ali Caglayan --- test/blackbox-tests/test-cases/promote/dune | 3 ++ .../promote/symlink-to-nonexistent.t | 44 +++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 test/blackbox-tests/test-cases/promote/dune create mode 100644 test/blackbox-tests/test-cases/promote/symlink-to-nonexistent.t diff --git a/test/blackbox-tests/test-cases/promote/dune b/test/blackbox-tests/test-cases/promote/dune new file mode 100644 index 00000000000..4e0194090f2 --- /dev/null +++ b/test/blackbox-tests/test-cases/promote/dune @@ -0,0 +1,3 @@ +(cram + (applies_to symlink-to-nonexistent) + (deps %{bin:git} ../git-helpers.sh)) diff --git a/test/blackbox-tests/test-cases/promote/symlink-to-nonexistent.t b/test/blackbox-tests/test-cases/promote/symlink-to-nonexistent.t new file mode 100644 index 00000000000..f5a5cdcf03b --- /dev/null +++ b/test/blackbox-tests/test-cases/promote/symlink-to-nonexistent.t @@ -0,0 +1,44 @@ +Tests for promoting with symlink to non-existent file. + + $ cat > dune-project < (lang dune 3.21) + > EOF + $ cp dune-project dune-workspace + + $ cat > dune < (rule + > (with-stdout-to "x.gen" + > (echo "toto"))) + > (rule + > (alias bench) + > (action + > (diff promoted x.gen))) + > EOF + +Unset INSIDE_DUNE in order to choose the "git diff" diff algorithm. Root +detection will now be automatic so a dune-workspace file was included above. + $ unset INSIDE_DUNE + +The "git diff" command that dune will run will unfortunately go looking for a +`.git` root. We therefore initialise a git repo to avoid this from escaping the +test. + $ . ../git-helpers.sh + $ git init -q + +This should fail initially but not with the "Unable to resolve symlink" error. + $ dune build @bench + File "dune", lines 4-7, characters 0-55: + 4 | (rule + 5 | (alias bench) + 6 | (action + 7 | (diff promoted x.gen))) + Error: Unable to resolve symlink _build/default/promoted + [1] + +Promotion should work + $ dune promote + Promoting _build/default/x.gen to promoted. + + $ cat promoted + toto + From 20d258043d62fdb35e648d50805d398b6b4002dd Mon Sep 17 00:00:00 2001 From: Ali Caglayan Date: Thu, 23 Oct 2025 11:05:45 +0200 Subject: [PATCH 2/2] fix: promotion over non-existent file When we use "git diff" as the git tool, we have some logic to resolve symlinks since "git diff" doesn't handle them. This logic doesn't take into account the case where the target of a symlink doesn't exist, which happens when the file you are promoting doesn't exist yet. This can easily be fixed by taking into account this case. Signed-off-by: Ali Caglayan --- doc/changes/fixed/12615.md | 2 ++ src/promote/print_diff.ml | 8 ++++++-- .../test-cases/promote/symlink-to-nonexistent.t | 12 ++++++------ 3 files changed, 14 insertions(+), 8 deletions(-) create mode 100644 doc/changes/fixed/12615.md diff --git a/doc/changes/fixed/12615.md b/doc/changes/fixed/12615.md new file mode 100644 index 00000000000..a6b9792ed5d --- /dev/null +++ b/doc/changes/fixed/12615.md @@ -0,0 +1,2 @@ +- Fix a bug where dune was unable to promote over non-existant files in certain + cases (#12615, fixes #8075, @Alizter) diff --git a/src/promote/print_diff.ml b/src/promote/print_diff.ml index a7331ef3077..bd9172ed601 100644 --- a/src/promote/print_diff.ml +++ b/src/promote/print_diff.ml @@ -13,8 +13,12 @@ let resolve_link_for_git path = "Unable to resolve symlink %s. Max recursion depth exceeded" (Path.to_string path) ] - | Error (Unix_error _) -> - User_error.raise [ Pp.textf "Unable to resolve symlink %s" (Path.to_string path) ] + | Error (Unix_error (ENOENT, _, _)) -> path + | Error (Unix_error err) -> + User_error.raise + [ Pp.textf "Unable to resolve symlink %s" (Path.to_string path) + ; Unix_error.Detailed.pp err + ] ;; module Diff = struct diff --git a/test/blackbox-tests/test-cases/promote/symlink-to-nonexistent.t b/test/blackbox-tests/test-cases/promote/symlink-to-nonexistent.t index f5a5cdcf03b..ea134e8dee6 100644 --- a/test/blackbox-tests/test-cases/promote/symlink-to-nonexistent.t +++ b/test/blackbox-tests/test-cases/promote/symlink-to-nonexistent.t @@ -27,12 +27,12 @@ test. This should fail initially but not with the "Unable to resolve symlink" error. $ dune build @bench - File "dune", lines 4-7, characters 0-55: - 4 | (rule - 5 | (alias bench) - 6 | (action - 7 | (diff promoted x.gen))) - Error: Unable to resolve symlink _build/default/promoted + File "promoted", line 1, characters 0-0: + ------ /dev/null + ++++++ x.gen + File "/dev/null", line 1, characters 0-1: + +|toto + No newline at the end of x.gen [1] Promotion should work