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 only_sources field to copy_files stanza #9827

Merged
merged 20 commits into from
Feb 9, 2024
Merged

Conversation

jchavarri
Copy link
Collaborator

@jchavarri jchavarri commented Jan 24, 2024

Fixes #9709.

Adds new stanzas copy_files_src and copy_files_src# so that only source files and folders are considered when matching the pattern passed to the stanza.

About the implementation, I tried to keep it as minimal as possible, building on top of existing copy_files rules handling. This means there are parts of the rules generation function that are useless in the copy_files_src case, like the if not exists_or_generated check. But I thought this is better than adding a whole function that will share a lot of code with the original one.

About the tests, I am not sure how to proceed, maybe it's worth duplicating all existing copy_files tests with the new stanza, to see how it behaves?

@jchavarri jchavarri requested review from nojb and rgrinberg January 24, 2024 09:53
@jchavarri
Copy link
Collaborator Author

Another random thought for the future, is if it'd be desirable to deprecate copy_files so it gets renamed to copy_files_bld or copy_files_build, so that it's clearer for users the behavior of each stanza.

Signed-off-by: Javier Chávarri <[email protected]>
@emillon
Copy link
Collaborator

emillon commented Jan 24, 2024

About syntax: could the distinction be expressed as a new field in copy_files? such as:

