dune
dune copied to clipboard
Usability/Documentation issues with copy_files/glob
Expected Behavior
-
copy_files
does not warn if the<glob>
expression matches a directory instead of a file. It would be very useful to report such errors, in the same way as the Cannot copy files onto themselves message already does for files in the local directory. Currently, if the user mistakenly uses a directory name (or even the name of a non-existing file), dune silently does nothing, without reporting any errors. -
It is unclear to me why
(copy_files (glob_files_rec <glob>))
does not work. Thecopy_files
documentation mentions:<glob>
represents the set of files to copy. See the glob for details.That page, in turn, mentions:
Dune supports globbing files in a single directory via
(glob_files ...)
and, starting with Dune 3.0, in all sub-directories recursively via(glob_files_rec ...)
.I then assumed that
<glob>
in thecopy_files
part could be replaced with(glob_files ...)
. So I tried using(copy_files (files (glob_files_rec ../dir/*)))
, but it complains withError: Unexpected list
. If I remove thefiles
part, since thecopy_files
doc mentions that The short form(copy_files <glob>)
is equivalent to(copy_files (files <glob>))
, it then complains withError: field files missing
. In both cases, I am unable to combinecopy_files
withglob_files
, which seems it should be possible from the documentation. The lack of usage examples for this option makes it harder to understand how it must be written.
Actual Behavior
- No errors reported in case of non-existing/directory name
- Error when trying to combine
copy_files
andglob_files
; lack of usage examples.
Reproduction
First issue:
-
cd /tmp && dune init project proj
-
cd proj
-
mkdir d; touch c
-
echo "(copy_files ../d)" >> bin/dune
# user meant "../c" instead of "../d" -
echo "(copy_files ../invalid)" >> bin/dune
# user entered a non-existing path -
dune build
No error/warning is emitted; no files are copied.
Second issue:
-
echo "(copy_files (glob_files_rec ../d/*))" >> bin/dune
# documentation suggests it might work -
dune build
# error - Erase erroneous line from
bin/dune
-
echo "(copy_files (files (glob_files_rec ../d/*)))" >> bin/dune
# documentation suggests it might work -
dune build
# another error
Also, there are no examples with glob_files_rec
.
Specifications
- Version of
dune
(output ofdune --version
): 3.3.1 - Version of
ocaml
(output ofocamlc --version
): 4.08.1 - Operating system (distribution and version): Linux Fedora 36
Another (minor) issue I just noticed: when a dirs
stanza is used, other directories are excluded when using copy_files
; however, the error message is Cannot find directory: <dir>
. It took me a while to realize it was the dirs
stanza from another dune file that was causing it. For instance, if my root dune
file contains (dirs bin lib test)
, but inside lib
I have a dune
file with copy_files ../share/*
, Dune's message Cannot find directory: share
will not be that helpful. Ideally, something like "path excluded from Dune's build" would be best. Otherwise, a simple addition to the existing message, such as "Check that the path exists and is not excluded by any dirs
stanza" might be enough. Then again, the wording of this message is very important: it should tell users that dirs
may exclude certain directories, but not that they should add a dirs
stanza; otherwise beginners might feel compelled to add such stanzas to their files...
Sorry for yet another related comment on this subject:
glob_files
/glob_files_rec
are useful in deps
, but I believe they are rarely (if ever) used to match possibly empty lists. For instance, if I mistakenly write (glob_files_rec ../node_moduless/*.js)
(with an extra 's'), the glob will match no files at all, but will silently continue.
There are probably cases where an empty match is desirable; but from my experience with Makefile and the wildcard
function (which also evaluates to the empty list without any warnings), I noticed that in most cases users want to be warned when their globs result in empty expansions. For instance, shells default to not-nullglob precisely to avoid issues with accidental empty globbing.
Ideally, two versions of glob_files
/glob_files_rec
should exist, one of them warning/erroring out if it expands to nothing (preferably the default one), and another with the current behavior. Adding a modifier such as nullglob
, e.g. glob_files (nullglob) <files>
could allow switching between them.