Skip to content

[merlin] Cleanup leftover merlin files#4261

Merged
voodoos merged 8 commits intoocaml:mainfrom
voodoos:merlin-cleanup
Feb 25, 2021
Merged

[merlin] Cleanup leftover merlin files#4261
voodoos merged 8 commits intoocaml:mainfrom
voodoos:merlin-cleanup

Conversation

@voodoos
Copy link
Copy Markdown
Collaborator

@voodoos voodoos commented Feb 19, 2021

Would fix #4168

This PR is a proposal to automatically get rid of .merlin files that were promoted by earlier versions of Dune (mainly 2.7.1).

The criteria is:

  • The file _build/.to-delete-in-source-tree that contains the list of promoted until-clean files has a .merlin entry for the current directory.
  • No rule declares promoting a file named .merlin in the current directory.

This way, user that setup custom rules to generate custom .merlin won't see there promoted file disapear unexpectedly.
I will test it in real upgrade conditions this afternoon.

I understand this may feel too hacky. If you feel deleting the files that way is too sketchy we always can raise a warning instead, asking for a dune clean.

@voodoos voodoos added this to the 2.8.3 milestone Feb 19, 2021
@voodoos voodoos requested review from a user, aalekseyev and rgrinberg February 19, 2021 12:40
@voodoos
Copy link
Copy Markdown
Collaborator Author

voodoos commented Feb 19, 2021

I can confirm that:

  • building a project with Dune 2.7.1 generates .merlin files
  • rebuilding with Dune 2.8.2 does not delete these files
  • rebuilding with this PR does

@rgrinberg
Copy link
Copy Markdown
Member

@aalekseyev mind taking a look at this?

@aalekseyev
Copy link
Copy Markdown
Collaborator

Looking.

let merlin_in_src = Path.Source.(relative source_dir merlin_file) in
let source_files_to_ignore =
if
Path.Set.mem (Promoted_to_delete.load ()) (Path.source merlin_in_src)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Calling load once per directory sounds expensive. My understanding is that we expect this file to have size O(n) where n is the number of directories with .merlin files (eve without taking into account anything else the user happens to promote) and you're loading it n times, which makes for O(n^2) time complexity.

I think we should be able to change it so that load is only called once, and Promoted_to_delete.dump simply writes out the db without calling load again.

@aalekseyev
Copy link
Copy Markdown
Collaborator

I just pushed a commit extracting the new code into a separate function and adding some comments.

voodoos and others added 6 commits February 25, 2021 14:16
Signed-off-by: Ulysse Gérard <thevoodoos@gmail.com>
Signed-off-by: Ulysse Gérard <thevoodoos@gmail.com>
Signed-off-by: Ulysse Gérard <thevoodoos@gmail.com>
Signed-off-by: Arseniy Alekseyev <aalekseyev@janestreet.com>
Signed-off-by: Arseniy Alekseyev <aalekseyev@janestreet.com>
Signed-off-by: Ulysse Gérard <thevoodoos@gmail.com>
@voodoos
Copy link
Copy Markdown
Collaborator Author

voodoos commented Feb 25, 2021

Thanks for your review @aalekseyev.

I modified the load function to read the database from disk only once.
I also took that opportunity change the behavior of remove_now. The updated database (without .merlin) files will be dumped only at the end of the build, not each time a .merlin file is removed.

There are still checks that will run for each folder, do you think it is an issue ?
I am thinking about that test:

Path.Set.mem (Promoted_to_delete.load ()) (Path.source merlin_in_src)
&& not (Path.Source.Set.mem source_files_to_ignore merlin_in_src)

Signed-off-by: Arseniy Alekseyev <aalekseyev@janestreet.com>
Signed-off-by: Arseniy Alekseyev <aalekseyev@janestreet.com>
@aalekseyev
Copy link
Copy Markdown
Collaborator

I pushed a commit simplifying the db management code in Promoted_to_delete. Instead of storing two chunks of the database that need to be merged at some point, I think it's much simpler to store just one database that's already merged. That makes it easy (or at least easier) to reason about watching builds and it seems simpler in general.

Please let me know if I'm not seeing a specific reason to avoid that change.

@aalekseyev
Copy link
Copy Markdown
Collaborator

Running a simple test membership check once per directory does not sound problematic to me.

@voodoos
Copy link
Copy Markdown
Collaborator Author

voodoos commented Feb 25, 2021

I pushed a commit simplifying the db management code in Promoted_to_delete. [...]

Please let me know if I'm not seeing a specific reason to avoid that change.

