ash-project / spark

Tooling for building DSLs in Elixir
MIT License
127 stars 25 forks source link

Spark generates very long module names causing compile errors on some systems #103

Open jimsynz opened 3 months ago

jimsynz commented 3 months ago

Describe the bug Deeply nested DSLs create module names such as Elixir.Wayfarer.Dsl.Wayfarer.Config.Wayfarer.Targets.Targets.Wayfarer.Targets.Targets.Http.Wayfarer.Targets.Targets.HealthChecks.HealthChecks which will trigger enametoolong on some systems:

08:20:24.969 [error] Process #PID<0.153.0> raised an exception
** (File.Error) could not write to file "/home/james/Dev/harton.dev/james/wayfarer/_build/dev/lib/wayfarer/ebin/Elixir.Wayfarer.Dsl.Wayfarer.Config.Wayfarer.Targets.Targets.Wayfarer.Targets.Targets.Http.Wayfarer.Targets.Targets.HealthChecks.HealthChecks.beam": file name too long
    (elixir 1.17.1) lib/file.ex:1144: File.write!/3
    (elixir 1.17.1) lib/kernel/parallel_compiler.ex:334: anonymous fn/3 in Kernel.ParallelCompiler.write_module_binaries/3
    (elixir 1.17.1) lib/enum.ex:1268: anonymous fn/3 in Enum.flat_map/2
    (stdlib 6.0) maps.erl:860: :maps.fold_1/4
    (elixir 1.17.1) lib/enum.ex:2543: Enum.flat_map/2
    (elixir 1.17.1) lib/kernel/parallel_compiler.ex:261: Kernel.ParallelCompiler.spawn_workers/3
    (mix 1.17.1) lib/mix/compilers/elixir.ex:1018: anonymous fn/9 in Mix.Compilers.Elixir.compiler_loop/6

To be clear this an issue with BEAM and not Spark or Elixir and in response to a similar bug report against Elixir José's response boils down to "just use shorter module names". I think he's right. There are a couple of strategies I can think of;

  1. Move generated modules out of the Elixir. namespace (I suggest Spark.).
  2. Name modules by using a hash of their DSL path. I'd suggest :erlang.phash2 since it should always be available. It doesn't really matter if the modules are "discoverable" as they're only ever imported by Spark anyway. We can always add a flag to disable this behaviour while debugging.

To Reproduce I triggered it by using eCryptfs on a portable Linux device because the effective file length limit is ~140 bytes. It is possible to reproduce on Linux & macOS (255 byte limit) by creating a DSL with very long entity names.

Expected behavior The DSL extension should cleanly compile.

Runtime

Additional context Add any other context about the problem here.

zachdaniel commented 3 months ago

Open to any of these. The generated modules are hidden and any public use of them is incorrect. So honestly I'm down for "anything that works" 😅

zachdaniel commented 3 months ago

@jimsynz if you've got some time to tackle this that would be great, got a lot on ye olde plate at the moment.

jimsynz commented 3 months ago

Yeah, I've added it to my list :)