(copy_files
 (only_sources)
 (files subdir/*.ml))

Or even:

(copy_files (source_files subdir/*.ml))

Signed-off-by: Javier Chávarri <[email protected]>
@jchavarri
Copy link
Collaborator Author

About syntax: could the distinction be expressed as a new field in copy_files?

Sure, added in 8434970.

@jchavarri jchavarri changed the title Add copy_files_src stanza Add only_sources field to copy_files stanza Jan 24, 2024
> (lang dune 3.13)
> EOF
$ cat >subdir/dune <<EOF
> (library (name foo))
Copy link
Member

Choose a reason for hiding this comment

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

Could you change the test not to rely on libraries? It should be easy enough to just use the files being copied as targets.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Sorry, i don't understand what you mean. The rule that has foo.re.ml as target is created by the library, afaiu. If I remove the library and try to do dune build subdir/foo.re.ml (which is what I assume the suggestion is about), dune will show Error: Don't know how to build subdir/foo.re.ml.

If I target the copied file foo.re directly, then I can't test the difference between regular copy_files behavior and the new behavior, because in both cases the target will be generated, because it's in the source.

Could you share a snippet of what you have in mind please?

Copy link
Member

@rgrinberg rgrinberg Jan 25, 2024

Choose a reason for hiding this comment

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

Something like this:

$ cat >target/dune <EOF
> (copy_files
>  (only_sources true)
>  (files foo/*))
> EOF
 
$ cat >foo/dune <<EOF
> (with-stdout-to in-build (echo ""))
> EOF

$ touch foo/in-source

$ dune build target/in-source # should pass
$ dune build target/in-build # should fail with unknown target
$  # now modify target/dune to set `(only_sources false)`
$ dune build target/in-build # should pass

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I tried this but get an error due to multiple rules generated:

  $ mkdir -p target foo
  $ cat >dune-project <<EOF
  > (lang dune 3.14)
  > EOF
  $ cat >target/dune <<EOF
  > (copy_files
  >  (files ../foo/*))
  > EOF
  $ cat >foo/dune <<EOF
  > (rule
  >  (with-stdout-to in-build
  >  (echo "")))
  > EOF

  $ touch foo/in-source

  $ dune build target/in-source # should pass
  Error: Multiple rules generated for _build/default/target/dune:
  - target/dune:2
  - file present in source tree
  Hint: rm -f target/dune
  [1]
  $ dune build target/in-build # should fail with unknown target
  Error: Multiple rules generated for _build/default/target/dune:
  - target/dune:2
  - file present in source tree
  Hint: rm -f target/dune
  [1]

Show the difference when `only_sources` is used

  $ cat >target/dune <<EOF
  > (copy_files
  >  (only_sources true)
  >  (files ../foo/*))
  > EOF

  $ dune build target/in-source # should pass
  Error: Multiple rules generated for _build/default/target/dune:
  - target/dune:3
  - file present in source tree
  Hint: rm -f target/dune
  [1]
  $ dune build target/in-build # should fail with unknown target
  Error: Multiple rules generated for _build/default/target/dune:
  - target/dune:3
  - file present in source tree
  Hint: rm -f target/dune
  [1]

Copy link
Member

Choose a reason for hiding this comment

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

I think you can just modify the glob to exclude dune. One simple way is to use an extension for your files and then select them with *.txt.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Thanks, I updated the test in f81d57f.

@@ -22,8 +23,16 @@ let long_form =
and+ mode = field "mode" ~default:Rule.Mode.Standard (check >>> Rule_mode_decoder.decode)
and+ enabled_if = Enabled_if.decode ~allowed_vars:Any ~since:(Some (2, 8)) ()
and+ files = field "files" (check >>> String_with_vars.decode)
and+ only_sources = field_b "only_sources"
Copy link
Member

Choose a reason for hiding this comment

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

This field should be available starting 3.14

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

n/m this was a larger change that I expected, created #9840 for it, should be merged first.

@nojb
Copy link
Collaborator

nojb commented Jan 24, 2024

About syntax: could the distinction be expressed as a new field in copy_files? such as:

(copy_files
 (only_sources)
 (files subdir/*.ml))

Or even:

(copy_files (source_files subdir/*.ml))

Sorry for coming late to the discussion, but I think (source_files ...) is somewhat better than (only_sources) which feels less compositional (eg in the future we could support multiple globs in a single copy_files stanza, both from source and build directory, etc).

@jchavarri
Copy link
Collaborator Author

@nojb I am not sure about the suggested approach. Note that copy_files also support a short form: (copy_files <glob>). What would be the behavior in that case if we add a source_files field to the stanza?

With the current approach using only_sources boolean field, there is no ambiguity, as there is only a single field where the glob is defined.

in the future we could support multiple globs in a single copy_files stanza, both from source and build directory

As this is already achievable using two copy_files stanzas, it is not a much needed feature (for me / imo).

@jchavarri jchavarri requested a review from rgrinberg January 25, 2024 11:26
@@ -27,7 +27,7 @@ end
module Version = struct
type t = int * int

let latest = 3, 13
let latest = 3, 14
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Note I had to change this to be able to run the test. Not sure if bumping this version involves more work / should be done in a different PR.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It's a bit surprising that this version is stored in dune-rpc library 🤔

@nojb
Copy link
Collaborator

nojb commented Jan 25, 2024

@nojb I am not sure about the suggested approach. Note that copy_files also support a short form: (copy_files <glob>). What would be the behavior in that case if we add a source_files field to the stanza?

Generally speaking, the short form is legacy; it dates from when the (copy_files) stanza had only one field; I don't think we should support new additions to the short form.

For the question at hand ((copy_files (only_sources) (files ...)) vs (copy_files (source_files ...))): even though I have a slight preference for the latter one, I don't have a strong argument for it, so feel free to go with your intuition and what the other devs think. Just a remark: the name only_sources suggests that the files copied with (only_sources) are a subset of those copied without it, but if I'm not wrong, this is not quite what the implementation is doing, rather, we are expanding the glob in the source directory rather than in the build directory, and this could result in extra files (which are never copied to the build directory) being considered. Is this correct, or am I missing something?

@jchavarri
Copy link
Collaborator Author

Just a remark: the name only_sources suggests that the files copied with (only_sources) are a subset of those copied without it, but if I'm not wrong, this is not quite what the implementation is doing, rather, we are expanding the glob in the source directory rather than in the build directory, and this could result in extra files (which are never copied to the build directory) being considered. Is this correct, or am I missing something?

Your assumption is correct, I hadn't thought of that scenario. Maybe we could rename it to from_source? Assuming we don't go with source_files... I don't have a strong opinion either, and I didn't know the short form was legacy. Curious to see what @emillon and @rgrinberg think.

@jchavarri jchavarri mentioned this pull request Jan 25, 2024
@rgrinberg
Copy link
Member

I wouldn't say the short form is legacy, but it certainly doesn't need to support all the features of the full stanza.

rather, we are expanding the glob in the source directory rather than in the build directory, and this could result in extra files (which are never copied to the build directory) being considered. Is this correct, or am I missing something?

When could this make a difference? Sources files in a directory are always a subset of the targets in that directory. Note that copying things to the build directory is nothing more than setting up a copy rule from the source to the build dir.

@rgrinberg rgrinberg added this to the 3.14.0 milestone Jan 25, 2024
Copy link
Member

@rgrinberg rgrinberg left a comment

Choose a reason for hiding this comment

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

LGTM apart from the usual boilerplate:

  • Reference docs
  • CHANGES entry
    No preference for whether to use a field or a constructor. I see no issues with using multiple copy_files stanzas if it's not possible to express everything in a single stanza.

Signed-off-by: Javier Chávarri <[email protected]>
@jchavarri
Copy link
Collaborator Author

LGTM apart from the usual boilerplate:

Added in 6166c80.

Signed-off-by: Javier Chávarri <[email protected]>
Signed-off-by: Javier Chávarri <[email protected]>
@jchavarri jchavarri changed the title Add only_sources field to copy_files stanza Add sources field to copy_files stanza Jan 26, 2024
@jchavarri
Copy link
Collaborator Author

@emillon Thanks. I think sources is better, updated the PR to it in dd2bd16.

Signed-off-by: Javier Chávarri <[email protected]>
Signed-off-by: Javier Chávarri <[email protected]>
@rgrinberg
Copy link
Member

The previous form actually had a concrete advantage of the current, you could extend it to enable/disable it with pforms. E.g.

(copy_files
 (only_sources (= %{os} macosx)
 (glob *))

From my experience, the above ends up being useful for many fields. So I would recommend to not forbid it.

This reverts commit dd2bd16.

Signed-off-by: Javier Chávarri <[email protected]>
@jchavarri
Copy link
Collaborator Author

The previous form

@rgrinberg I understand you are referring to the field rename from only_sources to sources. Reverted in d1ee4b7.

@jchavarri jchavarri changed the title Add sources field to copy_files stanza Add only_sources field to copy_files stanza Jan 29, 2024
Signed-off-by: Javier Chávarri <[email protected]>
@emillon
Copy link
Collaborator

emillon commented Jan 30, 2024

(only_sources (= %{os} macosx)) is only possible if this field has type Blang.t and is expanded later. Is there a motivating use case for this?

@rgrinberg
Copy link
Member

There's no motivating use case, but usually what ends up happening is that somebody requires the blang functionality eventually and then we end up having to add more versioning code to add blang support. Adding such versioning code is usually about as much work as just allowing blang. So yes I'd prefer to keep the language more uniform and allow toggles to take blangs

@jchavarri
Copy link
Collaborator Author

you could extend it to enable/disable it with pforms

@rgrinberg Just a clarification, are you expecting this extension to be part of this PR as well? Or were you referring purely to the naming (only_sources seems to fit better the pform usage than sources).

@emillon emillon mentioned this pull request Feb 6, 2024
20 tasks
@emillon
Copy link
Collaborator

emillon commented Feb 8, 2024

I just added the blang part, with a short syntax for true. @rgrinberg how does it look?

@emillon emillon requested a review from rgrinberg February 8, 2024 12:58
@emillon emillon merged commit fe12953 into ocaml:main Feb 9, 2024
25 of 26 checks passed
emillon added a commit to emillon/opam-repository that referenced this pull request Feb 9, 2024
CHANGES:

### Added

- Introduce a `(dynamic_include ..)` stanza. This is like `(include foo)` but
  allows `foo` to be the target of a rule. Currently, there are some
  limitations on the stanzas that can be generated. For example, public
  executables, libraries are currently forbidden. (ocaml/dune#9913, @rgrinberg)

- Introduce `$ dune promotion list` to print the list of available promotions.
  (ocaml/dune#9705, @moyodiallo)

- If Sherlodoc is installed, add a search bar in generated HTML docs (ocaml/dune#9772,
  @EmileTrotignon)

- Add `only_sources` field to `copy_files` stanza (ocaml/dune#9827, fixes ocaml/dune#9709,
  @jchavarri)

- The `(foreign_library)` stanza now supports the `(enabled_if)` field. (ocaml/dune#9914,
  @nojb)

### Fixed

- Fix `$ dune install -p` incorrectly recognizing packages that are supposed to
  be filtered (ocaml/dune#9879, fixes ocaml/dune#4814, @rgrinberg)

- subst: correctly handle opam files in opam/ subdirectory (ocaml/dune#9895, fixes ocaml/dune#9862,
  @emillon)

- Odoc private rules are not set up if a library is not available due to
  `enabled_if` (ocaml/dune#9897, @rgrinberg and @jchavarri)

### Changed

- When dune language 3.14 is enabled, resolve the binary in `(run %{bin:..}
  ..)` from where the binary is built. (ocaml/dune#9708, @rgrinberg)

- boot: remove single-command bootstrap. This was an alternative bootstrap
  strategy that was used in certain conditions. Removal makes the bootstrap a
  bit slower on Linux when only a single core is available, but bootstrap is
  now reproducible in all cases. (ocaml/dune#9735, fixes ocaml/dune#9507, @emillon)
emillon added a commit to emillon/opam-repository that referenced this pull request Feb 12, 2024
CHANGES:

### Added

- Introduce a `(dynamic_include ..)` stanza. This is like `(include foo)` but
  allows `foo` to be the target of a rule. Currently, there are some
  limitations on the stanzas that can be generated. For example, public
  executables, libraries are currently forbidden. (ocaml/dune#9913, @rgrinberg)

- Introduce `$ dune promotion list` to print the list of available promotions.
  (ocaml/dune#9705, @moyodiallo)

- If Sherlodoc is installed, add a search bar in generated HTML docs (ocaml/dune#9772,
  @EmileTrotignon)

- Add `only_sources` field to `copy_files` stanza (ocaml/dune#9827, fixes ocaml/dune#9709,
  @jchavarri)

- The `(foreign_library)` stanza now supports the `(enabled_if)` field. (ocaml/dune#9914,
  @nojb)

### Fixed

- Fix `$ dune install -p` incorrectly recognizing packages that are supposed to
  be filtered (ocaml/dune#9879, fixes ocaml/dune#4814, @rgrinberg)

- subst: correctly handle opam files in opam/ subdirectory (ocaml/dune#9895, fixes ocaml/dune#9862,
  @emillon)

- Odoc private rules are not set up if a library is not available due to
  `enabled_if` (ocaml/dune#9897, @rgrinberg and @jchavarri)

### Changed

- When dune language 3.14 is enabled, resolve the binary in `(run %{bin:..}
  ..)` from where the binary is built. (ocaml/dune#9708, @rgrinberg)

- boot: remove single-command bootstrap. This was an alternative bootstrap
  strategy that was used in certain conditions. Removal makes the bootstrap a
  bit slower on Linux when only a single core is available, but bootstrap is
  now reproducible in all cases. (ocaml/dune#9735, fixes ocaml/dune#9507, @emillon)
@jchavarri jchavarri deleted the source-files branch May 30, 2024 12:56
nberth pushed a commit to nberth/opam-repository that referenced this pull request Jun 18, 2024
CHANGES:

### Added

- Introduce a `(dynamic_include ..)` stanza. This is like `(include foo)` but
  allows `foo` to be the target of a rule. Currently, there are some
  limitations on the stanzas that can be generated. For example, public
  executables, libraries are currently forbidden. (ocaml/dune#9913, @rgrinberg)

- Introduce `$ dune promotion list` to print the list of available promotions.
  (ocaml/dune#9705, @moyodiallo)

- If Sherlodoc is installed, add a search bar in generated HTML docs (ocaml/dune#9772,
  @EmileTrotignon)

- Add `only_sources` field to `copy_files` stanza (ocaml/dune#9827, fixes ocaml/dune#9709,
  @jchavarri)

- The `(foreign_library)` stanza now supports the `(enabled_if)` field. (ocaml/dune#9914,
  @nojb)

### Fixed

- Fix `$ dune install -p` incorrectly recognizing packages that are supposed to
  be filtered (ocaml/dune#9879, fixes ocaml/dune#4814, @rgrinberg)

- subst: correctly handle opam files in opam/ subdirectory (ocaml/dune#9895, fixes ocaml/dune#9862,
  @emillon)

- Odoc private rules are not set up if a library is not available due to
  `enabled_if` (ocaml/dune#9897, @rgrinberg and @jchavarri)

### Changed

- When dune language 3.14 is enabled, resolve the binary in `(run %{bin:..}
  ..)` from where the binary is built. (ocaml/dune#9708, @rgrinberg)

- boot: remove single-command bootstrap. This was an alternative bootstrap
  strategy that was used in certain conditions. Removal makes the bootstrap a
  bit slower on Linux when only a single core is available, but bootstrap is
  now reproducible in all cases. (ocaml/dune#9735, fixes ocaml/dune#9507, @emillon)
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.

copy_files glob should operate on source files (not target files inside _build folder)
4 participants