This commit is contained in:
parent
aa2ff7b2f0
commit
2f3113f55d
11742 changed files with 1223940 additions and 0 deletions
|
|
@ -0,0 +1,79 @@
|
|||
Basic tests for the file-watching mode.
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
----------------------------------------------------------------------------------
|
||||
* Compile a simple rule
|
||||
|
||||
$ echo "(lang dune 2.0)" > dune-project
|
||||
|
||||
$ cat > x <<EOF
|
||||
> original-contents
|
||||
> EOF
|
||||
|
||||
$ cat >dune <<EOF
|
||||
> (rule
|
||||
> (target y)
|
||||
> (deps x)
|
||||
> (action (system "cat x > y")))
|
||||
> EOF
|
||||
|
||||
$ start_dune
|
||||
|
||||
$ build y
|
||||
Success
|
||||
$ cat _build/default/y
|
||||
original-contents
|
||||
|
||||
$ echo new-contents > x
|
||||
|
||||
$ build y
|
||||
Success
|
||||
$ cat _build/default/y
|
||||
new-contents
|
||||
|
||||
$ echo new-contents2 > x
|
||||
|
||||
$ build y
|
||||
Success
|
||||
$ cat _build/default/y
|
||||
new-contents2
|
||||
|
||||
----------------------------------------------------------------------------------
|
||||
* File rename
|
||||
|
||||
$ mv x z
|
||||
$ build y
|
||||
Failure
|
||||
|
||||
$ echo new-contents3 > z
|
||||
|
||||
$ build y
|
||||
Failure
|
||||
|
||||
$ mv z x
|
||||
$ build y
|
||||
Success
|
||||
$ cat _build/default/y
|
||||
new-contents3
|
||||
|
||||
$ with_timeout dune shutdown
|
||||
$ cat .#dune-output
|
||||
Success, waiting for filesystem changes...
|
||||
Success, waiting for filesystem changes...
|
||||
Success, waiting for filesystem changes...
|
||||
File "dune", lines 1-4, characters 0-59:
|
||||
1 | (rule
|
||||
2 | (target y)
|
||||
3 | (deps x)
|
||||
4 | (action (system "cat x > y")))
|
||||
Error: No rule found for x
|
||||
Had 1 error, waiting for filesystem changes...
|
||||
File "dune", lines 1-4, characters 0-59:
|
||||
1 | (rule
|
||||
2 | (target y)
|
||||
3 | (deps x)
|
||||
4 | (action (system "cat x > y")))
|
||||
Error: No rule found for x
|
||||
Had 1 error, waiting for filesystem changes...
|
||||
Success, waiting for filesystem changes...
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
Test rules that copy source files in file-watching mode.
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
$ echo '(lang dune 3.0)' > dune-project
|
||||
$ cat > dune <<EOF
|
||||
> (rule
|
||||
> (deps (glob_files *.txt))
|
||||
> (target summary)
|
||||
> (action (system "cat %{deps} > %{target}")))
|
||||
> EOF
|
||||
$ echo a > a.txt
|
||||
|
||||
$ start_dune
|
||||
|
||||
$ build summary
|
||||
Success
|
||||
$ cat _build/default/summary
|
||||
a
|
||||
|
||||
Add [b.txt] manually. Dune notices this.
|
||||
|
||||
$ echo b > b.txt
|
||||
$ build summary
|
||||
Success
|
||||
$ cat _build/default/summary
|
||||
a
|
||||
b
|
||||
|
||||
Now add [c.txt] via a new rule. Note that we do not request [c.txt] to be built,
|
||||
only [summary], but Dune still builds it. Presumably, this isn't a bug but a
|
||||
consequence of using a glob in this directory, which forces all *.txt rules.
|
||||
|
||||
$ cat > dune <<EOF
|
||||
> (rule
|
||||
> (deps (glob_files *.txt))
|
||||
> (target summary)
|
||||
> (action (system "cat %{deps} > %{target}")))
|
||||
> (rule
|
||||
> (target c.txt)
|
||||
> (action (write-file %{target} "c\n")))
|
||||
> EOF
|
||||
|
||||
$ build summary
|
||||
Success
|
||||
$ cat _build/default/summary
|
||||
a
|
||||
b
|
||||
c
|
||||
|
||||
Dune notices that [d.txt] appears via promotion.
|
||||
|
||||
$ mkdir subdir
|
||||
$ cat > subdir/dune <<EOF
|
||||
> (rule
|
||||
> (target d.txt)
|
||||
> (mode (promote (into ..)))
|
||||
> (action (write-file %{target} "d\n")))
|
||||
> EOF
|
||||
$ build summary subdir/d.txt
|
||||
Success
|
||||
$ cat _build/default/summary
|
||||
a
|
||||
b
|
||||
c
|
||||
d
|
||||
|
||||
Note that [d.txt] is here but [c.txt] isn't (it's not promoted).
|
||||
|
||||
$ ls *.txt
|
||||
a.txt
|
||||
b.txt
|
||||
d.txt
|
||||
|
||||
We're done.
|
||||
|
||||
$ stop_dune
|
||||
Success, waiting for filesystem changes...
|
||||
Success, waiting for filesystem changes...
|
||||
Success, waiting for filesystem changes...
|
||||
Success, waiting for filesystem changes...
|
||||
|
|
@ -0,0 +1,152 @@
|
|||
Test directory target promotion in file-watching mode.
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
$ echo '(lang dune 3.0)' > dune-project
|
||||
$ mkdir test; cd test
|
||||
$ cat > dune-project <<EOF
|
||||
> (lang dune 3.0)
|
||||
> (using directory-targets 0.1)
|
||||
> EOF
|
||||
$ cat > dune <<EOF
|
||||
> (rule
|
||||
> (mode promote)
|
||||
> (deps src (sandbox always))
|
||||
> (targets (dir d1))
|
||||
> (action (system "mkdir -p d1/d2; cp src d1/a; cp src d1/b; cp src d1/d2/c")))
|
||||
> EOF
|
||||
|
||||
$ echo -n "*" > src
|
||||
$ start_dune
|
||||
|
||||
$ build d1
|
||||
Success
|
||||
$ cat d1/a d1/b d1/d2/c
|
||||
***
|
||||
|
||||
Change [src] and rebuild.
|
||||
|
||||
$ echo -n "+" > src
|
||||
$ build d1
|
||||
Success
|
||||
$ cat d1/a d1/b d1/d2/c
|
||||
+++
|
||||
|
||||
Remove a file and rebuild.
|
||||
|
||||
$ rm d1/a
|
||||
$ build d1
|
||||
Success
|
||||
$ cat d1/a d1/b d1/d2/c
|
||||
+++
|
||||
|
||||
Remove a directory and rebuild.
|
||||
|
||||
$ rm -rf d2
|
||||
$ build d1
|
||||
Success
|
||||
$ cat d1/a d1/b d1/d2/c
|
||||
+++
|
||||
|
||||
Modify a file and rebuild.
|
||||
|
||||
$ echo -n "*" > d1/b
|
||||
$ cat d1/a d1/b d1/d2/c
|
||||
+*+
|
||||
$ build d1
|
||||
Success
|
||||
$ cat d1/a d1/b d1/d2/c
|
||||
+++
|
||||
|
||||
Replace a directory with a file and rebuild.
|
||||
|
||||
$ rm -rf d1/d2
|
||||
$ touch d1/d2
|
||||
$ build d1
|
||||
Success
|
||||
$ cat d1/a d1/b d1/d2/c
|
||||
+++
|
||||
|
||||
Replace a file with a directory and rebuild.
|
||||
|
||||
$ rm d1/b
|
||||
$ mkdir -p d1/b
|
||||
$ build d1
|
||||
Success
|
||||
$ cat d1/a d1/b d1/d2/c
|
||||
+++
|
||||
|
||||
Add some unexpected files and directories and check that Dune deletes them.
|
||||
|
||||
$ mkdir -p d1/unexpected-dir-1
|
||||
$ mkdir -p d1/d2/unexpected-dir-2
|
||||
$ touch d1/unexpected-file-1
|
||||
$ touch d1/unexpected-dir-1/unexpected-file-2
|
||||
$ touch d1/d2/unexpected-file-3
|
||||
$ build d1
|
||||
Success
|
||||
$ cat d1/a d1/b d1/d2/c
|
||||
+++
|
||||
$ ls d1 | grep unexpected
|
||||
[1]
|
||||
$ ls d1/d2 | grep unexpected
|
||||
[1]
|
||||
|
||||
We're done.
|
||||
|
||||
$ stop_dune
|
||||
Success, waiting for filesystem changes...
|
||||
Success, waiting for filesystem changes...
|
||||
Success, waiting for filesystem changes...
|
||||
Success, waiting for filesystem changes...
|
||||
Success, waiting for filesystem changes...
|
||||
Success, waiting for filesystem changes...
|
||||
Success, waiting for filesystem changes...
|
||||
Success, waiting for filesystem changes...
|
||||
|
||||
Now test file-system events generated during directory target promotion.
|
||||
|
||||
$ rm -rf d1
|
||||
$ start_dune --debug-cache=fs
|
||||
$ build d1
|
||||
Success
|
||||
|
||||
$ stop_dune > .#debug-output
|
||||
|
||||
Show that Dune ignores the initial "dune-workspace" events (injected by Dune).
|
||||
|
||||
$ cat .#debug-output | grep dune-workspace
|
||||
Updating dir_contents cache for "dune-workspace": Skipped
|
||||
Updating file_digest cache for "dune-workspace": Skipped
|
||||
Updating path_stat cache for "dune-workspace": Updated { changed = false }
|
||||
|
||||
Dune correctly notices that the contents of . changed because [d1] was created.
|
||||
|
||||
$ cat .#debug-output | grep '"."'
|
||||
Updating dir_contents cache for ".": Updated { changed = true }
|
||||
Updating file_digest cache for ".": Skipped
|
||||
Updating path_stat cache for ".": Updated { changed = false }
|
||||
|
||||
|
||||
Here [path_stat] of [d1] changed, because it didn't exist before the build. Dune
|
||||
later recomputed [path_stat] once again, when [d1/b] was modified, and the
|
||||
result remained unchanged (because fields like [mtime] are ignored). The result
|
||||
of [dir_contents] also remained unchanged because Dune fixed the listing of [d1]
|
||||
by re-promoting the directory target.
|
||||
|
||||
$ cat .#debug-output | grep \"d1\"
|
||||
Updating dir_contents cache for "d1": Updated { changed = false }
|
||||
Updating file_digest cache for "d1": Skipped
|
||||
Updating path_stat cache for "d1": Updated { changed = true }
|
||||
Updating dir_contents cache for "d1": Updated { changed = false }
|
||||
Updating file_digest cache for "d1": Skipped
|
||||
Updating path_stat cache for "d1": Updated { changed = false }
|
||||
|
||||
Events below occurred because we replaced file [d1/b] with a directory. Dune
|
||||
undid this change to bring the promoted directory target up to date, which
|
||||
explains why [file_digest] remained unchanged.
|
||||
|
||||
$ cat .#debug-output | grep d1/b
|
||||
Updating dir_contents cache for "d1/b": Skipped
|
||||
Updating file_digest cache for "d1/b": Updated { changed = false }
|
||||
Updating path_stat cache for "d1/b": Skipped
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
Demonstrate running "dune promote" concurrently with a passive rpc server
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
$ echo '(lang dune 3.20)' > dune-project
|
||||
$ echo " $ echo hello" > my_test.t
|
||||
|
||||
$ start_dune
|
||||
|
||||
The test expectedly fails (see errors at the end of this file)
|
||||
$ build "(alias my_test)"
|
||||
Failure
|
||||
|
||||
Promotion happens on the running RPC server.
|
||||
$ dune promote
|
||||
Success
|
||||
|
||||
$ build "(alias my_test)"
|
||||
Success
|
||||
|
||||
$ stop_dune
|
||||
File "my_test.t", line 1, characters 0-0:
|
||||
Error: Files _build/default/my_test.t and _build/default/my_test.t.corrected
|
||||
differ.
|
||||
Had 1 error, waiting for filesystem changes...
|
||||
Promoting _build/default/my_test.t.corrected to my_test.t.
|
||||
Success, waiting for filesystem changes...
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
(cram
|
||||
(deps helpers.sh))
|
||||
|
||||
(cram
|
||||
; see https://github.com/ocaml/dune/pull/4728
|
||||
(enabled_if
|
||||
(<> "macosx" %{ocaml-config:system}))
|
||||
(applies_to * \ path-pwd))
|
||||
|
||||
(cram
|
||||
; see https://github.com/ocaml/dune/pull/4728
|
||||
(enabled_if
|
||||
(= "macosx" %{ocaml-config:system}))
|
||||
(applies_to path-pwd))
|
||||
|
||||
(cram
|
||||
(applies_to what-dune-watches)
|
||||
(deps %{bin:strace}))
|
||||
|
||||
;; These tests sometimes get stuck and time out:
|
||||
|
||||
(cram
|
||||
(applies_to
|
||||
watching-eager-concurrent-build-command
|
||||
watching-eager-concurrent-exec-command)
|
||||
(enabled_if false))
|
||||
|
|
@ -0,0 +1,467 @@
|
|||
Tests for [Fs_memo] module.
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
$ test () {
|
||||
> echo "------------------------------------------"
|
||||
> before=$(cat _build/default/result 2>/dev/null)
|
||||
> start_dune --debug-cache=fs
|
||||
> build . | grep -v Success
|
||||
> between=$(cat _build/default/result)
|
||||
> eval "$@"
|
||||
> build . | grep -v Success
|
||||
> stop_dune | grep -v dune-workspace >> .#tmp
|
||||
> after=$(cat _build/default/result)
|
||||
> cat .#tmp | grep -v Updating
|
||||
> echo "------------------------------------------"
|
||||
> echo "result = '$before' -> '$between' -> '$after'"
|
||||
> echo "------------------------------------------"
|
||||
> cat .#tmp | grep Updating | sort
|
||||
> rm .#tmp
|
||||
> }
|
||||
|
||||
The action ignores the dependency [dep]. We use it to force rerunning the action
|
||||
when necessary.
|
||||
|
||||
$ echo "(lang dune 2.0)" > dune-project
|
||||
$ cat >dune <<EOF
|
||||
> (rule
|
||||
> (alias default)
|
||||
> (deps dep
|
||||
> (glob_files file-?)
|
||||
> (glob_files dir/file-?)
|
||||
> (glob_files dir/subdir/file-?))
|
||||
> (target result)
|
||||
> (action (system "\| echo Executing rule...
|
||||
> "\| echo %{deps} |
|
||||
> "\| tr ' ' '\n' |
|
||||
> "\| xargs -n 1 |
|
||||
> "\| grep -v dep |
|
||||
> "\| xargs cat > result
|
||||
> )))
|
||||
> EOF
|
||||
|
||||
$ echo -n 1 > file-1
|
||||
$ touch dep
|
||||
|
||||
Note that we receive two events for [file-2] because it's first created empty
|
||||
and then the contents is written to it.
|
||||
|
||||
$ test "echo -n 2 > file-2"
|
||||
------------------------------------------
|
||||
Executing rule...
|
||||
Success, waiting for filesystem changes...
|
||||
Executing rule...
|
||||
Success, waiting for filesystem changes...
|
||||
------------------------------------------
|
||||
result = '' -> '1' -> '12'
|
||||
------------------------------------------
|
||||
Updating dir_contents cache for ".": Updated { changed = true }
|
||||
Updating dir_contents cache for "file-2": Skipped
|
||||
Updating dir_contents cache for "file-2": Skipped
|
||||
Updating file_digest cache for ".": Skipped
|
||||
Updating file_digest cache for "file-2": Skipped
|
||||
Updating file_digest cache for "file-2": Skipped
|
||||
Updating path_stat cache for ".": Updated { changed = false }
|
||||
Updating path_stat cache for "file-2": Skipped
|
||||
Updating path_stat cache for "file-2": Skipped
|
||||
|
||||
Note that Dune did not re-execute the rule because the set of files matching
|
||||
the glob remains unchanged.
|
||||
|
||||
$ test "mkdir dir"
|
||||
------------------------------------------
|
||||
Success, waiting for filesystem changes...
|
||||
Success, waiting for filesystem changes...
|
||||
------------------------------------------
|
||||
result = '12' -> '12' -> '12'
|
||||
------------------------------------------
|
||||
Updating dir_contents cache for ".": Updated { changed = true }
|
||||
Updating dir_contents cache for "dir": Skipped
|
||||
Updating file_digest cache for ".": Skipped
|
||||
Updating file_digest cache for "dir": Skipped
|
||||
Updating path_stat cache for ".": Updated { changed = false }
|
||||
Updating path_stat cache for "dir": Skipped
|
||||
|
||||
We create [dir/file-3] before running Dune, so we only observe a single
|
||||
[file_digest] change event with the file watcher.
|
||||
|
||||
$ echo -n '?' > dir/file-3
|
||||
$ test "echo -n 3 > dir/file-3"
|
||||
------------------------------------------
|
||||
Executing rule...
|
||||
Success, waiting for filesystem changes...
|
||||
Executing rule...
|
||||
Success, waiting for filesystem changes...
|
||||
------------------------------------------
|
||||
result = '12' -> '12?' -> '123'
|
||||
------------------------------------------
|
||||
Updating dir_contents cache for "dir/file-3": Skipped
|
||||
Updating file_digest cache for "dir/file-3": Updated { changed = true }
|
||||
Updating path_stat cache for "dir/file-3": Skipped
|
||||
|
||||
Now, Dune similarly updates [file_digest] for [file-2].
|
||||
|
||||
$ test "echo -n '*' > file-2"
|
||||
------------------------------------------
|
||||
Success, waiting for filesystem changes...
|
||||
Executing rule...
|
||||
Success, waiting for filesystem changes...
|
||||
------------------------------------------
|
||||
result = '123' -> '123' -> '1*3'
|
||||
------------------------------------------
|
||||
Updating dir_contents cache for "file-2": Skipped
|
||||
Updating file_digest cache for "file-2": Updated { changed = true }
|
||||
Updating path_stat cache for "file-2": Skipped
|
||||
|
||||
On deletion of a file, we receive events for the file and the parent directory.
|
||||
|
||||
$ test "rm file-2"
|
||||
------------------------------------------
|
||||
Success, waiting for filesystem changes...
|
||||
Executing rule...
|
||||
Success, waiting for filesystem changes...
|
||||
------------------------------------------
|
||||
result = '1*3' -> '1*3' -> '13'
|
||||
------------------------------------------
|
||||
Updating dir_contents cache for ".": Updated { changed = true }
|
||||
Updating dir_contents cache for "file-2": Skipped
|
||||
Updating file_digest cache for ".": Skipped
|
||||
Updating file_digest cache for "file-2": Updated { changed = true }
|
||||
Updating path_stat cache for ".": Updated { changed = false }
|
||||
Updating path_stat cache for "file-2": Skipped
|
||||
|
||||
Dune notices that [dir_contents] of both [dir] and [.] changed, and also that
|
||||
[dir/file-3]'s digest changed (from a digest to the error about missing file).
|
||||
|
||||
$ test "mv dir/file-3 ."
|
||||
------------------------------------------
|
||||
Success, waiting for filesystem changes...
|
||||
Executing rule...
|
||||
Success, waiting for filesystem changes...
|
||||
------------------------------------------
|
||||
result = '13' -> '13' -> '13'
|
||||
------------------------------------------
|
||||
Updating dir_contents cache for ".": Updated { changed = true }
|
||||
Updating dir_contents cache for "dir": Updated { changed = true }
|
||||
Updating dir_contents cache for "dir/file-3": Skipped
|
||||
Updating dir_contents cache for "file-3": Skipped
|
||||
Updating file_digest cache for ".": Skipped
|
||||
Updating file_digest cache for "dir": Skipped
|
||||
Updating file_digest cache for "dir/file-3": Updated { changed = true }
|
||||
Updating file_digest cache for "file-3": Skipped
|
||||
Updating path_stat cache for ".": Updated { changed = false }
|
||||
Updating path_stat cache for "dir": Updated { changed = false }
|
||||
Updating path_stat cache for "dir/file-3": Skipped
|
||||
Updating path_stat cache for "file-3": Skipped
|
||||
|
||||
$ test "mkdir dir/subdir"
|
||||
------------------------------------------
|
||||
Success, waiting for filesystem changes...
|
||||
Success, waiting for filesystem changes...
|
||||
------------------------------------------
|
||||
result = '13' -> '13' -> '13'
|
||||
------------------------------------------
|
||||
Updating dir_contents cache for "dir": Updated { changed = true }
|
||||
Updating dir_contents cache for "dir/subdir": Skipped
|
||||
Updating file_digest cache for "dir": Skipped
|
||||
Updating file_digest cache for "dir/subdir": Skipped
|
||||
Updating path_stat cache for "dir": Updated { changed = false }
|
||||
Updating path_stat cache for "dir/subdir": Skipped
|
||||
|
||||
Again, there are two events for [file-4]: for creation and modification.
|
||||
|
||||
$ test "echo -n 4 > dir/subdir/file-4"
|
||||
------------------------------------------
|
||||
Success, waiting for filesystem changes...
|
||||
Executing rule...
|
||||
Success, waiting for filesystem changes...
|
||||
------------------------------------------
|
||||
result = '13' -> '13' -> '134'
|
||||
------------------------------------------
|
||||
Updating dir_contents cache for "dir/subdir": Updated { changed = true }
|
||||
Updating dir_contents cache for "dir/subdir/file-4": Skipped
|
||||
Updating dir_contents cache for "dir/subdir/file-4": Skipped
|
||||
Updating file_digest cache for "dir/subdir": Skipped
|
||||
Updating file_digest cache for "dir/subdir/file-4": Skipped
|
||||
Updating file_digest cache for "dir/subdir/file-4": Skipped
|
||||
Updating path_stat cache for "dir/subdir": Updated { changed = false }
|
||||
Updating path_stat cache for "dir/subdir/file-4": Skipped
|
||||
Updating path_stat cache for "dir/subdir/file-4": Skipped
|
||||
|
||||
Here we are getting duplicate events for directories [dir] and [dir/subdir]
|
||||
because we watch each of them both directly and via their parents.
|
||||
|
||||
$ test "mv dir/subdir ."
|
||||
------------------------------------------
|
||||
Success, waiting for filesystem changes...
|
||||
Executing rule...
|
||||
Success, waiting for filesystem changes...
|
||||
------------------------------------------
|
||||
result = '134' -> '134' -> '13'
|
||||
------------------------------------------
|
||||
Updating dir_contents cache for ".": Updated { changed = true }
|
||||
Updating dir_contents cache for "dir": Updated { changed = false }
|
||||
Updating dir_contents cache for "dir": Updated { changed = true }
|
||||
Updating dir_contents cache for "dir/subdir": Updated { changed = false }
|
||||
Updating dir_contents cache for "dir/subdir": Updated { changed = true }
|
||||
Updating dir_contents cache for "subdir": Skipped
|
||||
Updating file_digest cache for ".": Skipped
|
||||
Updating file_digest cache for "dir": Skipped
|
||||
Updating file_digest cache for "dir": Skipped
|
||||
Updating file_digest cache for "dir/subdir": Skipped
|
||||
Updating file_digest cache for "dir/subdir": Skipped
|
||||
Updating file_digest cache for "subdir": Skipped
|
||||
Updating path_stat cache for ".": Updated { changed = false }
|
||||
Updating path_stat cache for "dir": Updated { changed = false }
|
||||
Updating path_stat cache for "dir": Updated { changed = false }
|
||||
Updating path_stat cache for "dir/subdir": Updated { changed = false }
|
||||
Updating path_stat cache for "dir/subdir": Updated { changed = true }
|
||||
Updating path_stat cache for "subdir": Skipped
|
||||
|
||||
This seems to be a bug: Dune doesn't notice that a directory's permission
|
||||
changed and succeeds instead of failing.
|
||||
|
||||
$ test "chmod -r subdir"
|
||||
------------------------------------------
|
||||
Success, waiting for filesystem changes...
|
||||
Success, waiting for filesystem changes...
|
||||
------------------------------------------
|
||||
result = '13' -> '13' -> '13'
|
||||
------------------------------------------
|
||||
|
||||
If we repeat the test, we finally see the failure.
|
||||
|
||||
# CR-someday amokhov: Fix this.
|
||||
|
||||
$ test "echo How about now?"
|
||||
------------------------------------------
|
||||
Failure
|
||||
How about now?
|
||||
Failure
|
||||
Error: inotify_add_watch(subdir): Permission denied
|
||||
Had 1 error, waiting for filesystem changes...
|
||||
Error: inotify_add_watch(subdir): Permission denied
|
||||
Had 1 error, waiting for filesystem changes...
|
||||
------------------------------------------
|
||||
result = '13' -> '13' -> '13'
|
||||
------------------------------------------
|
||||
|
||||
Same problem in the other direction.
|
||||
|
||||
$ test "chmod +r subdir"
|
||||
------------------------------------------
|
||||
Failure
|
||||
Failure
|
||||
Error: inotify_add_watch(subdir): Permission denied
|
||||
Had 1 error, waiting for filesystem changes...
|
||||
Error: inotify_add_watch(subdir): Permission denied
|
||||
Had 1 error, waiting for filesystem changes...
|
||||
------------------------------------------
|
||||
result = '13' -> '13' -> '13'
|
||||
------------------------------------------
|
||||
|
||||
$ test "echo How about now?"
|
||||
------------------------------------------
|
||||
How about now?
|
||||
Success, waiting for filesystem changes...
|
||||
Success, waiting for filesystem changes...
|
||||
------------------------------------------
|
||||
result = '13' -> '13' -> '13'
|
||||
------------------------------------------
|
||||
|
||||
Same problem for files.
|
||||
|
||||
$ test "chmod -r file-1"
|
||||
------------------------------------------
|
||||
Success, waiting for filesystem changes...
|
||||
Success, waiting for filesystem changes...
|
||||
------------------------------------------
|
||||
result = '13' -> '13' -> '13'
|
||||
------------------------------------------
|
||||
|
||||
$ test "chmod +r file-1"
|
||||
------------------------------------------
|
||||
Failure
|
||||
Failure
|
||||
Error: file-1: Permission denied
|
||||
-> required by _build/default/file-1
|
||||
-> required by _build/default/result
|
||||
-> required by alias default
|
||||
Had 1 error, waiting for filesystem changes...
|
||||
Error: file-1: Permission denied
|
||||
-> required by _build/default/file-1
|
||||
-> required by _build/default/result
|
||||
-> required by alias default
|
||||
Had 1 error, waiting for filesystem changes...
|
||||
------------------------------------------
|
||||
result = '13' -> '13' -> '13'
|
||||
------------------------------------------
|
||||
|
||||
Dune receives one event for [file-1] when moving it within the same directory,
|
||||
and two events for [file-5]: for moving and for changing. There are two events
|
||||
for [dir_contents] of [.] because moving a file is interpreted as deleting and
|
||||
then creating a file.
|
||||
|
||||
$ test "mv file-1 file-5; echo -n 5 > file-5"
|
||||
------------------------------------------
|
||||
Success, waiting for filesystem changes...
|
||||
Executing rule...
|
||||
Success, waiting for filesystem changes...
|
||||
------------------------------------------
|
||||
result = '13' -> '13' -> '35'
|
||||
------------------------------------------
|
||||
Updating dir_contents cache for ".": Updated { changed = false }
|
||||
Updating dir_contents cache for ".": Updated { changed = true }
|
||||
Updating dir_contents cache for "file-1": Skipped
|
||||
Updating dir_contents cache for "file-5": Skipped
|
||||
Updating dir_contents cache for "file-5": Skipped
|
||||
Updating file_digest cache for ".": Skipped
|
||||
Updating file_digest cache for ".": Skipped
|
||||
Updating file_digest cache for "file-1": Updated { changed = true }
|
||||
Updating file_digest cache for "file-5": Skipped
|
||||
Updating file_digest cache for "file-5": Skipped
|
||||
Updating path_stat cache for ".": Updated { changed = false }
|
||||
Updating path_stat cache for ".": Updated { changed = false }
|
||||
Updating path_stat cache for "file-1": Skipped
|
||||
Updating path_stat cache for "file-5": Skipped
|
||||
Updating path_stat cache for "file-5": Skipped
|
||||
|
||||
Tests for watching symbolic links.
|
||||
|
||||
First, create a symbolic link. Dune correctly updates the [result].
|
||||
|
||||
$ test "ln -s ../file-3 dir/file-6"
|
||||
------------------------------------------
|
||||
Success, waiting for filesystem changes...
|
||||
Executing rule...
|
||||
Success, waiting for filesystem changes...
|
||||
------------------------------------------
|
||||
result = '35' -> '35' -> '353'
|
||||
------------------------------------------
|
||||
Updating dir_contents cache for "dir": Updated { changed = true }
|
||||
Updating dir_contents cache for "dir/file-6": Skipped
|
||||
Updating file_digest cache for "dir": Skipped
|
||||
Updating file_digest cache for "dir/file-6": Skipped
|
||||
Updating path_stat cache for "dir": Updated { changed = false }
|
||||
Updating path_stat cache for "dir/file-6": Skipped
|
||||
|
||||
Now, delete the symbolic link. Dune receives the corresponding events and
|
||||
reruns the affected action.
|
||||
|
||||
$ test "rm dir/file-6"
|
||||
------------------------------------------
|
||||
Success, waiting for filesystem changes...
|
||||
Executing rule...
|
||||
Success, waiting for filesystem changes...
|
||||
------------------------------------------
|
||||
result = '353' -> '353' -> '35'
|
||||
------------------------------------------
|
||||
Updating dir_contents cache for "dir": Updated { changed = true }
|
||||
Updating dir_contents cache for "dir/file-6": Skipped
|
||||
Updating file_digest cache for "dir": Skipped
|
||||
Updating file_digest cache for "dir/file-6": Updated { changed = true }
|
||||
Updating path_stat cache for "dir": Updated { changed = false }
|
||||
Updating path_stat cache for "dir/file-6": Updated { changed = true }
|
||||
|
||||
Now test symbolic links to directories.
|
||||
|
||||
$ mkdir another-dir
|
||||
$ rmdir dir
|
||||
$ ln -s another-dir dir
|
||||
|
||||
At first, things appear to be working well: we correctly discover [dir/file-7]
|
||||
and re-execute the rule.
|
||||
|
||||
$ test "echo -n 7 > another-dir/file-7"
|
||||
------------------------------------------
|
||||
Success, waiting for filesystem changes...
|
||||
Executing rule...
|
||||
Success, waiting for filesystem changes...
|
||||
------------------------------------------
|
||||
result = '35' -> '35' -> '357'
|
||||
------------------------------------------
|
||||
Updating dir_contents cache for "dir": Updated { changed = true }
|
||||
Updating dir_contents cache for "dir/file-7": Skipped
|
||||
Updating dir_contents cache for "dir/file-7": Skipped
|
||||
Updating file_digest cache for "dir": Skipped
|
||||
Updating file_digest cache for "dir/file-7": Skipped
|
||||
Updating file_digest cache for "dir/file-7": Skipped
|
||||
Updating path_stat cache for "dir": Updated { changed = false }
|
||||
Updating path_stat cache for "dir/file-7": Skipped
|
||||
Updating path_stat cache for "dir/file-7": Skipped
|
||||
|
||||
Deleting [dir] triggers a rebuild.
|
||||
|
||||
$ test "rm dir"
|
||||
------------------------------------------
|
||||
Success, waiting for filesystem changes...
|
||||
Executing rule...
|
||||
Success, waiting for filesystem changes...
|
||||
------------------------------------------
|
||||
result = '357' -> '357' -> '35'
|
||||
------------------------------------------
|
||||
Updating dir_contents cache for ".": Updated { changed = true }
|
||||
Updating dir_contents cache for "dir": Updated { changed = true }
|
||||
Updating file_digest cache for ".": Skipped
|
||||
Updating file_digest cache for "dir": Skipped
|
||||
Updating path_stat cache for ".": Updated { changed = false }
|
||||
Updating path_stat cache for "dir": Updated { changed = true }
|
||||
|
||||
Restoring the symlink is correctly noticed.
|
||||
|
||||
$ test "ln -s another-dir dir"
|
||||
------------------------------------------
|
||||
Success, waiting for filesystem changes...
|
||||
Executing rule...
|
||||
Success, waiting for filesystem changes...
|
||||
------------------------------------------
|
||||
result = '35' -> '35' -> '357'
|
||||
------------------------------------------
|
||||
Updating dir_contents cache for ".": Updated { changed = true }
|
||||
Updating dir_contents cache for "dir": Skipped
|
||||
Updating file_digest cache for ".": Skipped
|
||||
Updating file_digest cache for "dir": Skipped
|
||||
Updating path_stat cache for ".": Updated { changed = false }
|
||||
Updating path_stat cache for "dir": Skipped
|
||||
|
||||
However, deleting [another-dir] isn't handled correctly.
|
||||
|
||||
# CR-someday amokhov: Fix this.
|
||||
|
||||
$ test "rm another-dir/file-7; sleep 0.001; rmdir another-dir"
|
||||
------------------------------------------
|
||||
Success, waiting for filesystem changes...
|
||||
Executing rule...
|
||||
Success, waiting for filesystem changes...
|
||||
------------------------------------------
|
||||
result = '357' -> '357' -> '35'
|
||||
------------------------------------------
|
||||
Updating dir_contents cache for ".": Updated { changed = true }
|
||||
Updating dir_contents cache for "another-dir": Updated { changed = true }
|
||||
Updating dir_contents cache for "dir": Updated { changed = true }
|
||||
Updating dir_contents cache for "dir/file-7": Skipped
|
||||
Updating file_digest cache for ".": Skipped
|
||||
Updating file_digest cache for "another-dir": Skipped
|
||||
Updating file_digest cache for "dir": Skipped
|
||||
Updating file_digest cache for "dir/file-7": Updated { changed = true }
|
||||
Updating path_stat cache for ".": Updated { changed = false }
|
||||
Updating path_stat cache for "another-dir": Updated { changed = true }
|
||||
Updating path_stat cache for "dir": Updated { changed = false }
|
||||
Updating path_stat cache for "dir/file-7": Skipped
|
||||
|
||||
If we force a rebuild, Dune belatedly notices that [another-dir/file-7] is now
|
||||
unreachable but doesn't complain about the symlink [dir] now being broken. We
|
||||
should fix this too.
|
||||
|
||||
$ test "echo force > dep"
|
||||
------------------------------------------
|
||||
Success, waiting for filesystem changes...
|
||||
Executing rule...
|
||||
Success, waiting for filesystem changes...
|
||||
------------------------------------------
|
||||
result = '35' -> '35' -> '35'
|
||||
------------------------------------------
|
||||
Updating dir_contents cache for "dep": Skipped
|
||||
Updating file_digest cache for "dep": Updated { changed = true }
|
||||
Updating path_stat cache for "dep": Skipped
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
Reproduction case for #4923: weird things observed when we add/remove
|
||||
a file in watch mode.
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
$ echo '(lang dune 3.0)' > dune-project
|
||||
$ mkdir a b
|
||||
$ cat > a/dune <<EOF
|
||||
> (library (name a))
|
||||
> EOF
|
||||
$ cat > b/dune <<EOF
|
||||
> (library (name b))
|
||||
> EOF
|
||||
$ touch a/a.ml b/b.ml
|
||||
$ cat > dune <<EOF
|
||||
> (executable (name x) (libraries b))
|
||||
> EOF
|
||||
$ echo 'print_endline "Hello, world!"' > x.ml
|
||||
|
||||
$ start_dune
|
||||
|
||||
$ build x.exe
|
||||
Success
|
||||
$ _build/default/x.exe
|
||||
Hello, world!
|
||||
|
||||
In the past, adding a new file while Dune was running in watching mode
|
||||
was corrupting Dune's internal state. For instance, here it no longer
|
||||
knew how to build x.exe. This is now fixed.
|
||||
|
||||
$ touch b/blah
|
||||
|
||||
$ build x.exe
|
||||
Success
|
||||
$ _build/default/x.exe
|
||||
Hello, world!
|
||||
|
||||
$ stop_dune
|
||||
Success, waiting for filesystem changes...
|
||||
Success, waiting for filesystem changes...
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
A test case for #5064: errors when changing module dependencies in the
|
||||
file-watching mode.
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
$ echo '(lang dune 3.0)' > dune-project
|
||||
$ mkdir lib
|
||||
$ cat > lib/dune <<EOF
|
||||
> (library (name lib))
|
||||
> EOF
|
||||
$ cat > dune <<EOF
|
||||
> (executable (name x) (libraries lib))
|
||||
> EOF
|
||||
$ echo 'let hello = "Hello"' > lib/a.ml
|
||||
$ echo 'let world = "World"' > lib/b.ml
|
||||
$ echo 'let message = A.hello ^ ", " ^ B.world' > lib/lib.ml
|
||||
|
||||
$ echo 'print_endline Lib.message' > x.ml
|
||||
|
||||
$ start_dune
|
||||
|
||||
$ build x.exe
|
||||
Success
|
||||
$ _build/default/x.exe
|
||||
Hello, World
|
||||
|
||||
Now let's make [lib/a.ml] depend on [lib/b.ml]. It doesn't work!
|
||||
|
||||
$ cat > lib/a.ml <<EOF
|
||||
> let _ = B.world
|
||||
> let hello = "Hello"
|
||||
> EOF
|
||||
|
||||
$ build x.exe
|
||||
Success
|
||||
|
||||
Let's try a manual restart.
|
||||
|
||||
$ stop_dune
|
||||
Success, waiting for filesystem changes...
|
||||
Success, waiting for filesystem changes...
|
||||
|
||||
$ start_dune
|
||||
|
||||
It works now!
|
||||
|
||||
$ build x.exe
|
||||
Success
|
||||
|
||||
We're done.
|
||||
|
||||
$ stop_dune
|
||||
Success, waiting for filesystem changes...
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
$ . ./helpers.sh
|
||||
|
||||
This test demonstrates a fixed bug where rules for .install are being duplicated between
|
||||
rebuilds.
|
||||
|
||||
$ cat > dune-project << EOF
|
||||
> (lang dune 3.11)
|
||||
> (package
|
||||
> (allow_empty)
|
||||
> (name test))
|
||||
> EOF
|
||||
|
||||
$ mkdir src
|
||||
|
||||
$ start_dune
|
||||
$ build .
|
||||
Success
|
||||
|
||||
$ cat > src/a
|
||||
|
||||
$ build .
|
||||
Success
|
||||
|
||||
$ stop_dune
|
||||
Success, waiting for filesystem changes...
|
||||
Success, waiting for filesystem changes...
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
$ . ./helpers.sh
|
||||
|
||||
This test demonstrates a bug where multiple rules for ccomp and .opam are loaded between
|
||||
rebuilds.
|
||||
|
||||
$ cat > dune-project << EOF
|
||||
> (lang dune 3.11)
|
||||
> (package
|
||||
> (allow_empty)
|
||||
> (name test))
|
||||
> (generate_opam_files true)
|
||||
> EOF
|
||||
|
||||
$ mkdir src
|
||||
|
||||
$ cat > src/dune << EOF
|
||||
> (library
|
||||
> (name dune_rpc_lwt_tests)
|
||||
> (foreign_stubs
|
||||
> (language c)
|
||||
> (names stub)))
|
||||
> EOF
|
||||
|
||||
$ cat > src/stub.c
|
||||
|
||||
$ start_dune
|
||||
$ build .
|
||||
Success
|
||||
|
||||
$ cat > src/a
|
||||
|
||||
$ build .
|
||||
Success
|
||||
|
||||
$ stop_dune
|
||||
Success, waiting for filesystem changes...
|
||||
Success, waiting for filesystem changes...
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
DUNE_RUNNING=0
|
||||
|
||||
start_dune () {
|
||||
((dune build "$@" --passive-watch-mode > .#dune-output 2>&1) || (echo exit $? >> .#dune-output)) &
|
||||
DUNE_PID=$!;
|
||||
DUNE_RUNNING=1;
|
||||
}
|
||||
|
||||
timeout="$(command -v timeout || echo gtimeout)"
|
||||
|
||||
with_timeout () {
|
||||
$timeout 2 "$@"
|
||||
exit_code=$?
|
||||
if [ "$exit_code" = 124 ]
|
||||
then
|
||||
echo Timed out
|
||||
cat .#dune-output
|
||||
else
|
||||
return "$exit_code"
|
||||
fi
|
||||
}
|
||||
|
||||
stop_dune () {
|
||||
with_timeout dune shutdown;
|
||||
# On Linux, we may run into a bash pid aliasing bug that causes wait to
|
||||
# reject the pid. Therefore we use tail to wait instead.
|
||||
if [ "$(uname -s)" = "Linux" ]
|
||||
then
|
||||
# wait for all child processes
|
||||
tail --pid=$DUNE_PID -f /dev/null;
|
||||
else
|
||||
# wait for dune to exit
|
||||
wait $DUNE_PID;
|
||||
fi
|
||||
cat .#dune-output;
|
||||
}
|
||||
|
||||
build () {
|
||||
with_timeout dune rpc build --wait "$@"
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
We test the behavior of watch mode when we have multiple errors
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
$ echo "(lang dune 3.11)" > dune-project
|
||||
|
||||
$ start_dune
|
||||
|
||||
$ cat > x <<EOF
|
||||
> not so
|
||||
> EOF
|
||||
|
||||
$ cat >dune <<EOF
|
||||
> (rule
|
||||
> (action
|
||||
> (progn
|
||||
> (write-file y "different")
|
||||
> (diff x y))))
|
||||
> (rule
|
||||
> (action
|
||||
> (progn
|
||||
> (write-file z "different")
|
||||
> (diff x z))))
|
||||
> (rule
|
||||
> (deps y z)
|
||||
> (action
|
||||
> (write-file w "")))
|
||||
> EOF
|
||||
|
||||
$ build w
|
||||
Failure
|
||||
|
||||
$ stop_dune
|
||||
File "x", line 1, characters 0-0:
|
||||
Error: Files _build/default/x and _build/default/y differ.
|
||||
File "x", line 1, characters 0-0:
|
||||
Error: Files _build/default/x and _build/default/z differ.
|
||||
Had 2 errors, waiting for filesystem changes...
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
This is a bug occur that occurs when we're running dune in watch mode and
|
||||
adding . to $CWD
|
||||
|
||||
Reproduce #6907
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
$ export PATH=.:$PATH
|
||||
$ echo "(lang dune 2.0)" > dune-project
|
||||
|
||||
$ start_dune
|
||||
|
||||
$ cat > x <<EOF
|
||||
> original-contents
|
||||
> EOF
|
||||
|
||||
$ cat >dune <<EOF
|
||||
> (rule (with-stdout-to y (echo %{read:x})))
|
||||
> EOF
|
||||
|
||||
$ build y
|
||||
Success
|
||||
|
||||
$ touch x
|
||||
|
||||
$ build y
|
||||
Success
|
||||
|
||||
$ stop_dune
|
||||
Success, waiting for filesystem changes...
|
||||
Success, waiting for filesystem changes...
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
Modify an input file during the build so that dune interrupts the
|
||||
build
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
$ echo "(lang dune 2.0)" > dune-project
|
||||
|
||||
$ cat > x <<EOF
|
||||
> original-contents
|
||||
> EOF
|
||||
|
||||
$ cat >dune <<'EOF'
|
||||
> (rule
|
||||
> (target y)
|
||||
> (deps x)
|
||||
> (action (bash "\> if [[ "$(cat x)" == unstable ]]; then
|
||||
> "\> touch ../../go-ahead
|
||||
> "\> sleep 1000
|
||||
> "\> exit 1
|
||||
> "\> else
|
||||
> "\> cat x > y
|
||||
> "\> fi
|
||||
> )))
|
||||
> EOF
|
||||
|
||||
The rule above makes the test hang if it sees an "unstable" state of
|
||||
the file. This makes it easy to make sure that the dune won't finish
|
||||
before we're able to cancel the build.
|
||||
|
||||
$ start_dune
|
||||
|
||||
$ build y
|
||||
Success
|
||||
$ cat _build/default/y
|
||||
original-contents
|
||||
|
||||
$ echo unstable > x
|
||||
|
||||
$ (dune_cmd wait-for-file-to-appear go-ahead; echo new-contents > x) & build y
|
||||
Success
|
||||
|
||||
$ cat _build/default/y
|
||||
new-contents
|
||||
|
||||
$ stop_dune
|
||||
Success, waiting for filesystem changes...
|
||||
Success, waiting for filesystem changes...
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
Modify an input file during the build so that Dune interrupts the build once.
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
Bad rule! You are not supposed to modify the source tree. No ice-cream for you!
|
||||
|
||||
$ mkdir test
|
||||
$ cd test
|
||||
|
||||
$ echo '(lang dune 3.0)' > dune-project
|
||||
$ cat > dune <<EOF
|
||||
> (rule
|
||||
> (deps (glob_files *.txt) (sandbox none))
|
||||
> (alias default)
|
||||
> (action (system "\| echo "I'm seeing: %{deps}" >> ../../../output
|
||||
> "\| touch ../../new-source.txt
|
||||
> )))
|
||||
> EOF
|
||||
|
||||
$ touch old-source.txt
|
||||
$ start_dune
|
||||
|
||||
$ build .
|
||||
Success
|
||||
|
||||
We can see in the output below that the rule ran exactly twice. Note that the
|
||||
file watcher generates the next touch event for new-source.txt but it
|
||||
is ignored because the contents of new-source.txt is the same,
|
||||
i.e. the empty file.
|
||||
|
||||
$ cat ../output
|
||||
I'm seeing: old-source.txt
|
||||
I'm seeing: new-source.txt old-source.txt
|
||||
|
||||
$ stop_dune
|
||||
Success, waiting for filesystem changes...
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
Test that Dune mkdirs the right set of directories in the sandbox.
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
----------------------------------------------------------------------------------
|
||||
* Compile a simple rule
|
||||
|
||||
$ echo "(lang dune 2.0)" > dune-project
|
||||
|
||||
$ mkdir test
|
||||
$ cat >test/dune <<EOF
|
||||
> (rule
|
||||
> (target target)
|
||||
> (mode promote)
|
||||
> (deps (sandbox always))
|
||||
> (action (chdir subdir (system "echo hello > ../target; pwd"))))
|
||||
> EOF
|
||||
|
||||
$ start_dune
|
||||
|
||||
$ build test/target
|
||||
Success
|
||||
$ cat test/target
|
||||
hello
|
||||
|
||||
Now force a rebuild. This succeeds (in the past it could fail due to [mkdir]
|
||||
memoization).
|
||||
|
||||
$ rm _build/default/test/target test/target
|
||||
$ build test
|
||||
Success
|
||||
|
||||
$ with_timeout dune shutdown
|
||||
$ cat .#dune-output | sed -e 's#.sandbox/[^/]*/default/test/subdir#.sandbox/<hash>/default/test/subdir#'
|
||||
$TESTCASE_ROOT/_build/.sandbox/<hash>/default/test/subdir
|
||||
Success, waiting for filesystem changes...
|
||||
$TESTCASE_ROOT/_build/.sandbox/<hash>/default/test/subdir
|
||||
Success, waiting for filesystem changes...
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
We demonstrate that dune can be turned off by sigpipe
|
||||
|
||||
$ echo '(lang dune 3.0)' > dune-project
|
||||
$ touch dout
|
||||
$ dune build --passive-watch-mode > dout 2>&1 &
|
||||
$ pid=$!
|
||||
$ kill -s PIPE $pid
|
||||
$ wait $pid
|
||||
[141]
|
||||
$ cat dout
|
||||
|
|
@ -0,0 +1,200 @@
|
|||
Test target promotion in file-watching mode.
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
$ echo '(lang dune 3.0)' > dune-project
|
||||
$ cat > dune <<EOF
|
||||
> (rule
|
||||
> (mode promote)
|
||||
> (deps original)
|
||||
> (target promoted)
|
||||
> (action (copy %{deps} %{target})))
|
||||
> (rule
|
||||
> (deps promoted)
|
||||
> (target result)
|
||||
> (action (system "cat promoted promoted > result")))
|
||||
> EOF
|
||||
$ echo hi > original
|
||||
|
||||
$ start_dune
|
||||
|
||||
$ build result
|
||||
Success
|
||||
$ cat promoted
|
||||
hi
|
||||
$ cat _build/default/result
|
||||
hi
|
||||
hi
|
||||
|
||||
Now change the [original] and rebuild.
|
||||
|
||||
$ echo bye > original
|
||||
$ build result
|
||||
Success
|
||||
$ cat promoted
|
||||
bye
|
||||
$ cat _build/default/result
|
||||
bye
|
||||
bye
|
||||
|
||||
Now try deleting the promoted file.
|
||||
|
||||
$ rm promoted
|
||||
$ build result
|
||||
Success
|
||||
$ cat promoted
|
||||
bye
|
||||
$ cat _build/default/result
|
||||
bye
|
||||
bye
|
||||
|
||||
Now try replacing its content.
|
||||
|
||||
$ echo hi > promoted
|
||||
$ build result
|
||||
Success
|
||||
$ cat promoted
|
||||
bye
|
||||
$ cat _build/default/result
|
||||
bye
|
||||
bye
|
||||
|
||||
Now switch the mode to standard. Dune reports an error about multiple rules for
|
||||
[_build/default/promoted], as expected (see the error at the end of the test).
|
||||
|
||||
$ cat > dune <<EOF
|
||||
> (rule
|
||||
> (mode standard)
|
||||
> (deps original)
|
||||
> (target promoted)
|
||||
> (action (copy %{deps} %{target})))
|
||||
> (rule
|
||||
> (deps promoted)
|
||||
> (target result)
|
||||
> (action (system "cat promoted promoted > result")))
|
||||
> EOF
|
||||
|
||||
$ build result
|
||||
Failure
|
||||
|
||||
We use the hint and it starts to work.
|
||||
|
||||
$ rm -f promoted
|
||||
$ build result
|
||||
Success
|
||||
$ cat promoted
|
||||
cat: promoted: No such file or directory
|
||||
[1]
|
||||
$ cat _build/default/promoted
|
||||
bye
|
||||
$ cat _build/default/result
|
||||
bye
|
||||
bye
|
||||
|
||||
Now use [fallback] to override the rule that generates [promoted].
|
||||
|
||||
$ cat > dune <<EOF
|
||||
> (rule
|
||||
> (mode fallback)
|
||||
> (deps original)
|
||||
> (target promoted)
|
||||
> (action (copy %{deps} %{target})))
|
||||
> (rule
|
||||
> (deps promoted)
|
||||
> (target result)
|
||||
> (action (system "cat promoted promoted > result")))
|
||||
> EOF
|
||||
|
||||
At first, we don't have the source, so the rule is used.
|
||||
|
||||
$ build result
|
||||
Success
|
||||
$ cat promoted
|
||||
cat: promoted: No such file or directory
|
||||
[1]
|
||||
$ cat _build/default/promoted
|
||||
bye
|
||||
$ cat _build/default/result
|
||||
bye
|
||||
bye
|
||||
|
||||
Now we create the source file and it overrides the rule.
|
||||
|
||||
$ echo hi > promoted
|
||||
$ build result
|
||||
Success
|
||||
$ cat promoted
|
||||
hi
|
||||
$ cat _build/default/promoted
|
||||
hi
|
||||
$ cat _build/default/result
|
||||
hi
|
||||
hi
|
||||
|
||||
We're done.
|
||||
|
||||
$ stop_dune
|
||||
Success, waiting for filesystem changes...
|
||||
Success, waiting for filesystem changes...
|
||||
Success, waiting for filesystem changes...
|
||||
Success, waiting for filesystem changes...
|
||||
Error: Multiple rules generated for _build/default/promoted:
|
||||
- dune:1
|
||||
- file present in source tree
|
||||
Hint: rm -f promoted
|
||||
Had 1 error, waiting for filesystem changes...
|
||||
Success, waiting for filesystem changes...
|
||||
Success, waiting for filesystem changes...
|
||||
Success, waiting for filesystem changes...
|
||||
|
||||
Now test file-system events generated during target promotion.
|
||||
|
||||
$ cat > dune <<EOF
|
||||
> (rule
|
||||
> (mode promote)
|
||||
> (deps original)
|
||||
> (target promoted)
|
||||
> (action (copy %{deps} %{target})))
|
||||
> (rule
|
||||
> (deps promoted)
|
||||
> (target result)
|
||||
> (action (system "cat promoted promoted > result")))
|
||||
> EOF
|
||||
|
||||
$ cat promoted
|
||||
hi
|
||||
$ start_dune --debug-cache=fs
|
||||
$ build result
|
||||
Success
|
||||
$ cat promoted
|
||||
bye
|
||||
|
||||
$ stop_dune > .#debug-output
|
||||
|
||||
Show that Dune ignores the initial "dune-workspace" events (injected by Dune).
|
||||
|
||||
$ cat .#debug-output | grep dune-workspace
|
||||
Updating dir_contents cache for "dune-workspace": Skipped
|
||||
Updating file_digest cache for "dune-workspace": Skipped
|
||||
Updating path_stat cache for "dune-workspace": Updated { changed = false }
|
||||
|
||||
Show that Dune ignores "promoted" events. Events for ".#promoted.dune-temp" are
|
||||
filtered out by Dune's file watcher and don't show up here. The [path_digest]
|
||||
event for [promoted] is more interesting: the file's content did change from "hi"
|
||||
to "bye" but Dune subscribed to it *after* making the promotion, precisely to
|
||||
avoid unnecessarily restarting after receiving the event that it caused itself.
|
||||
|
||||
$ cat .#debug-output | grep promoted
|
||||
Updating dir_contents cache for "promoted": Skipped
|
||||
Updating file_digest cache for "promoted": Updated { changed = false }
|
||||
Updating path_stat cache for "promoted": Skipped
|
||||
|
||||
Show that Dune ignores events for the . directory: [dir_contents] didn't change
|
||||
because [promoted] existed before running the build. Also, the subset of fields
|
||||
of [path_stat] that matter to Dune didn't change either (the [mtime] field did
|
||||
change but [fs_memo] does not provide a way to subscribe to it).
|
||||
|
||||
$ cat .#debug-output | grep '"."'
|
||||
Updating dir_contents cache for ".": Updated { changed = false }
|
||||
Updating file_digest cache for ".": Skipped
|
||||
Updating path_stat cache for ".": Updated { changed = false }
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
Test what happens in watch mode when we depend on dot files
|
||||
|
||||
$ . ./helpers.sh
|
||||
|
||||
$ echo '(lang dune 3.0)' > dune-project
|
||||
$ cat > dune <<EOF
|
||||
> (rule
|
||||
> (targets y)
|
||||
> (deps .x)
|
||||
> (action (system "cat .x > y")))
|
||||
> EOF
|
||||
|
||||
$ start_dune
|
||||
|
||||
$ echo 1 > .x
|
||||
$ build y
|
||||
Success
|
||||
$ cat _build/default/y
|
||||
1
|
||||
|
||||
$ echo 2 > .x
|
||||
$ build y
|
||||
Success
|
||||
$ cat _build/default/y
|
||||
2
|
||||
|
||||
$ stop_dune
|
||||
Success, waiting for filesystem changes...
|
||||
Success, waiting for filesystem changes...
|
||||
|
||||
Same but in a sub-directory (the exclude regexp used to be sensitive to that):
|
||||
|
||||
$ mkdir test
|
||||
$ mv dune test/dune
|
||||
|
||||
$ start_dune
|
||||
|
||||
$ echo 1 > test/.x
|
||||
$ build test/y
|
||||
Success
|
||||
$ cat _build/default/test/y
|
||||
1
|
||||
|
||||
$ echo 2 > test/.x
|
||||
$ build test/y
|
||||
Success
|
||||
$ cat _build/default/test/y
|
||||
2
|
||||
|
||||
$ stop_dune
|
||||
Success, waiting for filesystem changes...
|
||||
Success, waiting for filesystem changes...
|
||||
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
Demonstrate running "dune build" concurrently with an eager rpc server.
|
||||
|
||||
$ echo '(lang dune 3.18)' > dune-project
|
||||
$ echo '(executable (name foo))' > dune
|
||||
$ echo 'let () = print_endline "Hello, World!"' > foo.ml
|
||||
|
||||
Build the project once before starting the watch server so the watch server starts immediately.
|
||||
$ dune build
|
||||
$ dune build --watch &
|
||||
Success, waiting for filesystem changes...
|
||||
Success, waiting for filesystem changes...
|
||||
Success, waiting for filesystem changes...
|
||||
File "foo.ml", line 1, characters 9-21:
|
||||
1 | let () = print_endlin "Hello, World!"
|
||||
^^^^^^^^^^^^
|
||||
Error: Unbound value print_endlin
|
||||
Hint: Did you mean print_endline?
|
||||
Had 1 error, waiting for filesystem changes...
|
||||
File "foo.ml", line 1, characters 9-21:
|
||||
1 | let () = print_endlin "Hello, World!"
|
||||
^^^^^^^^^^^^
|
||||
Error: Unbound value print_endlin
|
||||
Hint: Did you mean print_endline?
|
||||
Had 1 error, waiting for filesystem changes...
|
||||
|
||||
Demonstrate that we can run "dune build" while the watch server is running.
|
||||
$ dune build
|
||||
Success
|
||||
|
||||
Demonstrate that a warning is displayed when extra arguments are passed to
|
||||
"dune build", since those arguments will be ignored.
|
||||
$ dune build --auto-promote 2>&1 | sed 's/pid: [0-9]*/pid: PID/g'
|
||||
Warning: Your build request is being forwarded to a running Dune instance
|
||||
(pid: PID) so most command-line arguments will be ignored.
|
||||
Success
|
||||
|
||||
Demonstrate that error messages are still printed by "dune build" when it's
|
||||
acting as an RPC client while running concurrently with an RPC server.
|
||||
$ echo 'let () = print_endlin "Hello, World!"' > foo.ml
|
||||
$ dune build
|
||||
File "$TESTCASE_ROOT/foo.ml", line 1, characters 9-21:
|
||||
1 | let () = print_endlin "Hello, World!"
|
||||
^^^^^^^^^^^^
|
||||
Unbound value print_endlin
|
||||
Hint: Did you mean print_endline?
|
||||
Error: Build failed with 1 error.
|
||||
[1]
|
||||
|
||||
$ dune shutdown
|
||||
$ wait
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
Demonstrate running "dune exec" concurrently with an eager rpc server.
|
||||
|
||||
$ echo '(lang dune 3.18)' > dune-project
|
||||
$ echo '(executable (name foo))' > dune
|
||||
$ echo 'let () = print_endline "foo"' > foo.ml
|
||||
$ touch README.md
|
||||
|
||||
Just watch the readme file so we don't accidentally build foo.exe before
|
||||
testing the --no-build option:
|
||||
$ dune build README.md --watch &
|
||||
Success, waiting for filesystem changes...
|
||||
Success, waiting for filesystem changes...
|
||||
Success, waiting for filesystem changes...
|
||||
|
||||
Demonstrate handling the --no-build option:
|
||||
$ dune exec --no-build ./foo.exe
|
||||
Error: Program './foo.exe' isn't built yet. You need to build it first or
|
||||
remove the '--no-build' option.
|
||||
[1]
|
||||
|
||||
Demonstrate running an executable from the current project:
|
||||
$ dune exec ./foo.exe
|
||||
foo
|
||||
|
||||
Demonstrate running an executable from PATH:
|
||||
$ dune exec echo "bar"
|
||||
Warning: As this is not the main instance of Dune it is unable to locate the
|
||||
executable "echo" within this project. Dune will attempt to resolve the
|
||||
executable's name within your PATH only.
|
||||
bar
|
||||
|
||||
Demonstrate printing a warning if arguments are passed that would be ignored
|
||||
due to how Dune builds via RPC:
|
||||
$ dune exec --force ./foo.exe 2>&1 | sed 's/pid: [0-9]*/pid: PID/g'
|
||||
Warning: Your build request is being forwarded to a running Dune instance
|
||||
(pid: PID). Note that certain command line arguments may be ignored.
|
||||
foo
|
||||
|
||||
Demonstrate trying to run exec in watch mode while another watch server is running:
|
||||
$ dune exec ./foo.exe --watch 2>&1 | sed 's/pid: [0-9]*/pid: PID/g'
|
||||
Error: Another instance of dune (pid: PID) has locked the _build
|
||||
directory. Refusing to start a new watch server until no other instances of
|
||||
dune are running.
|
||||
|
||||
Demonstrate running an executable via an absolute path:
|
||||
$ dune exec $(which echo) "baz"
|
||||
baz
|
||||
|
||||
$ dune shutdown
|
||||
$ wait
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
Demonstrate building through rpc when server is running in eager watch
|
||||
|
||||
$ echo '(lang dune 3.8)' > dune-project
|
||||
$ mkdir src
|
||||
$ echo '(library (name foo))' > src/dune
|
||||
$ touch src/a.ml
|
||||
$ touch src/b.ml
|
||||
|
||||
$ dune build @all
|
||||
$ dune build --watch &
|
||||
Success, waiting for filesystem changes...
|
||||
Success, waiting for filesystem changes...
|
||||
|
||||
$ dune rpc build --wait .
|
||||
Success
|
||||
|
||||
$ dune shutdown
|
||||
$ wait
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
Show what Dune watches via inotify
|
||||
|
||||
$ mkdir test
|
||||
$ cd test
|
||||
|
||||
$ echo '(lang dune 3.0)' > dune-project
|
||||
$ mkdir src
|
||||
$ echo '(library (name foo))' > src/dune
|
||||
$ touch src/a.ml
|
||||
$ touch src/b.ml
|
||||
|
||||
$ strace -o ../log -e inotify_add_watch dune build --passive-watch-mode &
|
||||
Success, waiting for filesystem changes...
|
||||
|
||||
$ dune rpc build --wait .
|
||||
Success
|
||||
$ dune shutdown
|
||||
$ wait
|
||||
|
||||
The pattern below excludes absolute files as Dune currently watches
|
||||
everything in the PATH, which is not very reproducible.
|
||||
|
||||
$ sed -nE 's/inotify_add_watch\([0-9]*, "([^/].*)", .*\) (=.*)/watch \1 \2/p' ../log | sort -u
|
||||
watch . = 2
|
||||
watch _build/.sync = 1
|
||||
watch src = 3
|
||||
|
||||
Since the pattern above is not reproducible, uncomment the next lines
|
||||
to see what it is really doing
|
||||
# $ sed -nE 's/inotify_add_watch\([0-9]*, "(.*)", .*\) (=.*)/watch \1 \2/p' ../log | sort -u -k4n -k2 | sed "s,$OPAM_SWITCH_PREFIX,OPAM_SWITCH_PREFIX," | sed "s,$DUNE_SOURCEROOT,DUNE_SOURCEROOT,"
|
||||
# watch _build/.sync = 1
|
||||
# watch . = 2
|
||||
# watch src = 3
|
||||
# watch DUNE_SOURCEROOT/_build/default/test/blackbox-tests/test-cases/.bin = 4
|
||||
# watch DUNE_SOURCEROOT/_build/install/default/bin = 5
|
||||
# watch OPAM_SWITCH_PREFIX/bin = 6
|
||||
# watch OPAM_SWITCH_PREFIX/lib/ocaml = 7
|
||||
Loading…
Add table
Add a link
Reference in a new issue