When running mix clean --deps, the .erl files generated from .xrl/.yrl are left behind.
All artefacts and intermediate files for the dependencies are deleted after running mix clean --deps, leaving the tree as it looked after mix deps.get, before the compilation.
I'll use Absinthe as an example dependency. I'm using a GitHub tag instead of Hex version, because the artefact pushed to Hex has the .erl files in question included for some reason (which might be a separate issue around mix hex.publish that's outside of the scope for this bug report).
mix new mix_bug && cd mix_bug{:absinthe, git: "https://github.com/absinthe-graphql/absinthe.git", tag: "v1.4.13"} to the list of deps.mix deps.get.erl files:$ ls deps/absinthe/src
absinthe_lexer.xrl absinthe_parser.yrl
mix compile && mix clean --deps.erl files should be gone after cleaning, but they are not:$ ls deps/absinthe/src/
absinthe_lexer.erl absinthe_lexer.xrl absinthe_parser.erl absinthe_parser.yrl
$ elixir --version
Erlang/OTP 21 [erts-10.1] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe] [dtrace]
Elixir 1.7.3 (compiled with Erlang/OTP 21)
$ mix --version
Erlang/OTP 21 [erts-10.1] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe] [dtrace]
Mix 1.7.3 (compiled with Erlang/OTP 21)
I was checking the clean task and it uses a simple approach of cleaning the _build/deps folder instead of invoking the deps.clean task like it does for the project. Would make sense to call this task?
If so, I also notice that deps.clean does a similar thing. Would make sense to change deps.clean first to consider those files?
@ggcampinho unfortunately I'm not familiar with the codebase enough to definitely answer your questions (assuming they are for me :)), but from a common sense point of view it would be much better to use the same logic for the dependencies as for the project itself.
Also, the dependencies might be built by something other than Mix, e.g. rebar, and probably should be cleaned using that as well to accommodate for custom scripts/hooks, so maybe the cleaning logic should mirror the dependency compilation.
@ggcampinho yes, I think we need to traverse the deps but we need to be careful with some things:
As long as we have those in mind, we should be good. I would start with changing deps.clean and then we can figure out a way of changing clean too.
I think a simple approach might be to change how the leex and yecc compilers work in Elixir - instead of writing the files to /src and then letting the erlang compiler do the job, we could have them write the temporary .erl file somewhere in /_build and compile to .beam directly. This means we wouldn't have any intermediary files in source directories.
I am on this!
Ok, I am not on this. I think the solution of changing the compiler is not going to fly. 馃棥
We probably need to change deps.clean instead, as @ggcampinho first suggested. @ggcampinho are you planning to tackle this?
Just reading through this thread, I gave it a go on removing those .erl files that get built in deps/{package}/src. This works, but also does not sound like the solution @josevalim outlined here.
We need to make sure before invoking the clean task, the dependency is OK, otherwise cleaning can fail or we may even end-up trying to compile the dependency only to clean it
how do we accomplish making sure the dependency is OK?
Just thought I would try and give this a go!
@drincruz right. We cannot hardcode the "src" directory because any dependency may have multiple compilers and any other directory can have compiled artefacts. It may be that the best way to solve this is to actually simplify the depending cleaning into two: "build" and "source" and it is always all or nothing, instead of being granular.
@josevalim yeah, i figured it wouldn't have been as straight forward as i thought!
i think i have a bit of free time before i get busy some again, so i'll try and take a look some more later! 馃憤
Another suggestion given by @michalmuskala in #10153 is to emit the .beam files directly from .yrl/.xrl compilers.
@michalmuskala I looked into your solution and it has complexities too. Namely, the .yrl and .xrl files may depend on other files as behaviours and parse transforms, and we would need to compile those first. It is hard for this to happen in practice but it is technically a limitation (and a backwards incompatible change).
deps.clean may be the best option here after all... it will also be the most correct one for anyone implementing other compilers.
Most helpful comment
I think a simple approach might be to change how the
leexandyecccompilers work in Elixir - instead of writing the files to/srcand then letting theerlangcompiler do the job, we could have them write the temporary.erlfile somewhere in/_buildand compile to.beamdirectly. This means we wouldn't have any intermediary files in source directories.