ocaml / ocaml/dune

[RFC] dune fetch

Open
#4,826 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

proposal
Dominant language
OCaml
Stars
1.9k
Forks
500
Avg merge
15h 21m
Merged PRs (30d)
277

Description

This RFC proposes the addition of dune fetch, a command to locate
and promote files from the build directory into the working tree.

Background

The story for interacting with build artifacts is pretty bad. Aside
from manually searching _build, there are a few different
mechanisms for this:

  • dune promote is great, but is limited to things declared via the
    diff action
  • dune install "installs packages" according to the documentation,
    but it's not immediately obvious what this means. ReadTheDocs
    suggests that this installs things to the system; this can be
    used as a general mechanism if you install to the misc section,
    but it requires you to know in advance what you might want to
    retrieve.
  • ReadTheDocs claims that "some [targets] are sometimes copied to the
    source tree for the need of external tools".

None of these work particularly well if you'd like to examine a build
artifact after the fact in an ad-hoc way. An example use case might be
to do some post-hoc performance profiling of a benchmark.

Goals

  • Convenience: Artifacts should be produced in an obvious place in
    the source tree on user request.
  • Opacity: Users and external tools should never need to
    understand the layout of _build; it is an internal
    implementation detail of Dune and should be treated as such.

Proposed solution

Introduce a new command dune fetch [targets], which will bring the
listed targets up to date, then copy them from _build into the
source tree, e.g. dune fetch bin/main.exe will cause an up-to-date
version of bin/main.exe to be produced.

Semantics
  • dune fetch should not try to be clever, beyond potentially
    (re)building its arguments and copying them to the source tree. If the
    user requests to fetch a file a, the only file produced should be
    named a. This means that implicit renames, such as those declared in
    install or the copy action should not be followed unless the user
    explicitly requests them (e.g., fetching bin/main.exe should not
    produce a file named dune.exe).

  • Artifacts should be produced in the location matching the target --
    running dune fetch b/c from directory %{root}/a should cause
    %{root}/a/b/c to be created. This should not cause any issues
    with intermediate directories, as rules cannot declare targets outside
    of their own directories.

  • If the build fails for any reason, no artifacts are produced in the
    source tree, even if some artifacts were built successfully. i.e.,
    dune fetch a b will either produce both or neither of a and
    b.

  • Only the targets explicitly requested should be copied,
    even if the rules for doing so produce other artifacts. This will
    minimize clutter and reduce the chance that a user will mistake
    a stale artifact for up-to-date.

  • If no context is specified, targets are fetched from the default
    context. Otherwise, dune fetch bar --context foo will try to
    produce bar in the foo context.

The question of what to do about aliases is
currently still undecided (see Remaining
Questions).

Implementation

The obvious implementation would be to invoke dune build on the
specified targets, then to copy the files from _build.

The easiest implementation is to alias dune fetch to a subcommand of
build, say dune build --fetch. In this case, we are effectively
creating a new target that is located in the source tree whose rule is
a copy from the build directory, which should inform the interactions
with watching mode (etc).

Remaining Questions

  • What should we do if the users attempts to fetch an alias?
    • The easiest thing to do is to reject it and fail. This makes the
      most intuitive sense; dune fetch @runtest or dune fetch @default aren't obviously meaningful.
    • On the other hand, if we go with the dune build --fetch
      implementation, users may reasonably expect dune build --fetch @default to build and promote "everything". Alternatives
      include only promoting the direct file dependencies of the alias,
      or recursively following aliases until a rule with concrete file
      targets is encountered. These have the potential to produce
      a lot of unexpected output.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading the RFC, especially the proposed dune fetch semantics and the unresolved alias behavior. Inspect the existing dune build subcommand path mentioned as a possible implementation, then determine how the requested targets, contexts, copying, and all-or-nothing behavior should be handled. Done means an agreed design and implementation that satisfies the listed semantics, including a decision on aliases.

Written by the indexing model from the issue text.

Assessment

Tech stack
ocaml
Domain
build-system, cli
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.