`mix format` has different results on MacOS (Elixir1.18.4) and Ubuntu 24.04 (Elixir 1.16 and 1.17)

We’re maintaining a Phoenix server written by some devs who are no longer with the project. We have some CI machinery that checks the source code format with

mix format --check-formatted '{lib,priv,test,config}/**/*.{ex,exs}'

To get the code to pass this, I’m running

mix format

on my dev machine and committing the result.

Unfortunately, while mix format on my dev machine MacOS (Elixir1.18.4) is fine with a particular file, mix format --check-formatted running under Ubuntu 24.04 (Elixir 1.16 and 1.17) complains:

The following files are not formatted:

/home/runner/work/reticulum/reticulum/lib/ret/storage_used.ex

       |
30 30  |
31 31  |          {:ok, [_FS, _kb, used, _Avail], _RestStr} =
32    -|            :io_lib.fread('~s~d~d~d', line |> to_charlist)
   32 +|            :io_lib.fread(~c"~s~d~d~d", line |> to_charlist)
33 33  |
34 34  |          {:ok, [{:storage_used, used}]}
       |

If I change that line as mix format appears to want, mix format on my dev machine is cool with it and it passes the automated tests.

However, I’m reluctant to change code that has been working fine for years without understanding what’s going on.

Well, all sigils have docs. Here’s the one that is shown here: Kernel — Elixir v1.18.4

TL;DR the Elixir team wants to discourage using single quotes and use the ~c sigil instead. So.

- 'something`    # BEFORE
+ ~c"something"  # AFTER

It appears that the format is supposed to be a string, rather than a charlist (io — stdlib v7.0.1), so I changed the single quotes to double.

Not 100% true. If you visit the prompt() type in the same docs you’ll see it can either be an atom or Unicode character data, and the latter can be either a charlist (those denoted with 'abc' or ~c"abc") or a normal binary (i.e. a String).

So yeah, just straight up changing it to be a string should work.

As for your original question, it’s quite safe to just migrate to ~c where you had the old syntax of charlists before.

2 Likes