Escript with EEx or release with cli arguments

I’m building a CLI application to automate different reporting things.

Now others found about this software and also want to use it, so using iex -S mix and calling the functions directly is no longer an option :smiley:

I tried using escript (which looks like what I want), but it complains, that the module EEx is not found.

Also I wondered if I can somehow use mix release because I don’t want to force anyone to install the erlang runtime (since that sounds like a support nightmare): So is there a way to configure a release in a way that it produces a “command line application” that is not started, but instead accepts arguments, does it’s thing and then terminates?

1 Like

I am in a similar situation and have been thinking about this, your post got me to actually get off my butt and try it. Make a blank project. I called mine “test” then I changed Test.hello/1 to IO.puts :world instead of return :world Then mix release, and do _build/dev/rel/test/bin/test eval "Testy.hello" And it does exactly what you expect!

If you’re on linux and you really wanted to be sophisticated about delivery you could put it into a podman container or something and roll it into a single binary, but if you don’t need to roll up a single container (or don’t have the luxury of being in linux) it should be pretty easy to roll up a shell script that will do roll up parameters into the right thing using a release.

Don’t forget to add EEx to your list of :extra_applications in Mix.exs if it needs to be there at runtime. Though I feel like it’s generally better to make it so all of your EEx code runs at compile time, if that’s possible for what you’re doing.

1 Like

Thank you so much for your answer! I’m terribly sorry that it took me so long to write this.

The solution for my first problem was to add EEx to my :extra_applications. Possibly I could use EEx at compile time, I simply have no clue how in this case. I’ll try that :smiley:

Running the application with eval is an interesting approach, even though it does not allow for passing arguments on the command line, correct?

1 Like

Some of the EEx functions are intended to be run at compile time (for example function_from_file/5). To use this, call EEx.function_from_file(…) inside of defmodule, but outside of a def.

I haven’t tried this, but knowing how Elixir cares about consistency, I’d bet that eval will respect System.argv/0,1. I would be very surprised if it didn’t.

1 Like

I just tried it and (at least by default) it will not pass anything to the evaluated function… You can probably work around that by just using env vars, but I think the escript fix is fine for me now :slight_smile: