From 4d887c25c8b66b3ffc9abea89bacab079e53e902 Mon Sep 17 00:00:00 2001 From: Etienne Millon Date: Fri, 12 Jul 2024 14:32:53 +0200 Subject: [PATCH] doc: rework usage and CLI --- doc/reference/cli/build-dir.rst | 16 ++ doc/reference/{cli.rst => cli/index.rst} | 61 ++--- doc/reference/cli/init.rst | 98 ++++++++ doc/reference/cli/install.rst | 54 ++++ doc/reference/cli/only-packages.rst | 13 + doc/reference/cli/runtest.rst | 16 ++ doc/reference/cli/subst.rst | 54 ++++ doc/reference/cli/utop.rst | 34 +++ doc/reference/cli/watch.rst | 7 + doc/reference/index.rst | 2 +- doc/usage.rst | 301 ----------------------- 11 files changed, 314 insertions(+), 342 deletions(-) create mode 100644 doc/reference/cli/build-dir.rst rename doc/reference/{cli.rst => cli/index.rst} (86%) create mode 100644 doc/reference/cli/init.rst create mode 100644 doc/reference/cli/install.rst create mode 100644 doc/reference/cli/only-packages.rst create mode 100644 doc/reference/cli/runtest.rst create mode 100644 doc/reference/cli/subst.rst create mode 100644 doc/reference/cli/utop.rst create mode 100644 doc/reference/cli/watch.rst diff --git a/doc/reference/cli/build-dir.rst b/doc/reference/cli/build-dir.rst new file mode 100644 index 00000000000..01d75882622 --- /dev/null +++ b/doc/reference/cli/build-dir.rst @@ -0,0 +1,16 @@ +``--build-dir`` - Custom Build Directory +======================================== + +By default Dune places all build artifacts in the ``_build`` directory relative +to the user's workspace. However, one can customize this directory by using the +``--build-dir`` flag or the ``DUNE_BUILD_DIR`` environment variable. + +.. code:: console + + $ dune build --build-dir _build-foo + + # this is equivalent to: + $ DUNE_BUILD_DIR=_build-foo dune build + + # Absolute paths are also allowed + $ dune build --build-dir /tmp/build foo.exe diff --git a/doc/reference/cli.rst b/doc/reference/cli/index.rst similarity index 86% rename from doc/reference/cli.rst rename to doc/reference/cli/index.rst index 4831085e528..6af4a5eee3a 100644 --- a/doc/reference/cli.rst +++ b/doc/reference/cli/index.rst @@ -4,6 +4,27 @@ Command Line Interface This is a short overview of the commands available in Dune. Reference documentation for each command is available through ``dune COMMAND --help``. +.. toctree:: + :caption: Commands + :maxdepth: 1 + + runtest + utop + subst + init + install + +.. toctree:: + :caption: Common Options + :maxdepth: 1 + + only-packages + watch + build-dir + +Other Commands +-------------- + .. describe:: dune build Build the given targets, or the default ones. @@ -99,30 +120,6 @@ documentation for each command is available through ``dune COMMAND --help``. Additional Dune help. -.. describe:: dune init - - Command group for initializing Dune components. - - .. describe:: dune init executable - - Initialize a binary executable. - - .. describe:: dune init library - - Initialize an OCaml library. - - .. describe:: dune init project - - Initialize a whole OCaml project. - - .. describe:: dune init test - - Initialize a test harness. - -.. describe:: dune install - - Install packages defined in workspace. - .. describe:: dune installed-libraries Print out libraries installed on the system. @@ -197,22 +194,10 @@ documentation for each command is available through ``dune COMMAND --help``. Dump rules. -.. describe:: dune runtest - - Run tests. - -.. describe:: dune test - - A command alias for ``dune runtest``. - .. describe:: dune shutdown Cancel and shutdown any builds in the current workspace. -.. describe:: dune subst - - Substitute watermarks in source files. - .. describe:: dune top Print a list of toplevel directives for including directories and loading @@ -225,7 +210,3 @@ documentation for each command is available through ``dune COMMAND --help``. .. describe:: dune upgrade Upgrade projects across major Dune versions. - -.. describe:: dune utop - - Load library in UTop. diff --git a/doc/reference/cli/init.rst b/doc/reference/cli/init.rst new file mode 100644 index 00000000000..e0326a1f604 --- /dev/null +++ b/doc/reference/cli/init.rst @@ -0,0 +1,98 @@ +.. _initializing_components: + +init - Initializing Components +============================== + +NOTE: The ``dune init`` command is still under development and subject to +change. + +Dune's ``init`` subcommand provides limited support for generating Dune file +stanzas and folder structures to define components. The ``dune init`` command can be used to +quickly add new projects, libraries, tests, and executables without having to +manually create Dune files in a text editor, or it can be composed to programmatically generate +parts of a multi-component project. + +Initializing a Project +---------------------- + +You can run the following command to initialize a new Dune project that uses the ``base`` and ``cmdliner`` +libraries and supports inline tests: + +.. code:: console + + $ dune init proj myproj --libs base,cmdliner --inline-tests --ppx ppx_inline_test + +This creates a new directory called ``myproj``, including subdirectories and +``dune`` files for library, executable, and test components. Each component's +``dune`` file will also include the declarations required for the given +dependencies. + +This is the quickest way to get a basic ``dune`` project up and building. + +Initializing an Executable +-------------------------- + +To add a new executable to a ``dune`` file in the current directory +(creating the file if necessary), run + +.. code:: console + + $ dune init exe myexe --libs base,containers,notty --ppx ppx_deriving + +This will add the following stanza to the ``dune`` file: + +.. code:: dune + + (executable + (name main) + (libraries base containers notty) + (preprocess + (pps ppx_deriving))) + +Initializing a Library +---------------------- + +Run the following command to create a new directory ``src``, initialized as a library: + +.. code:: console + + $ dune init lib mylib src --libs core --inline-tests --public + +This will ensure the file ``./src/dune`` contains the below stanza (creating +the file and directory, if necessary): + +.. code:: dune + + (library + (public_name mylib) + (inline_tests) + (name mylib) + (libraries core) + (preprocess + (pps ppx_inline_tests))) + +Initializing Components in a Specified Directory +------------------------------------------------ + +All ``init`` subcommands take an optional ``PATH`` argument, which should be a +path to a directory. When supplied, the component will be created in the +specified directory. E.g., to initialize a project in the current working +directory, run + +.. code:: console + + $ dune init proj my_proj . + +To initialize a project in a directory in some nested path, run + +.. code:: console + + $ dune init proj my_proj path/to/my/project + +If the specified directory does not already exist, it will be created. + +Learning More About the ``init`` Commands +----------------------------------------- + +Consult the manual page using the ```dune init --help`` command for more +details. diff --git a/doc/reference/cli/install.rst b/doc/reference/cli/install.rst new file mode 100644 index 00000000000..8cc333eaec0 --- /dev/null +++ b/doc/reference/cli/install.rst @@ -0,0 +1,54 @@ +install - Manually Installing a Package +======================================= + +Via opam +-------- + +When releasing a package using Dune in opam, there's nothing special +to do. Dune generates a file called ``.install`` at the +root of the project. This contains a list of files to install, and +opam reads it in order to perform the installation. + +Manually +-------- + +When not using opam, or when you want to manually install a package, +you can ask Dune to perform the installation via the ``install`` +command: + +.. code:: console + + $ dune install [PACKAGE]... + +This command takes a list of package names to install. If no packages +are specified, Dune will install all available packages in the +workspace. When several build contexts are specified via a +:doc:`/reference/dune-workspace/index` file, Dune performs the +installation in all the build contexts. + +Destination Directory +--------------------- + +For a given build context, the installation directories are determined with a +single scheme for all installation sections. Taking the ``lib`` installation +section as an example, the priorities of this scheme are as follows: + +#. if an explicit ``--lib `` argument is passed, use this path +#. if an explicit ``--prefix `` argument is passed, use ``/lib`` +#. if ``--lib `` argument is passed before during dune compilation to + ``./configure``, use this paths +#. if ``OPAM_SWITCH_PREFIX`` is present in the environment use ``$OPAM_SWITCH_PREFIX/lib`` +#. otherwise, fail + +Relocation Mode +--------------- + +The installation can be done in specific mode (``--relocation``) for creating a +directory that can be moved. In that case, the installed executables will +look up the package sites (cf :ref:`sites`) relative to its location. +The `--prefix` directory should be used to specify the destination. + + +If you're using plugins that depend on installed libraries and aren't +executable dependencies, like libraries that need to be loaded at +runtime, you must copy the libraries manually to the destination directory. diff --git a/doc/reference/cli/only-packages.rst b/doc/reference/cli/only-packages.rst new file mode 100644 index 00000000000..48856f8b0af --- /dev/null +++ b/doc/reference/cli/only-packages.rst @@ -0,0 +1,13 @@ +``--only-packages`` - Restricting the Set of Packages +===================================================== + +Restrict the set of packages from your workspace that Dune can see with +the ``--only-packages`` option: + +.. code:: console + + $ dune build --only-packages pkg1,pkg2,... @install + +This option acts as if you went through all the Dune files and +commented out the stanzas referring to a package that isn't in the list +given to ``dune``. diff --git a/doc/reference/cli/runtest.rst b/doc/reference/cli/runtest.rst new file mode 100644 index 00000000000..aae4982056c --- /dev/null +++ b/doc/reference/cli/runtest.rst @@ -0,0 +1,16 @@ +.. _running-tests: + +runtest - Running Tests +======================= + +There are two ways to run tests: + +- ``dune build @runtest`` +- ``dune test`` (or the more explicit ``dune runtest``) + +The two commands are equivalent, and they will run all the tests defined in the +current directory and its children directories recursively. You can also run the tests in a +specific sub-directory and its children by using: + +- ``dune build @foo/bar/runtest`` +- ``dune test foo/bar`` (or ``dune runtest foo/bar``) diff --git a/doc/reference/cli/subst.rst b/doc/reference/cli/subst.rst new file mode 100644 index 00000000000..c6cffb5ffef --- /dev/null +++ b/doc/reference/cli/subst.rst @@ -0,0 +1,54 @@ +.. _dune-subst: + +subst - Substitute Watermarks in Source Files +============================================= + +One of the features ``dune-release`` provides is watermarking; it replaces +various strings of the form ``%%ID%%`` in all your project files +before creating a release tarball or when the opam user pins the package. + +This is especially interesting for the ``VERSION`` watermark, which gets +replaced by the version obtained from the Version-Control System (VCS). For instance, if you're using +Git, ``dune-release`` invokes this command to find out the version: + +.. code:: console + + $ git describe --always --dirty --abbrev=7 + 1.0+beta9-79-g29e9b37 + +If no VCS is detected, ``dune subst`` will do nothing. + +Projects using Dune usually only need ``dune-release`` for creating and +publishing releases. However, they may still substitute the +watermarks when the user pins the package. To help with this, +Dune provides the ``subst`` sub-command. + +``dune subst`` performs the same substitution that ``dune-release`` does +with the default configuration, i.e., calling ``dune subst`` at the +root of your project will rewrite all your project files. + +More precisely, it replaces the following watermarks in the source files: + +- ``NAME``, the name of the project +- ``VERSION``, output of ``git describe --always --dirty --abbrev=7`` +- ``VERSION_NUM``, same as ``VERSION`` but with a potential leading + ``v`` or ``V`` dropped +- ``VCS_COMMIT_ID``, commit hash from the vcs +- ``PKG_MAINTAINER``, contents of the ``maintainer`` field from the + opam file +- ``PKG_AUTHORS``, contents of the ``authors`` field from the opam file +- ``PKG_HOMEPAGE``, contents of the ``homepage`` field from the opam file +- ``PKG_ISSUES``, contents of the ``issues`` field from the opam file +- ``PKG_DOC``, contents of the ``doc`` field from the opam file +- ``PKG_LICENSE``, contents of the ``license`` field from the opam file +- ``PKG_REPO``, contents of the ``repo`` field from the opam file + +The project name is obtained by reading the ``dune-project`` +file in the directory where ``dune subst`` is called. The +``dune-project`` file must exist and contain a valid ``(name ...)`` +field. + +Note that ``dune subst`` is meant to be called from the opam file and +behaves a bit different to other Dune commands. In +particular it doesn't try to detect the root of the workspace and must +be called from the root of the project. diff --git a/doc/reference/cli/utop.rst b/doc/reference/cli/utop.rst new file mode 100644 index 00000000000..0b1e8cb9bdb --- /dev/null +++ b/doc/reference/cli/utop.rst @@ -0,0 +1,34 @@ +utop - Load library in UTop +=========================== + +Dune supports launching a `utop `__ instance +with locally defined libraries loaded. + +.. code:: console + + $ dune utop -- + +Where ```` is a directory under which Dune searches (recursively) for +all libraries that will be loaded. ```` will be passed as arguments to the +``utop`` command itself. For example, ``dune utop lib -- -implicit-bindings`` will +start ``utop``, with the libraries defined in ``lib`` and implicit bindings for +toplevel expressions. + +Dune also supports loading individual modules unsealed by their signatures into +the toplevel. This is accomplished by launching a toplevel and then asking dune +to return the toplevel directives needed to evaluate the module: + +.. code:: console + + $ utop + # use_output "dune ocaml top-module path/to/module.ml";; + +Requirements & Limitations +-------------------------- + +* Utop version >= 2.0 is required for this to work. +* This subcommand only supports loading libraries. Executables aren't supported. +* Libraries that are dependencies of utop itself cannot be loaded. For example + `Camomile `__. +* Loading libraries that are defined in different directories into one ``utop`` + instance isn't possible. diff --git a/doc/reference/cli/watch.rst b/doc/reference/cli/watch.rst new file mode 100644 index 00000000000..d6b91a46cf0 --- /dev/null +++ b/doc/reference/cli/watch.rst @@ -0,0 +1,7 @@ +``--watch`` - Watch Mode +======================== + +The ``dune build`` and ``dune runtest`` commands support a ``-w`` (or +``--watch``) flag. When it's passed, Dune will perform the action as usual and +then wait for file changes and rebuild (or rerun the tests). This feature +requires ``inotifywait`` or ``fswatch`` to be installed. diff --git a/doc/reference/index.rst b/doc/reference/index.rst index abd7feb59bc..b3acca2f9b3 100644 --- a/doc/reference/index.rst +++ b/doc/reference/index.rst @@ -65,7 +65,7 @@ These documents specify the various features and languages present in Dune. :maxdepth: 1 :caption: Dune Components - cli + cli/index ../dune-libs ../caching diff --git a/doc/usage.rst b/doc/usage.rst index a999c9bc96e..6445b68ff81 100644 --- a/doc/usage.rst +++ b/doc/usage.rst @@ -6,112 +6,12 @@ Command-Line Interface There are mixed types of contents in this document, including: - - an how-to about ``dune init`` - reference info about finding the root and libraries - reference info about the CLI - how-to info about overriding what ``dune build`` does This section describes using ``dune`` from the shell. -.. _initializing_components: - -Initializing Components -======================= - -NOTE: The ``dune init`` command is still under development and subject to -change. - -Dune's ``init`` subcommand provides limited support for generating Dune file -stanzas and folder structures to define components. The ``dune init`` command can be used to -quickly add new projects, libraries, tests, and executables without having to -manually create Dune files in a text editor, or it can be composed to programmatically generate -parts of a multi-component project. - -Initializing a Project ----------------------- - -You can run the following command to initialize a new Dune project that uses the ``base`` and ``cmdliner`` -libraries and supports inline tests: - -.. code:: console - - $ dune init proj myproj --libs base,cmdliner --inline-tests --ppx ppx_inline_test - -This creates a new directory called ``myproj``, including subdirectories and -``dune`` files for library, executable, and test components. Each component's -``dune`` file will also include the declarations required for the given -dependencies. - -This is the quickest way to get a basic ``dune`` project up and building. - -Initializing an Executable ------------------------------ - -To add a new executable to a ``dune`` file in the current directory -(creating the file if necessary), run - -.. code:: console - - $ dune init exe myexe --libs base,containers,notty --ppx ppx_deriving - -This will add the following stanza to the ``dune`` file: - -.. code:: dune - - (executable - (name main) - (libraries base containers notty) - (preprocess - (pps ppx_deriving))) - -Initializing a Library ----------------------- - -Run the following command to create a new directory ``src``, initialized as a library: - -.. code:: console - - $ dune init lib mylib src --libs core --inline-tests --public - -This will ensure the file ``./src/dune`` contains the below stanza (creating -the file and directory, if necessary): - -.. code:: dune - - (library - (public_name mylib) - (inline_tests) - (name mylib) - (libraries core) - (preprocess - (pps ppx_inline_tests))) - -Initializing Components in a Specified Directory ------------------------------------------------- - -All ``init`` subcommands take an optional ``PATH`` argument, which should be a -path to a directory. When supplied, the component will be created in the -specified directory. E.g., to initialize a project in the current working -directory, run - -.. code:: console - - $ dune init proj my_proj . - -To initialize a project in a directory in some nested path, run - -.. code:: console - - $ dune init proj my_proj path/to/my/project - -If the specified directory does not already exist, it will be created. - -Learning More About the ``init`` Commands ------------------------------------------ - -Consult the manual page using the ```dune init --help`` command for more -details. - .. _finding-root: Finding the Root @@ -250,80 +150,6 @@ variable. ``OCAMLPATH`` always has precedence and can have different values in different build contexts. For instance, you can set it manually in a specific build context via the ``dune-workspace`` file. -.. _running-tests: - -Running Tests -============= - -There are two ways to run tests: - -- ``dune build @runtest`` -- ``dune test`` (or the more explicit ``dune runtest``) - -The two commands are equivalent, and they will run all the tests defined in the -current directory and its children directories recursively. You can also run the tests in a -specific sub-directory and its children by using: - -- ``dune build @foo/bar/runtest`` -- ``dune test foo/bar`` (or ``dune runtest foo/bar``) - -Watch Mode -========== - -The ``dune build`` and ``dune runtest`` commands support a ``-w`` (or -``--watch``) flag. When it's passed, Dune will perform the action as usual and -then wait for file changes and rebuild (or rerun the tests). This feature -requires ``inotifywait`` or ``fswatch`` to be installed. - -Launching the Toplevel (REPL) -============================= - -Dune supports launching a `utop `__ instance -with locally defined libraries loaded. - -.. code:: console - - $ dune utop -- - -Where ```` is a directory under which Dune searches (recursively) for -all libraries that will be loaded. ```` will be passed as arguments to the -``utop`` command itself. For example, ``dune utop lib -- -implicit-bindings`` will -start ``utop``, with the libraries defined in ``lib`` and implicit bindings for -toplevel expressions. - -Dune also supports loading individual modules unsealed by their signatures into -the toplevel. This is accomplished by launching a toplevel and then asking dune -to return the toplevel directives needed to evaluate the module: - -.. code:: console - - $ utop - # use_output "dune ocaml top-module path/to/module.ml";; - -Requirements & Limitations --------------------------- - -* Utop version >= 2.0 is required for this to work. -* This subcommand only supports loading libraries. Executables aren't supported. -* Libraries that are dependencies of utop itself cannot be loaded. For example - `Camomile `__. -* Loading libraries that are defined in different directories into one ``utop`` - instance isn't possible. - -Restricting the Set of Packages -=============================== - -Restrict the set of packages from your workspace that Dune can see with -the ``--only-packages`` option: - -.. code:: console - - $ dune build --only-packages pkg1,pkg2,... @install - -This option acts as if you went through all the Dune files and -commented out the stanzas referring to a package that isn't in the list -given to ``dune``. - Distributing Projects ===================== @@ -340,133 +166,6 @@ The common defaults are that your projects include the following files: If your project contains several packages, all the package names must be prefixed by the shortest one. -.. _dune-subst: - -``dune subst`` -============== - -One of the features ``dune-release`` provides is watermarking; it replaces -various strings of the form ``%%ID%%`` in all your project files -before creating a release tarball or when the opam user pins the package. - -This is especially interesting for the ``VERSION`` watermark, which gets -replaced by the version obtained from the Version-Control System (VCS). For instance, if you're using -Git, ``dune-release`` invokes this command to find out the version: - -.. code:: console - - $ git describe --always --dirty --abbrev=7 - 1.0+beta9-79-g29e9b37 - -If no VCS is detected, ``dune subst`` will do nothing. - -Projects using Dune usually only need ``dune-release`` for creating and -publishing releases. However, they may still substitute the -watermarks when the user pins the package. To help with this, -Dune provides the ``subst`` sub-command. - -``dune subst`` performs the same substitution that ``dune-release`` does -with the default configuration, i.e., calling ``dune subst`` at the -root of your project will rewrite all your project files. - -More precisely, it replaces the following watermarks in the source files: - -- ``NAME``, the name of the project -- ``VERSION``, output of ``git describe --always --dirty --abbrev=7`` -- ``VERSION_NUM``, same as ``VERSION`` but with a potential leading - ``v`` or ``V`` dropped -- ``VCS_COMMIT_ID``, commit hash from the vcs -- ``PKG_MAINTAINER``, contents of the ``maintainer`` field from the - opam file -- ``PKG_AUTHORS``, contents of the ``authors`` field from the opam file -- ``PKG_HOMEPAGE``, contents of the ``homepage`` field from the opam file -- ``PKG_ISSUES``, contents of the ``issues`` field from the opam file -- ``PKG_DOC``, contents of the ``doc`` field from the opam file -- ``PKG_LICENSE``, contents of the ``license`` field from the opam file -- ``PKG_REPO``, contents of the ``repo`` field from the opam file - -The project name is obtained by reading the ``dune-project`` -file in the directory where ``dune subst`` is called. The -``dune-project`` file must exist and contain a valid ``(name ...)`` -field. - -Note that ``dune subst`` is meant to be called from the opam file and -behaves a bit different to other Dune commands. In -particular it doesn't try to detect the root of the workspace and must -be called from the root of the project. - -Custom Build Directory -====================== - -By default Dune places all build artifacts in the ``_build`` directory relative -to the user's workspace. However, one can customize this directory by using the -``--build-dir`` flag or the ``DUNE_BUILD_DIR`` environment variable. - -.. code:: console - - $ dune build --build-dir _build-foo - - # this is equivalent to: - $ DUNE_BUILD_DIR=_build-foo dune build - - # Absolute paths are also allowed - $ dune build --build-dir /tmp/build foo.exe - -Installing a Package -==================== - -Via opam --------- - -When releasing a package using Dune in opam, there's nothing special -to do. Dune generates a file called ``.install`` at the -root of the project. This contains a list of files to install, and -opam reads it in order to perform the installation. - -Manually --------- - -When not using opam, or when you want to manually install a package, -you can ask Dune to perform the installation via the ``install`` -command: - -.. code:: console - - $ dune install [PACKAGE]... - -This command takes a list of package names to install. If no packages -are specified, Dune will install all available packages in the -workspace. When several build contexts are specified via a -:doc:`/reference/dune-workspace/index` file, Dune performs the -installation in all the build contexts. - -Destination Directory ---------------------- - -For a given build context, the installation directories are determined with a -single scheme for all installation sections. Taking the ``lib`` installation -section as an example, the priorities of this scheme are as follows: - -#. if an explicit ``--lib `` argument is passed, use this path -#. if an explicit ``--prefix `` argument is passed, use ``/lib`` -#. if ``--lib `` argument is passed before during dune compilation to - ``./configure``, use this paths -#. if ``OPAM_SWITCH_PREFIX`` is present in the environment use ``$OPAM_SWITCH_PREFIX/lib`` -#. otherwise, fail - -Relocation Mode ---------------- - -The installation can be done in specific mode (``--relocation``) for creating a -directory that can be moved. In that case, the installed executables will -look up the package sites (cf :ref:`sites`) relative to its location. -The `--prefix` directory should be used to specify the destination. - - -If you're using plugins that depend on installed libraries and aren't -executable dependencies, like libraries that need to be loaded at -runtime, you must copy the libraries manually to the destination directory. - Querying Merlin Configuration =============================