120 lines
3 KiB
ReStructuredText
120 lines
3 KiB
ReStructuredText
Actions
|
|
=======
|
|
|
|
.. highlight:: dune
|
|
|
|
``(action ...)`` fields describe user actions.
|
|
|
|
User actions are always run from the same subdirectory of the current build
|
|
context as the ``dune`` file they are defined in, so for instance, an action defined
|
|
in ``src/foo/dune`` will be run from ``$build/<context>/src/foo``.
|
|
|
|
The argument of ``(action ...)`` fields is a small DSL that's interpreted by
|
|
Dune directly and doesn't require an external shell. All atoms in the DSL
|
|
support :doc:`/concepts/variables`. Moreover, you don't need to specify
|
|
dependencies explicitly for the special ``%{<kind>:...}`` forms; these are
|
|
recognized and automatically handled by Dune.
|
|
|
|
The DSL is currently quite limited, so if you want to do something complicated,
|
|
it's recommended to write a small OCaml program and use the DSL to invoke it.
|
|
You can use `shexp <https://github.com/janestreet/shexp>`__ to write portable
|
|
scripts or :ref:`configurator` for configuration related tasks. You can also
|
|
use :ref:`dune-action-plugin` to express program dependencies directly in the
|
|
source code.
|
|
|
|
The following constructions are available:
|
|
|
|
.. grid:: 1 1 2 2
|
|
|
|
.. grid-item::
|
|
|
|
.. toctree::
|
|
:caption: Running commands
|
|
|
|
run
|
|
system
|
|
bash
|
|
dynamic-run
|
|
chdir
|
|
setenv
|
|
with-accepted-exit-codes
|
|
|
|
.. grid-item::
|
|
|
|
.. toctree::
|
|
:caption: Input and output
|
|
|
|
echo
|
|
with-outputs-to
|
|
with-stdin-from
|
|
ignore-outputs
|
|
cat
|
|
copy
|
|
copy#
|
|
write-file
|
|
pipe-outputs
|
|
format-dune-file
|
|
|
|
.. grid-item::
|
|
|
|
.. toctree::
|
|
:caption: Comparing files
|
|
|
|
diff
|
|
diffq
|
|
cmp
|
|
|
|
.. grid-item::
|
|
|
|
.. toctree::
|
|
:caption: Control structures
|
|
|
|
progn
|
|
concurrent
|
|
no-infer
|
|
|
|
Note: expansion of the special ``%{<kind>:...}`` is done relative to the current
|
|
working directory of the DSL being executed. So for instance, if you
|
|
have this action in a ``src/foo/dune``:
|
|
|
|
.. code:: dune
|
|
|
|
(action (chdir ../../.. (echo %{dep:dune})))
|
|
|
|
Then ``%{dep:dune}`` will expand to ``src/foo/dune``. When you run various
|
|
tools, they often use the filename given on the command line in error messages.
|
|
As a result, if you execute the command from the original directory, it will
|
|
only see the basename.
|
|
|
|
To understand why this is important, let's consider this ``dune`` file living in
|
|
``src/foo``::
|
|
|
|
(rule
|
|
(target blah.ml)
|
|
(deps blah.mll)
|
|
(action
|
|
(run ocamllex -o %{target} %{deps})))
|
|
|
|
Here the command that will be executed is:
|
|
|
|
.. code:: console
|
|
|
|
$ ocamllex -o blah.ml blah.mll
|
|
|
|
And it will be executed in ``_build/<context>/src/foo``. As a result, if there
|
|
is an error in the generated ``blah.ml`` file, it will be reported as:
|
|
|
|
::
|
|
|
|
File "blah.ml", line 42, characters 5-10:
|
|
Error: ...
|
|
|
|
Which can be a problem, as your editor might think that ``blah.ml`` is at the root
|
|
of your project. Instead, this is a better way to write it::
|
|
|
|
(rule
|
|
(target blah.ml)
|
|
(deps blah.mll)
|
|
(action
|
|
(chdir %{workspace_root}
|
|
(run ocamllex -o %{target} %{deps}))))
|