elixir-ls icon indicating copy to clipboard operation
elixir-ls copied to clipboard

"File not included in .formatter.exs" even though it is

Open xxdavid opened this issue 1 year ago • 2 comments

Environment

  • Elixir & Erlang versions (elixir --version): Elixir 1.15.7 (compiled with Erlang/OTP 26)
  • Elixir Language Server version: v0.21.3
  • Operating system: macOS
  • Editor or IDE name (e.g. Emacs/VSCode): VS Code
  • Editor Plugin/LSP Client name and version: ElixirLS: Elixir support and debugger

Current behavior

Frequently, when saving a file (with format on save turned on), Elixir LS presents a message saying that

File some_path/some_file.ex not included in path_to_app/.formatter.exs

It does not happen every time, only sometimes. I found out that it's usually related to whether the Elixir LS is currently compiling the project or not. Usually, first save triggers the formatting without any problem. But it also starts the compilation and if I then save the file again, while the project is compiling, then this message pops up. If I then wait until Elixir LS prints the Compile took x milliseconds message, the formatting again works (once, i.e., until it starts compiling again).

It happens on an umbrella project where we have a common formatter.exs rules for all apps but one and we list the apps dynamically:

apps_with_common_rules =
  "{#{"apps/*" |> Path.wildcard() |> Enum.map(&Path.basename/1) |> List.delete("some_app") |> Enum.join(",")}}"

[
  inputs: [
    ".formatter.exs",
    "mix*.exs",
    "{config,rel}/**/*.exs",
    "apps/#{apps_with_common_rules}/mix*.exs",
    "apps/#{apps_with_common_rules}/lib/**/*.ex",
    "apps/#{apps_with_common_rules}/{config,test}/**/*.exs"
  ],
  subdirectories: ["apps/some_app"],
]

My guess is that when the project is compiling, Elixir LS uses a wrong CWD when evaluating the .formatter.exs, or something like that.

Expected behavior

I expect the formatting to work every time.

xxdavid avatar Jun 05 '24 08:06 xxdavid

Can you create a small repro project?

lukaszsamson avatar Jun 05 '24 09:06 lukaszsamson

Sure, here it is: https://github.com/xxdavid/elixir_ls_formatter_bug_reproducer

xxdavid avatar Jun 05 '24 12:06 xxdavid

@xxdavid The bug is in your .formatter.exs. Elixir compiler will change CWD during compilation and your code that may be called during it must be aware of the fact. ElixirLS always calls format formatter_for_file with root option being project dir so ordinary relative paths like lib/ work in includes. Your file defines paths from CWD relative wildcard

apps_with_common_rules =
  "{#{"apps/*" |> Path.wildcard() |> Enum.map(&Path.basename/1) |> List.delete("app_three") |> Enum.join(",")}}"

If i change it to using file relative path the bug goes away

apps_with_common_rules =
  "{#{"#{__DIR__}/apps/*" |> Path.wildcard() |> Enum.map(&Path.basename/1) |> List.delete("app_three") |> Enum.join(",")}}"

lukaszsamson avatar Jul 09 '24 05:07 lukaszsamson

Ok, thanks for clarification! :)

xxdavid avatar Jul 09 '24 08:07 xxdavid