Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make sure tasks are loaded #27

Merged
merged 2 commits into from
Sep 30, 2024
Merged

Make sure tasks are loaded #27

merged 2 commits into from
Sep 30, 2024

Conversation

svrdlans
Copy link
Contributor

running mix harness when asdf_elixir_version for a harness_process_manager has been set to 1.15.8-otp-25 results in the following error:

❯ mix harness
==> nimble_options
Compiling 3 files (.ex)
Generated nimble_options app
==> harness_process_manager
Compiling 1 file (.ex)
Generated harness_process_manager app
==> harness
Compiling 2 files (.ex)
error: module Projection is not loaded and could not be found. This may be happening because the module you are trying to load directly or indirectly depends on the current module
  lib/evolver.ex:4: Evolver (module)


== Compilation error in file lib/evolver.ex ==
** (CompileError) lib/evolver.ex: cannot compile module Evolver (errors have been logged)
    (elixir 1.15.8) expanding macro: Kernel.use/2
    lib/evolver.ex:4: Evolver (module)

further tinkering revealed that not all harness tasks are available when running "harness.compile" inside Mix.Tasks.Harness.run/1
in mix codebase the private fetch/1 function doesn't find the appropriate task modules for Harness.Compile and Harness.Check, maybe some others also:
https://github.com/elixir-lang/elixir/blob/4e6d67c169d75476677a768f5cff553a3c8f288b/lib/mix/lib/mix/task.ex#L316

but if we load tasks from the archive install location, then all task modules are available, and mix harness runs without issues


the proposed solution might not be the only one, but seems the simplest to me, and I'm open for any suggestions

@svrdlans svrdlans requested a review from a team September 25, 2024 21:48
Copy link
Member

@tonyvanriet tonyvanriet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks nice and clean to me.
good fix

@svrdlans
Copy link
Contributor Author

svrdlans commented Sep 26, 2024

further testing reveals that even with this change, we will still need to modify our harness libraries, more precisely the mix.exs template
I've found that both of these things work:

  def application do
    [
      mod: {<%= @app |> pascal() %>.Application, []},
      extra_applications: [:logger, :runtime_tools, :sasl],
      included_applications: [:harness]
    ]
  end

or

  defp aliases do
    Code.ensure_compiled(Harness)
    Code.ensure_compiled(Harness.Manifest)
    Code.ensure_compiled(Mix.Tasks.Harness.Check)

    [
      "ecto.setup": ["ecto.create", "ecto.migrate"],
      "ecto.reset": ["ecto.drop", "ecto.setup"],
      compile: ["harness.check", "compile"],
      test: ["ecto.reset --quiet", "ecto.migrate", "test"]
    ]
  end

without one of those "harness.check" task is not available:

❯ mix bless
==> event_listener
Generated event_listener app
Running compile with args ["--warnings-as-errors", "--force"]
==> extrack_translation_pm
Generated extrack_translation_pm app
** (Mix) The task "harness.check" could not be found. Did you mean "archive.check"?

there might be a nicer way to this, but I wasn't able to find it

@tonyvanriet
Copy link
Member

I don't have a strong intuition on which is better based on how they work internally or what's more idiomatic for Elixir. so all I'm left with is a preference for the ensure_compiled inside aliases since it at least puts the solution near the thing that depends on it in the code.

@svrdlans
Copy link
Contributor Author

svrdlans commented Sep 27, 2024

yeah, same, although I'd wrap those in a function and just have it like that:

  defp aliases do
    ensure_harness_check_is_available()

    [
      "ecto.setup": ["ecto.create", "ecto.migrate"],
      "ecto.reset": ["ecto.drop", "ecto.setup"],
      compile: ["harness.check", "compile"],
      test: ["ecto.reset --quiet", "ecto.migrate", "test"]
    ]
  end

  defp ensure_harness_check_is_available do
    [Harness, Harness.Manifest, Mix.Tasks.Harness.Check]
    |> Enum.each(&Code.ensure_compiled/1)
  end

@svrdlans svrdlans merged commit 07e9810 into main Sep 30, 2024
2 checks passed
@svrdlans svrdlans deleted the make-sure-tasks-are-loaded branch September 30, 2024 18:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants