Summary
The tier-2 scaffold's generated lib/<name>.ex has a @moduledoc """ … """ whose example nests a ~MOB""" … """ heredoc. The inner """ terminates the moduledoc early, so the prose after it is parsed as code and compilation fails. A freshly scaffolded tier-2 plugin does not compile.
Repro
mix mob.new_plugin my_widget --tier 2
cd my_widget && mix compile
** (SyntaxError) unexpected token: "`" (column 16)
15 │ The matching `MyWidget.View` (`use Mob.Component`) owns Elixir-side state.
│ ^
Root cause
lib/mob_dev/plugin/scaffold.ex → tier2_lib/2. The moduledoc heredoc contains:
~MOB"""
<Column>
{MyWidget.widget(id: :w)}
</Column>
"""
inside the outer @moduledoc """ … """, so the inner closing """ closes the moduledoc; everything after it (the "The matching ... use Mob.Component" prose) is parsed as code.
This contradicts the Scaffold moduledoc's own claim that "a freshly scaffolded plugin compiles + activates" — tier 2 does not.
Suggested fix
In tier2_lib/2, use @moduledoc ~S"""…""" and don't nest a """ heredoc — describe the usage inline (e.g. "embed {MyWidget.widget(id: :w)} in a ~MOB sigil") rather than pasting a full triple-quoted sigil block. Add a generate-then-mix compile test for each tier (the "generate the project, lint/compile the output" pattern used in mob_new) so a non-compiling template can't ship.
Provenance
Found by mob_ci (device CI), which dogfoods mix mob.new_plugin --tier 0..4 to generate its sample plugins; the tier-2 fixture's moduledoc had to be de-nested to compile.
Summary
The tier-2 scaffold's generated
lib/<name>.exhas a@moduledoc """ … """whose example nests a~MOB""" … """heredoc. The inner"""terminates the moduledoc early, so the prose after it is parsed as code and compilation fails. A freshly scaffolded tier-2 plugin does not compile.Repro
Root cause
lib/mob_dev/plugin/scaffold.ex→tier2_lib/2. The moduledoc heredoc contains:inside the outer
@moduledoc """ … """, so the inner closing"""closes the moduledoc; everything after it (the "The matching ...use Mob.Component" prose) is parsed as code.This contradicts the
Scaffoldmoduledoc's own claim that "a freshly scaffolded plugin compiles + activates" — tier 2 does not.Suggested fix
In
tier2_lib/2, use@moduledoc ~S"""…"""and don't nest a"""heredoc — describe the usage inline (e.g. "embed{MyWidget.widget(id: :w)}in a~MOBsigil") rather than pasting a full triple-quoted sigil block. Add a generate-then-mix compiletest for each tier (the "generate the project, lint/compile the output" pattern used in mob_new) so a non-compiling template can't ship.Provenance
Found by mob_ci (device CI), which dogfoods
mix mob.new_plugin --tier 0..4to generate its sample plugins; the tier-2 fixture's moduledoc had to be de-nested to compile.