Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a (chdir ..) stanza #3268

Merged
merged 1 commit into from
Apr 8, 2020
Merged

Add a (chdir ..) stanza #3268

merged 1 commit into from
Apr 8, 2020

Conversation

rgrinberg
Copy link
Member

This stanza allows one to write rules for a sub directory with the following
form:

(subdir bar ;; bar is the subdir
  ;; arbtirary stanzas can go here
 )

This form is quite useful for code generation. That's because it's easier to
generate the dune file in one go for an entire build rather than setting up
multiple rules.

It also gives us the ability to override dune file in subdirs. For example:

$ cat dune
(data_only_dirs foo)
(subdirs foo ..) ;; (1)
$ cat foo/dune
 <contents>

The idea is that should be ignored and the dune file is specified
using (1). This is quite useful in some vendoring situations where you don't
want to be applying your own patches.

@rgrinberg rgrinberg requested review from a user and aalekseyev March 16, 2020 10:50
src/dune/file_tree.ml Outdated Show resolved Hide resolved
src/dune/file_tree.ml Outdated Show resolved Hide resolved
@nojb
Copy link
Collaborator

nojb commented Mar 16, 2020

What happens if there is already a dune file in the subdir which is not ignored ? Are the dune files merged ?

@rgrinberg
Copy link
Member Author

What happens if there is already a dune file in the subdir which is not ignored ? Are the dune files merged ?

The current implementations behaves as follows:

  • It concatenates all normal stanzas.
  • Directory visibility stanzas such as (data_only_dirs .) override each other.

I realize that this isn't consistent, but it gives us the ability to shadow dune files in sub directories without editing them. That seems like a useful thing to have. We can also disallow stanzas such as (data_only_dirs .) inside (subdir ..)

@ghost
Copy link

ghost commented Mar 16, 2020

The implicit shadowing behaviour makes me nervous. Are you thinking of shadowing dune files of vendored code? If shadowing is the intent, then it should be fully explicit to avoid surprises.

Otherwise, the feature in general seems good to me. What do you think of calling the stanza chdir? I have been thinking of a proper semantic for variable expansion, and it seems to me that chdir could be generalised so that it can appear pretty much anywhere.

@rgrinberg
Copy link
Member Author

rgrinberg commented Mar 16, 2020 via email

@ghost
Copy link

ghost commented Mar 16, 2020

Not sure about the syntax, but essentially you would declare that you want to override competing stanzas. For instance:

(shadow_other_stanzas
 (dirs ...))

@nojb
Copy link
Collaborator

nojb commented Mar 16, 2020

How would explicit shadowing look like? Shadowing dune files of vendored dirs is indeed what I’m looking for. I agree that the way it’s working out here is quite confusing. I’m fine with removing this part of the PR for now and just erroring out whenever there are competing dirs, vendored_dirs, data_only_dirs stanzas for a directory.

One possibility is for each chdir stanza to come with a merge_mode: merge (concatenate stanzas), replace (replace stanzas), etc.

@rgrinberg
Copy link
Member Author

Actually, I'm not entirely sure I need anything special. The following should just work:

(data_only_dirs foo)
(chdir foo ..)

There's no need for any shadowing here.

@ghost
Copy link

ghost commented Mar 16, 2020

Great, no shadowing is simpler :)

@rgrinberg rgrinberg changed the title [WIP] Add a (subdir ..) stanza [WIP] Add a (chdir ..) stanza Mar 16, 2020
@rgrinberg rgrinberg requested review from emillon and nojb as code owners March 17, 2020 12:12
@rgrinberg
Copy link
Member Author

@diml the implementation is now ready for review - there's no more shadowing.

Also, I found it quite difficult to reason about all the parent directories when computing the dune file. I've changed the algorithm to be a bit simpler by doing work upfront so that we need to look only at the dune file of the parent.

