0

I'm currently trying to write a mix task that automates the scaffolding of an Elm app in a phoenix (v1.3) project. It's generating all the elm files / js script to add, installing node and elm modules correctly. I'm also generating an elm_view.ex and elm_controller.ex that takes the name of the current otp_app, and it outputs the files correctly like below:

defmodule PipeDream.Web.ElmController do
  use PipeDream.Web, :controller

  def index(conn, _params) do
    render conn, "index.html"
  end
end

However, when I start the server with mix phx.server I get an error: "module PipeDream.Web.ElmController is not available". I've found that when I go to these files and save them the module gets picked up correctly (similar error with the elm_view.ex).

Could this be something to do with how I'm rendering the controller and view templates? The templates look like this:

defmodule <%= @app_name %>.Web.ElmController do
  use <%= @app_name %>.Web, :controller

  def index(conn, _params) do
    render conn, "index.html"
  end
end

and I'm using EEx.eval_string(template_string, assigns: [app_name: app]) to add the app module name and then writing the file with Mix.Generator.create_file

Would be super grateful for any help or suggestions!

  • So the files are created on the disk, but `mix phx.server` only picks it up after you manually open the file in an editor and save them (without making any changes)? – Dogbert May 17 '17 at 11:33
  • yep that's right – Andrew MacMurray May 17 '17 at 11:37
  • Can you post the source of the Mix task (where you call `create_file` etc)? – Dogbert May 17 '17 at 11:58
  • sure, this is the mix task file: https://github.com/TechforgoodCAST/pipe-dream/blob/master/lib/mix/tasks/phx.gen.elm.ex – Andrew MacMurray May 17 '17 at 12:01
  • 1
    I believe there could be an issue with file creation time. Just out of curiosity, would you [`File.touch/2`](https://hexdocs.pm/elixir/File.html#touch/2) the newly created file with _localtime_ given as the second parameter? Also, I suggest you to use [`Mix.Generator.embed_template/2`](https://hexdocs.pm/mix/Mix.Generator.html#embed_template/2) to compile and embed template. – Aleksei Matiushkin May 17 '17 at 13:24
  • @mudasobwa the `File.touch/2` worked a charm, thanks! But will try with `Mix.Generator.embed_template/2` also, I didn't quite understand how to use it at first but will have another go. – Andrew MacMurray May 17 '17 at 14:03
  • @mudasobwa I had a go with the `embed_template` and it was still the same problem unfortunately – Andrew MacMurray May 17 '17 at 16:10
  • @AndrewMacMurray I never said it would fix the file creation time issue, it’s just more natural to use the `Mix.Generator`’s functions in, well, generator for mix :) – Aleksei Matiushkin May 17 '17 at 16:26
  • I've never seen this issue with any of the generators I've written. However, I've seen strange mix behaviour in the past. The first thing I usually do when I'm developing packages is `rm -rf deps && rm -rf _build && mix do deps.get, deps.compile, compile`. I know its a bit of a sledgehammer approach, but its resolved problems for me in the past. – Steve Pallen May 17 '17 at 16:48

1 Answers1

1

Since there are many comments above, I decided to post a [hacky but yet working] solution as an answer for the future visitors.

There is some kind of file creation time issue when Elixir/Mix try to cache/check the dependencies. While the sledgehammer solution proposed by Steve Pallen (rm -rf deps && rm -rf _build && mix do deps.get, deps.compile, compile) should work always, there might be a more handy hack: call File.touch/2 on newly generated files to enforce Mix to recompile them.

Also, as a sidenote, I would suggest to use Mix.Generator.embed_template/2 to compile and embed template, rather than generic EEx.eval_string to clarity the intent.

Aleksei Matiushkin
  • 119,336
  • 10
  • 100
  • 160