PJUllrich

PJUllrich

Author of Building Table Views with Phoenix LiveView

In my mix.exs I used to be able to call other Modules in order to fetch some configurations for my application-env configuration. Somehow this is not possible anymore since a few weeks (or the update to Elixir 1.11 maybe)

Here is an example of calling a module MyApp.Config.application_env() from inside my mix.exs file:

./mix.exs

defmodule MyApp.MixProject do
   use Mix.Project

     def project do
    [
      app: :my_app
      version: "0.2.0",
      elixir: "~> 1.5",
      elixirc_paths: elixirc_paths(Mix.env()),
      compilers: [:phoenix, :gettext] ++ Mix.compilers(),
      start_permanent: Mix.env() == :prod,
      aliases: aliases(),
      deps: deps(),
      test_paths: ["test", "lib"]
    ]
  end

  def application do
    [
      mod: {MyApp.Application, []},
      extra_applications: [:logger, :runtime_tools],
      env: MyApp.Config.application_env()
    ]
  end

  # Specifies which paths to compile per environment.
  defp elixirc_paths(:test), do: ["lib", "test/support"]
  defp elixirc_paths(_), do: ["lib"]

  # deps and aliases ....

./lib/config.ex

defmodule MyApp.Config do
  def application_env do
    [my_config: "foo", another_config: "bar"]
  end
end

Since the update to Elixir 1.11 I cannot call this module anymore since the compiler complains like this:

** (UndefinedFunctionError) function MyApp.Config.application_env/0 is undefined (module MyApp.Config is not available)
    MyApp.Config.application_env()
    mix.exs:28: MyApp.MixProject.application/0
    (mix 1.11.0) lib/mix/tasks/compile.app.ex:382: Mix.Tasks.Compile.App.project_apps/1
    (mix 1.11.0) lib/mix/tasks/compile.all.ex:97: Mix.Tasks.Compile.All.load_apps/2
    (mix 1.11.0) lib/mix/tasks/compile.all.ex:24: Mix.Tasks.Compile.All.run/1
    (mix 1.11.0) lib/mix/task.ex:394: Mix.Task.run_task/3
    (mix 1.11.0) lib/mix/tasks/compile.ex:119: Mix.Tasks.Compile.run/1
    (mix 1.11.0) lib/mix/task.ex:394: Mix.Task.run_task/3

I tried require-ing and import-ing the MyApp.Config module, but nothing helped. The config.ex file is compiled and put into the _build/dev/ebin folder, but somehow it is not available during compile-time. I also tried to set it to an module attribute like this: @config MyApp.Config, but even this didn’t help.

I have the feeling that it is related to the latest Compilation time improvements in 1.11 which states:

This change allows us to mark import s and require s as “exports dependencies” instead of “compile time” dependencies

Does somebody know how to make my MyApp.Config module available at compile-time again?

Showing Posts 1 to 8

NobbZ

NobbZ

When mix.exs is evaluated your application is not available, as your application is built using the evaluation result of the mix.exs.

So by requiring your applications code within mix.exs you are creating a circular dependency that your application needs to be compiled in order to get compiled.

PJUllrich

PJUllrich OP

Author of Building Table Views with Phoenix LiveView

Hmm, that makes sense, but now I’m wondering why it worked before :thinking:

PJUllrich

PJUllrich OP

Author of Building Table Views with Phoenix LiveView

On another node: How can I then extract logic to set the application env option to another module/script/config file? I need to set default values for many application environment variables and don’t want to do this in every application which uses this library. So, I cannot use the config/... files since these are overwritten by the implementing applications, I believe. The advice in this thread was to use the application env option in mix.exs, which is why I use above setup. But I also don’t want to have 30 defp functions in my mix.exs and therefore extracting them to another module. Do you know a better/different way of setting a multitude of default values in a library maybe?

NobbZ

NobbZ

Try to refactor your library to not need to rely on those defaults…

If you insist on providing them, you could have a an extra file in the project root defining them and load it via Code.eval_file/2.

PJUllrich

PJUllrich OP

Author of Building Table Views with Phoenix LiveView

Thanks for the hint!

I used Code.compile_file/2 now in order to compile the MyApp.Config-module before setting the application env option like this:

def application do
  [{my_config, _binary}] = Code.compile_file("lib/config.ex")

  [
      mod: {MyApp.Application, []},
      extra_applications: [:logger, :httpoison, :runtime_tools, :cachex],
      env: my_config.application_env()
  ]
end
hauleth

hauleth

Out of interest - why? Why not other way around?

PJUllrich

PJUllrich OP

Author of Building Table Views with Phoenix LiveView

At work, we have ~5 Phoenix micro-services which all share some common libraries like a Neuron API-Client or a Cachex request handler. These libraries (Neuron, Cachex) need to be configured, both locally and on our servers, for the test, dev, and prod environments. We don’t want to copy&paste the same configuration to all our micro-services, which is why we bundled the libraries and their configuration in a library of our own. Since the config.exs of a library is ignored when the library is used in a project like one of our micro-services, we needed to put the shared configurations in the application env option of our own library. We have ~30 private functions which return a configuration for a “sub-library” so we didn’t want to put all these functions into our mix.exs, but in a separate Config-Module.

If you know a way to refactor this nicely, I would much appreciate to hear about it :slight_smile:

hauleth

hauleth

config.exs is ignored, but the :env in application is not. So if you have application that is using that, then you can configure it there. In general, it depends, as there is few possible solutions, depending on use case.

— All posts loaded —

Where Next? Top

Trending in Questions Top

Blokh
Hey guys, I’ve got a huge CSV ( around 10 GB ) that needs to be processed hourly Do you guys have any suggestions what is the best prac...
New
RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
kszambelanczyk
Hello! Could someone please give me a help/sample code, how to delete a file from s3 using waffle/waffle_ecto from Phoenix app. I creat...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
FlyingNoodle
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve. They are GUI (Emerge) and State management (S...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews