Skip to content

Store component call file relative to cwd - #4489

Merged
SteffenDE merged 4 commits into
phoenixframework:mainfrom
onnimonni:relative-component-call-file
Nov 2, 2026
Merged

SteffenDE merged 4 commits into
phoenixframework:mainfrom
onnimonni:relative-component-call-file

Conversation

@onnimonni

@onnimonni onnimonni commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

Component call warnings (missing or unknown attrs and slots) are emitted from the caller's @after_verify, using the file stored in __components_calls__ at compile time. When a copy of the project reuses _build (git worktree or copy-on-write clone, compiled with check_cwd: false), these warnings point at the original checkout's absolute paths. Editors and coding agents then open and edit the wrong files.

Fix: store Path.relative_to_cwd(state.file). Elixir resolves relative diagnostic paths against the current directory when it prints them. html_engine.ex already does the same for annotations.

Verified: I made a required attr change in a relocated copy of a Phoenix app. Before the fix the warnings were └─ /original/checkout/lib/...; after it they are └─ lib/.... Full suite: 1561/1563. The 2 failures are the LiveReload tests that need a running file watcher backend; they also fail on main locally.

No new test, because it needs a change of cwd between compiling and verifying. Happy to add one if you prefer.

Context: phoenixframework/phoenix#6855

Second commit: the {module, function, file, line} caller tuple passed to Phoenix.LiveView.TagEngine.component/3 embedded __ENV__.file, an absolute path. It is injected into stack traces when a component raises, so it is now stored relative to the project like the rest of Elixir's stack trace entries. Together the two commits remove every absolute path the HEEx compiler puts into the compiled LiveViews of a generated Phoenix app (checked with a scan of the .beam literals).

Third commit: collocated templates (foo_live.html.heex) are declared with @external_resource, which is persisted with the absolute path. They are now stored relative to the project, which Mix and Elixir's docs already support. There is a new test in collocated_test.exs. Full suite: 1562/1564; the same 2 LiveReload tests fail on main locally.

Component call warnings are emitted from @after_verify of the caller,
using the file stored at compile time. With an absolute path, a copy of the
project reusing the build (git worktree, copy-on-write clone, compiled with
check_cwd: false) reported warnings in the original checkout's files.
onnimonni and others added 3 commits October 31, 2026 14:53
The caller tuple given to Phoenix.LiveView.TagEngine.component/3 is injected
into stacktraces when a component raises. Elixir's own stacktrace entries are
relative to the project, and an absolute path pointed copies of the project
that reuse the build (git worktrees, copy-on-write clones) to the original
checkout's files.
@external_resource is persisted in the module's attributes and Mix already
resolves relative paths against the project directory.
Mix persists compiler warnings by their absolute source path. Elixir
makes the file of a warning emitted from @after_verify absolute again
when collecting it, but not its source. A warning with a relative file
was therefore printed once and never stored in the manifest: later
compilations did not print it again with --all-warnings, and a no-op
compilation passed --warnings-as-errors.

Keep storing the file relative to the project, so that copies of the
project reusing the build report their own files, and expand it against
the current directory when the warning is emitted.
@SteffenDE
SteffenDE merged commit cff4e32 into phoenixframework:main Nov 2, 2026
9 checks passed
@SteffenDE

Copy link
Copy Markdown
Member

Thank you! 🙌🏻

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