src/dune/file_tree.ml Outdated Show resolved Hide resolved
src/dune/file_tree.ml Outdated Show resolved Hide resolved
@rgrinberg rgrinberg changed the title [WIP] Add a (chdir ..) stanza Add a (chdir ..) stanza Mar 17, 2020
@rgrinberg
Copy link
Member Author

Docs are ready as well.

cc @samoht @jordwalke this stanza could be quite useful for your dune file generation needs. Please see the docs.

@rgrinberg rgrinberg removed the request for review from emillon March 18, 2020 19:14
@rgrinberg
Copy link
Member Author

rgrinberg commented Mar 19, 2020

One possibility is for each chdir stanza to come with a merge_mode: merge (concatenate stanzas), replace (replace stanzas), etc.

I think the latest version of the PR covers this functionality in two steps. To replace, one may ignore the dune file in a directory using data_only_dirs, and then use chdir to set it manually. Otherwise, merging is the default behavior. See the tests for an example.

@nojb
Copy link
Collaborator

nojb commented Mar 27, 2020

We just had a discussion offline and we discovered a slightly surprising behavior this feature introduces:

$ cat dune
(env (_ (env-vars FOO foo))
(chdir sub
 (rule (with-stdout-to bar (echo %{env:FOO=yyy})))
$ cat sub/dune
(env (_ (env-vars FOO bar)))

What should be the contents of bar in this case?

It should be bar I think -- chdir should be equivalent to writing the inner stanzas in the subdirectory, no ? It looks a bit strange, but I think that we may end up shooting ourselves in the foot if we try anything cleverer than that.

And if you want to make sure there is no shadowing of the environment variable, you would always do something like:

(with-stdout-to bar-env (echo %{env:FOO=yyy}))
(chdir sub
  (rule (with-stdout-to bar (cat ../bar-env))))

@rgrinberg
Copy link
Member Author

Thanks for the feedback. @diml it seems like the other devs agree that it's most obvious to interpret the semantics as the code being in separate dune files. I tend to agree because I don't think it would be intuitive for fields in env to be lexically scoped. If we were to introduce a let stanza however, I would certainly expect it to be lexical.

@rgrinberg
Copy link
Member Author

@diml I've updated the documentation to remove the shadowing example

@ghost
Copy link

ghost commented Mar 31, 2020

Sounds good, let's go for this semantic then.

@ghost
Copy link

ghost commented Mar 31, 2020

As discussed in the meeting, we should rename the stanza to something else than chdir given that the scoping of %{env...} is different between the chdir stanza and action.

@rgrinberg
Copy link
Member Author

@diml will do.

@aalekseyev also volunteered to review the PR.

@aalekseyev
Copy link
Collaborator

Let me try to clarify my understanding of the overall design.

You're not changing the interface between Build_system and File_tree modules. From the point of view of Build_system, these "virtual" directories are treated exactly the same as a normal source directory that has a dune file in it, with no way to distinguish them using File_tree API.

If that's the right understanding, then the design seems good to me.

When I volunteered to review it's specifically the Build_system changes I was thinking of, and I approve all 0 lines of them. :-)

That said, one difference between virtual and real dirs that will be observable to the build system is the actual presence of the directory on disk. Don't we make some assumptions about the source directories actually existing on disk in some cases? One example I was thinking of is promotion: what happens if I write a rule that promotes into a virtual directory?

src/dune/file_tree.ml Outdated Show resolved Hide resolved
src/dune/file_tree.ml Outdated Show resolved Hide resolved
src/dune/file_tree.ml Outdated Show resolved Hide resolved
src/dune/file_tree.ml Outdated Show resolved Hide resolved
src/dune/file_tree.ml Outdated Show resolved Hide resolved
doc/dune-files.rst Outdated Show resolved Hide resolved
src/dune/file_tree.ml Outdated Show resolved Hide resolved
@aalekseyev
Copy link
Collaborator

Overall looks good to me. I haven't done the most thorough review possible, just glanced through the code, but the design seems good and the tests look good, and there's nothing glaringly terrible in the code.

@rgrinberg
Copy link
Member Author

rgrinberg commented Apr 3, 2020 via email

src/dune/file_tree.mli Outdated Show resolved Hide resolved
Copy link
Collaborator

@aalekseyev aalekseyev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The last 4 commits look good too.

This stanza is of the form:

(subdir <dir>
 <sexp>)

The interpretation is the same as writing <sexp> in teh dune file of
<dir>.

Signed-off-by: Rudi Grinberg <me@rgrinberg.com>
@rgrinberg
Copy link
Member Author

Thanks for the review. I've renamed chdir to subdir as we've discussed.

@rgrinberg rgrinberg merged commit 547a6c4 into ocaml:master Apr 8, 2020
rgrinberg added a commit to rgrinberg/opam-repository that referenced this pull request Apr 10, 2020
…lugin, dune-private-libs and dune-glob (2.5.0)

CHANGES:

- Add a `--release` option meaning the same as `-p` but without the
  package filtering. This is useful for custom `dune` invocation in opam
  files where we don't want `-p` (ocaml/dune#3260, @diml)

- Fix a bug introduced in 2.4.0 causing `.bc` programs to be built
  with `-custom` by default (ocaml/dune#3269, fixes ocaml/dune#3262, @diml)

- Allow contexts to be defined with local switches in workspace files (ocaml/dune#3265,
  fix ocaml/dune#3264, @rgrinberg)

- Delay expansion errors until the rule is used to build something (ocaml/dune#3261, fix
  ocaml/dune#3252, @rgrinberg, @diml)

- [coq] Support for theory dependencies and compositional builds using
  new field `(theories ...)` (ocaml/dune#2053, @ejgallego, @rgrinberg)

- From now on, each version of a syntax extension must be explicitely tied to a
  minimum version of the dune language. Inconsistent versions in a
  `dune-project` will trigger a warning for version <=2.4 and an error for
  versions >2.4 of the dune language. (ocaml/dune#3270, fixes ocaml/dune#2957, @voodoos)

- [coq] Bump coq lang version to 0.2. New coq features presented this release
  require this version of the coq lang. (ocaml/dune#3283, @ejgallego)

- Prevent installation of public executables disabled using the `enabled_if` field.
  Installation will now simply skip such executables instead of raising an
  error. (ocaml/dune#3195, @voodoos)

- `dune upgrade` will now try to upgrade projects using versions <2.0 to version
  2.0 of the dune language. (ocaml/dune#3174, @voodoos)

- Add a `top` command to integrate dune with any toplevel, not just
  utop. It is meant to be used with the new `#use_output` directive of
  OCaml 4.11 (ocaml/dune#2952, @mbernat, @diml)

- Allow per-package `version` in generated `opam` files (ocaml/dune#3287, @toots)

- [coq] Introduce the `coq.extraction` stanza. It can be used to extract OCaml
  sources (ocaml/dune#3299, fixes ocaml/dune#2178, @rgrinberg)

- Load ppx rewriters in dune utop and add pps field to toplevel stanza. Ppx
  extensions will now be usable in the toplevel
  (ocaml/dune#3266, fixes ocaml/dune#346, @stephanieyou)

- Add a `(subdir ..)` stanza to allow evaluating stanzas in sub directories.
  (ocaml/dune#3268, @rgrinberg)

- Fix a bug preventing one from running inline tests in multiple modes
  (ocaml/dune#3352, @diml)

- Allow the use of the `%{profile}` variable in the `enabled_if` field of the
  library stanza. (ocaml/dune#3344, @mrmr1993)

- Allow the use of `%{ocaml_version}` variable in `enabled_if` field of the
  library stanza. (ocaml/dune#3339, @voodoos)

- Fix dune build freezing on MacOS when cache is enabled. (ocaml/dune#3249, fixes #ocaml/dune#2973,
  @artempyanykh)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants