alchemist.el
alchemist.el copied to clipboard
problem using alchemist mode in mix umbrella project
I have an mix umbrella project with a couple of apps. A lot of the alchemist features doesn't work too well because the current project is seen to be the umbrella. Is it possible to select one of the apps as the current alchemist project instead?
Hi @7er
I'm not that experienced with how umbrella projects are structured, do you have a example codebase where I can have a look at it. I guss becaue Alchemist needs to have a proper mix project root to work correct. As you already mentioned it might work well with the selected apps inside a umbrella project because these are mix based.
But I will have a look at this one and it would be great with an example codebase for testing.
Absolutely: https://github.com/7er/kv_umbrella
Structure overview:
kv_umbrella/
mix.exs
apps/
kv/
mix.exs
lib/
kv_server/
mix.exs
lib/
kv_api/
mix.exs
lib/
PS: I've experimented a little more, and it seems that if I the first file I open is inside apps/kv_api, then the context for alchemist will be kv_api and everything will work ok. Maybe the only problem is that alchemist will not change context when it has selected kv_umbrella as the project and I visit a file lower in the directory hierarchy.
BTW: I'd be fine with knowing a way to select the alchemist mix project manually in some way.
Actually I think letting me select which mix project I want to be in the context of, would be the only workable solution as alchemist couldn't possibly know (without reading my mind) if I wanted to be in the umbrella or a sub-project for a certain operation.
Could we use ctrl-u for when you want to execute commands against the umbrella, and without for when you want the current sub project you are in?
The problem is that we have no way to check if we're in an umbrella project and the sub mix projects are just mix projects there is no evidance about that's a sub project. Hex packages for example have a .hex
file which makes it easy to identify if were inside an hex package.
About the idea to make it always selectable in which context alchemist functionality would be executed is not a good idea, the whole workflow would be so much break apart. Sure, if there would be a way to identify umbrella sub mix projects and umbrella projects at all it could be made dynamicly. But for example what's about completion, completion should always be just executed in the context of the root project (in this case the umbrella project root, because sub projects are also just dependencies and the compiled BEAM file informations are just in the root of the umbrella project.
What you guys think about that? I'm open for ideas and feedback.
We were discussing this issue briefly on IRC.
There's no 100% sure way to detect if we're in umbrella, but there are couple heuristics that could be used:
- checking if
mix.exs
is underapps/app_name
path. - there's
mix.exs
but nodeps
or_build
(_build
existed in umbrella applications prior to 1.2), - in
mix.exs
there arebuild_path
,config_path
anddeps_path
with values pointing to parent directory, - look not just for the first
mix.exs
file, but for the top-level one, - look not just for
mix.exs
but also for VCS-related files like.git
Another solution, that is acceptable is requiring each application in umbrella to have some file marking it as such, like .umberlla-app
.
Even if alchemist is able to detect umbrellas the question of whether to run tasks from top-level or from sub-apps still remains. There are some tasks you always want to run from the top (phoenix.start
), some you want to run always from the sub-apps (ecto.gen.migration
or phoenix.gen.something
) and some that you sometimes want to run from top-level and sometimes from a sub-app (most notably test
).
A temporary workaround for the completion issues is to symlink _build
in the app directories to ../../_build
.
Here is an solution, I'm not experienced enough with emacs script to implement it in a reasonable amount of time:
So it seems like the emacs script can run arbitrary elixir code so you can execute: Mix.Project.build_path with mix run
Then you can get the build directory into the script, you can also do the same trick with the elixir server and swap out elixirc for mix run.
You can also change the indicator for a root of the project with advice. It's not pretty, but it works for me now:
(defadvice alchemist-project-root (around seancribbs/alchemist-project-root activate)
(let ((alchemist-project-mix-project-indicator ".git"))
ad-do-it))
(defun seancribbs/activate-alchemist-root-advice ()
"Activates advice to override alchemist's root-finding logic"
(ad-activate 'alchemist-project-root))
(add-to-list 'elixir-mode-hook 'seancribbs/activate-alchemist-root-advice)
Is this not working yet?
@michaelraskansky you could add the name of the sub project as an argument to a function that would switch context from the top level app to the sub app, then that runs the mix command, then moves context back to the top level.
With that you can make the default context whatever directory the file in the active buffer is in.
@tonini wouldn't it be good to have the ability to switch contexts in alchemist somewhere, even if it's not visible to a user?
Sorry if I'm making a crazy suggestion. I'm pretty new to elixir and elisp
I would really love to see this solved.
@seancribbs I'm having trouble getting your workaround to work. Although it is quite possibly because I am using spacemacs.
What about just doing this: https://github.com/slashmili/alchemist.vim/commit/c19cb7d09518eb07f3b05b940f8475fa45daa03c#diff-f5284b7f9196da43f995606163114982R358