I considered doing it myself, I think it is a very reasonable change.
(At first I thought it would make load happen more often than before but it doesn't).

@aalekseyev
Copy link
Copy Markdown
Collaborator

There are still checks that will run for each folder, do you think it is an issue ?

I think doing a couple of extra map lookups per directory is fine.

@voodoos voodoos merged commit 20df2de into ocaml:main Feb 25, 2021
voodoos added a commit to voodoos/dune that referenced this pull request Feb 25, 2021
* Make Build_system delete left-over `.merlin` files
* simplify code managing the Promoted_to_delete db
* Add a test for merlin files cleanup

Signed-off-by: Ulysse Gérard <thevoodoos@gmail.com>
Co-authored-by: Arseniy Alekseyev <aalekseyev@janestreet.com>
voodoos added a commit to voodoos/dune that referenced this pull request Feb 25, 2021
Signed-off-by: Ulysse Gérard <thevoodoos@gmail.com>
voodoos added a commit that referenced this pull request Feb 25, 2021
Signed-off-by: Ulysse Gérard <thevoodoos@gmail.com>
rgrinberg pushed a commit that referenced this pull request Mar 7, 2021
* Make Build_system delete left-over `.merlin` files
* simplify code managing the Promoted_to_delete db
* Add a test for merlin files cleanup

Signed-off-by: Ulysse Gérard <thevoodoos@gmail.com>
Co-authored-by: Arseniy Alekseyev <aalekseyev@janestreet.com>
rgrinberg pushed a commit that referenced this pull request Mar 7, 2021
Signed-off-by: Ulysse Gérard <thevoodoos@gmail.com>
rgrinberg added a commit to rgrinberg/opam-repository that referenced this pull request Mar 7, 2021
…ne-action-plugin, dune-private-libs and dune-glob (2.8.3)

CHANGES:

- Make `patdiff` show refined diffs (ocaml/dune#4257, fixes ocaml/dune#4254, @hakuch)

- Fixed a bug that could result in needless recompilation under Windows due to
  case differences in the result of `Sys.getcwd` (observed under `emacs`).
  (ocaml/dune#3966, @nojb).

- Restore compatibility with Coq < 8.10 for coq-lang < 0.3 , document
  that `(using coq 0.3)` does require Coq 8.10 at least (ocaml/dune#4224, fixes
  ocaml/dune#4142, @ejgallego)

- Add a META rule for 'compiler-libs.native-toplevel' (ocaml/dune#4175, @AltGr)

- No longer call `chmod` on symbolic links (fixes ocaml/dune#4195, @dannywillems)

- Dune no longer automatically create or edit `dune-project` files
  (ocaml/dune#4239, fixes ocaml/dune#4108, @jeremiedimino)

- Have `dune` communicate the location of the standard library directory to
  `merlin` (ocaml/dune#4211, fixes ocaml/dune#4188, @nojb)

- Workaround incorrect exception raised by Unix.utimes (OCaml PR#8857) in
  Path.touch on Windows (ocaml/dune#4223, @dra27)

- `dune ocaml-merlin` is now able to provide configuration for source files in
  the `_build` directory. (ocaml/dune#4274, @voodoos)

- Automatically delete left-over Merlin files when rebuilding for the first time
  a project previously built with Dune `<= 2.7`. (ocaml/dune#4261, @voodoos, @aalekseyev)

- Fix `ppx.exe` being compiled for the wrong target when cross-compiling
  (ocaml/dune#3751, fixes ocaml/dune#3698, @toots)

- `dune top` correctly escapes the generated toplevel directives, and make it
  easier for `dune top` to locate C stubs associated to concerned libraries.
  (ocaml/dune#4242, fixes ocaml/dune#4231, @nojb)

- Do not pass include directories containing native objects when compiling
  bytecode (ocaml/dune#4200, @nojb)
@rand00
Copy link
Copy Markdown

rand00 commented Aug 20, 2021

Not all of my .merlin files were deleted after upgrading to dune.2.9.0, and would have loved a warning from dune that it was using a .merlin file instead of dune ocaml-merlin

@voodoos
Copy link
Copy Markdown
Collaborator Author

voodoos commented Aug 30, 2021

Not all of my .merlin files were deleted after upgrading to dune.2.9.0, and would have loved a warning from dune that it was using a .merlin file instead of dune ocaml-merlin

Was the leftover .merlin file created by Dune ? Some edge cases can benefit from using a custom merlin file so user-created ones are not deleted by Dune.

@rand00
Copy link
Copy Markdown

rand00 commented Aug 30, 2021

Yes it was by Dune, had a look at it before I deleted it manually. I'm pretty sure that I've never opened that file before, so I wouldn't have edited it accidentally. How does Dune determine if file was created by it?

@voodoos
Copy link
Copy Markdown
Collaborator Author

voodoos commented Aug 30, 2021

It keeps a database of promoted until-clean files so that they are deleted when cleaning. If you manually removed your _build directory once this database might not be in sync since leftover .merlin files would be considered user-created when a new build is done after that.

I don't see an easy way to distinguish between this kind of desynchronization and legit user-created .merlin files...

@rand00
Copy link
Copy Markdown

rand00 commented Aug 30, 2021

No I can see the problem - though my thought was more in the direction of Dune informing the user after upgrading to a version that switches away from .merlin files, if there were still .merlin files present that it didn't delete.

My primary problem was that I had to debug what was wrong with Merlin without any hints from Dune or Merlin

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.

[merlin] Upgrading to Dune 2.8 confuses Merlin with left-over config files

4 participants