{"id":5261,"date":"2016-03-31T11:20:07","date_gmt":"2016-03-31T14:20:07","guid":{"rendered":"http:\/\/blog.plataformatec.com.br\/?p=5261"},"modified":"2016-03-31T15:38:25","modified_gmt":"2016-03-31T18:38:25","slug":"inspecting-changing-and-debugging-elixir-project-dependencies","status":"publish","type":"post","link":"http:\/\/blog.plataformatec.com.br\/2016\/03\/inspecting-changing-and-debugging-elixir-project-dependencies\/","title":{"rendered":"Inspecting, changing and debugging Elixir project dependencies"},"content":{"rendered":"
You have probably heard that Elixir is very explicit and I\u2019d say the same!<\/p>\n
One of the things I really like in Elixir projects is that its dependencies are all explicitly included in the After working on a project for a while, I\u2019ve noticed a strange behavior in one of our dependencies. I’ve opened the That seems logical, doesn\u2019t it? For my surprise, I didn\u2019t get the expected behavior. The reason is straight-forward. Elixir projects (and its dependencies) are by default compiled for The kind of task we execute is deterministic. Running a test will make our What I did before would work if I tried to call the function I was inspecting through There\u2019s a simple test we can run to understand this better:<\/p>\n Instead of running When we declare our dependencies in the When we set \n Path and in umbrella dependencies are automatically recompiled by the parent project whenever they change.<\/em><\/strong>\n<\/p><\/blockquote>\n This way, every time I make a change and run a Mix task like An important consideration here is that we can inform any path in this option, it doesn\u2019t need to be a source code in the We know that Phoenix Framework uses In order to inspect I believe that Elixir has already proven that explicitness is a great asset. Keeping project’s dependencies in In case you find a bug in any of your dependencies, we strongly recommend that you submit a pull request back to its repository. You\u2019ll help other developers that are going through the same issue and you’ll he the community growth.<\/p>\n What about you? Are there any tips you\u2019d like to share for debugging Elixir dependencies?<\/p>\n You have probably heard that Elixir is very explicit and I\u2019d say the same! One of the things I really like in Elixir projects is that its dependencies are all explicitly included in the deps\/ directory. Every time we\u2019re curious about how a dependency works, we can just look at deps\/lib-name. After working on a … \u00bb<\/a><\/p>\n","protected":false},"author":38,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0,"footnotes":""},"categories":[1],"tags":[247,246,143,245],"aioseo_notices":[],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"http:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts\/5261"}],"collection":[{"href":"http:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/users\/38"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/comments?post=5261"}],"version-history":[{"count":9,"href":"http:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts\/5261\/revisions"}],"predecessor-version":[{"id":5264,"href":"http:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/posts\/5261\/revisions\/5264"}],"wp:attachment":[{"href":"http:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/media?parent=5261"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/categories?post=5261"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.plataformatec.com.br\/wp-json\/wp\/v2\/tags?post=5261"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}deps\/<\/code> directory. Every time we\u2019re curious about how a dependency works, we can just look at
deps\/lib-name<\/code>.<\/p>\n
deps\/lib-name<\/code> directory in my editor, inserted a couple
IO.inspect<\/code> calls, and recompiled my dependencies with:<\/p>\n
mix deps.compile\n<\/code><\/pre>\n
dev<\/code>,
test<\/code> and
prod<\/code> environments. These compiled files are located in
_build\/<\/code>, in a directory that holds the environment name (
_build\/dev\/<\/code>,
_build\/test\/<\/code> and
_build\/prod\/<\/code>). Accessing the applied changes in the source code depends on which environment we\u2019re running it.<\/p>\n
_build\/test\/<\/code> compiled files to be used, just like
iex -S mix<\/code> would use
build\/dev\/<\/code> files and so on.<\/p>\n
iex -S mix<\/code>. That\u2019s only because Elixir\u2019s default environment is
dev<\/code>. In order to make those changes to be visible in my tests, I\u2019d have to:<\/p>\n
MIX_ENV=test mix deps.compile\n<\/code><\/pre>\n
\n
mix new project<\/code><\/li>\n
iex -S mix<\/code><\/li>\n
_build<\/code> directory and notice that we now have a
_build\/dev<\/code> directory with that project’s compiled file<\/li>\n
mix test<\/code> and notice that we now have a
_build\/test<\/code><\/li>\n<\/ol>\n
Using
:path<\/code> option<\/h2>\n
mix deps.compile<\/code> for every change, there is a more convenient alternative.<\/p>\n
mix.exs<\/code> file we need to give it the library name and its version. We can also give it some extra options, among them there is a specific option that will help us when debugging dependencies:
path<\/code>.<\/p>\n
defp deps do\n [{:plug, path: \"deps\/plug\"},\n ...]\n end\n<\/code><\/pre>\n
:path<\/code>, our dependency will be automatically recompiled by our project, as mentioned in Mix.Tasks.Deps docs<\/a> (we can also access it through
mix help deps<\/code>).<\/p>\n
mix test<\/code> or
iex -S mix<\/code>, the dependency will be recompiled without having to run the compile task over and over again. With the
path<\/code> option we can also omit the version because it’ll be retrieved from the project being addressed.<\/p>\n
deps\/<\/code> directory. It could, for example, point to a checkout of a dependency in our machine. This is an excellent option when we\u2019re working on an open source project. We can test the changes we intend to submit (or to find an issue) inside a real project more easily.<\/p>\n
A dependency of other dependencies<\/h2>\n
Plug<\/code> for managing its requests but it\u2019s not listed in our project dependencies. That\u2019s because Plug is a Phoenix dependency<\/a>.<\/p>\n
Plug<\/code> we\u2019d have to include it on our
deps<\/code> function and use the
override: true<\/code> option. Otherwise Mix will warn us that there is a dependency conflict.<\/p>\n
defp deps do\n [{:phoenix, \"~> 1.1.4\"},\n {:postgrex, \">= 0.0.0\"},\n {:phoenix_ecto, \"~> 2.0\"},\n {:phoenix_html, \"~> 2.4\"},\n {:phoenix_live_reload, \"~> 1.0\", only: :dev},\n {:cowboy, \"~> 1.0\"},\n {:plug, path: \"deps\/plug\", override: true}]\n end\n<\/code><\/pre>\n
Conclusion<\/h2>\n
deps\/<\/code> has already proved useful when searching for code and documentation.<\/p>\n
\n
\n<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"