phoenixframework / phoenix

Peace of mind from prototype to production
https://www.phoenixframework.org
MIT License
21.45k stars 2.88k forks source link

Module loading error during mix phx.gen.auth #5973

Closed evnp closed 1 week ago

evnp commented 1 week ago

Environment

Elixir 1.17.2 (compiled with Erlang/OTP 26)

* Phoenix version (mix deps):

$ mix deps | grep phoenix

Actual behavior

My application name is CC (a shorthand name). However, when running mix phx.gen.auth I encounter an error:

$ mix phx.gen.auth Accounts User users
An authentication system can be created in two different ways:
- Using Phoenix.LiveView (default)
- Using Phoenix.Controller only
Do you want to create a LiveView based authentication system? [Yn]
Compiling 19 files (.ex)
Generated cc app
** (Mix) Unable to find Cc.Repo

21:02:15.856 [error] beam/beam_load.c(180): Error loading module 'Elixir.Cc.Repo':
  module name in object code is 'Elixir.CC.Repo'

Is specific capitalization critical here? I'd expect any PascalCase string would be valid as the app module name (CC being a PascalCase string of two one-letter terms).

Expected behavior

$ mix phx.gen.auth Accounts User users
An authentication system can be created in two different ways:
- Using Phoenix.LiveView (default)
- Using Phoenix.Controller only
Do you want to create a LiveView based authentication system? [Yn]
Compiling 19 files (.ex)
Generated cc app
* creating priv/repo/migrations/20241110210027_create_users_auth_tables.exs
* creating lib/cc/accounts/user_notifier.ex
...
* injecting lib/cc_web/router.ex - plug
* injecting lib/cc_web/components/layouts/root.html.heex

Please re-fetch your dependencies with the following command:

    $ mix deps.get

Remember to update your repository by running migrations:

    $ mix ecto.migrate

Once you are ready, visit "/users/register"
to create your account and then access "/dev/mailbox" to
see the account confirmation email.
03juan commented 1 week ago

In short:

The mix task is working as expected. Your app name :cc is being converted to Cc instead of CC, so if you renamed your repo or the actual app name is something else, you'll have to rename either according to the way that Macro works

Is specific capitalization critical here? I'd expect any PascalCase string would be valid as the app module name (CC being a PascalCase string of two one-letter terms).

Yes it's critical, but there are some idiosyncrasies of the Elixir Macro functions, used by the phx.gen.* code to create modules, that can lead to confusion as hinted at in the Macro.camelize/1 and Macro.underscore/1 docs:

This function was designed to camelize language identifiers/tokens, that's why it belongs to the Macro module. Do not use it as a general mechanism for camelizing strings

In general, underscore can be thought of as the reverse of camelize, however, in some cases formatting may be lost:

Macro.underscore("SAPExample")
"sap_example"

Macro.camelize("sap_example")
"SapExample"

For example:

iex(1)> Macro.camelize("c_c") |> Macro.underscore() |> Macro.camelize() |> Macro.underscore() |> dbg()

Macro.camelize("c_c") #=> "CC"
|> Macro.underscore() #=> "cc"
|> Macro.camelize() #=> "Cc"
|> Macro.underscore() #=> "cc"

"cc"

So if your application is named :cc, this function will try to load the repo module Cc.Repo, as seen in your error

https://github.com/phoenixframework/phoenix/blob/dad45278246207b26aa0c42c02398106c10e2b19/lib/mix/tasks/phx.gen.auth.ex#L770-L776

Generated cc app ** (Mix) Unable to find Cc.Repo

21:02:15.856 [error] beam/beam_load.c(180): Error loading module 'Elixir.Cc.Repo': module name in object code is 'Elixir.CC.Repo'

evnp commented 1 week ago

Hi Juan, appreciate the detailed response. That makes sense – I see now that changing project config to either app: :CC or app: :c_c, both allow the command to proceed as expected (though :c_c requires some file name changes, which is to be expected).

I had worked around the issue by doing a temporary search/replace of CC -> Cc across all files, then reverting that back after auth gen, which seems to have worked fine. But it sounds like I should probably app-wide rename to Cc to avoid other issues that stem from going against the grain here.

Will close this as it's working as expected. Thanks again for your help clarifying.