@@ -14,18 +14,27 @@ if Code.ensure_loaded?(Igniter) do
1414 This installer will:
1515
1616 1. Remove `:esbuild` and `:tailwind` deps
17- 2. Add Volt build config to `config/config.exs`
18- 3. Add format and lint config to `config/config.exs`
19- 4. Add `Volt.Formatter` plugin to `.formatter.exs`
20- 5. Add `Volt.DevServer` plug to your endpoint
21- 6. Add the Volt watcher to `config/dev.exs`
22-
23- You may need to manually remove old `config :esbuild` and
24- `config :tailwind` blocks from `config/config.exs`.
17+ 2. Remove `config :esbuild` and `config :tailwind` blocks
18+ 3. Update `assets.setup`, `assets.build`, and `assets.deploy` aliases
19+ 4. Add Volt build config to `config/config.exs`
20+ 5. Add format and lint config to `config/config.exs`
21+ 6. Add `Volt.Formatter` plugin to `.formatter.exs`
22+ 7. Add `Volt.DevServer` plug to your endpoint
23+ 8. Add the Volt watcher to `config/dev.exs`
2524 """
2625
2726 use Igniter.Mix.Task
2827
28+ alias Igniter.Code.Common
29+ alias Igniter.Code.Function
30+ alias Igniter.Code.Keyword , as: CodeKeyword
31+ alias Igniter.Code.List
32+ alias Igniter.Code.Tuple
33+ alias Igniter.Project.Config , as: ProjectConfig
34+ alias Igniter.Project.Deps , as: ProjectDeps
35+ alias Igniter.Project.Formatter , as: ProjectFormatter
36+ alias Igniter.Project.TaskAliases
37+
2938 @ impl Igniter.Mix.Task
3039 def info ( _argv , _composing_task ) do
3140 % Igniter.Mix.Task.Info {
@@ -37,69 +46,92 @@ if Code.ensure_loaded?(Igniter) do
3746 @ impl Igniter.Mix.Task
3847 def igniter ( igniter ) do
3948 app_name = Igniter.Project.Application . app_name ( igniter )
49+ endpoint = endpoint_module ( igniter )
4050
4151 igniter
4252 |> remove_old_deps ( )
43- |> warn_about_old_config ( )
53+ |> remove_old_config ( )
54+ |> remove_old_watchers ( app_name , endpoint )
55+ |> update_aliases ( )
4456 |> add_volt_config ( )
4557 |> add_format_config ( )
4658 |> add_lint_config ( )
4759 |> add_formatter_plugin ( )
48- |> add_dev_config ( app_name )
60+ |> add_dev_config ( app_name , endpoint )
4961 |> add_dev_server_plug ( )
5062 end
5163
5264 # ── Remove old tooling ──
5365
5466 defp remove_old_deps ( igniter ) do
5567 igniter
56- |> Igniter.Project.Deps . remove_dep ( :esbuild )
57- |> Igniter.Project.Deps . remove_dep ( :tailwind )
68+ |> ProjectDeps . remove_dep ( :esbuild )
69+ |> ProjectDeps . remove_dep ( :tailwind )
5870 end
5971
60- defp warn_about_old_config ( igniter ) do
61- has_esbuild =
62- Igniter.Project.Config . configures_root_key? ( igniter , "config.exs" , :esbuild )
63-
64- has_tailwind =
65- Igniter.Project.Config . configures_root_key? ( igniter , "config.exs" , :tailwind )
66-
67- cond do
68- has_esbuild and has_tailwind ->
69- Igniter . add_warning ( igniter , """
70- Found `config :esbuild` and `config :tailwind` in config/config.exs.
71- Please remove them manually — Volt replaces both.
72- Also remove esbuild/tailwind watchers from config/dev.exs.
73- """ )
74-
75- has_esbuild ->
76- Igniter . add_warning ( igniter , """
77- Found `config :esbuild` in config/config.exs.
78- Please remove it manually — Volt replaces esbuild.
79- Also remove the esbuild watcher from config/dev.exs.
80- """ )
81-
82- has_tailwind ->
83- Igniter . add_warning ( igniter , """
84- Found `config :tailwind` in config/config.exs.
85- Please remove it manually — Volt replaces the Tailwind CLI.
86- Also remove the tailwind watcher from config/dev.exs.
87- """ )
88-
89- true ->
90- igniter
91- end
72+ defp remove_old_config ( igniter ) do
73+ igniter
74+ |> ProjectConfig . remove_application_configuration ( "config.exs" , :esbuild )
75+ |> ProjectConfig . remove_application_configuration ( "config.exs" , :tailwind )
76+ |> ProjectConfig . remove_application_configuration ( "dev.exs" , :esbuild )
77+ |> ProjectConfig . remove_application_configuration ( "dev.exs" , :tailwind )
78+ end
79+
80+ defp remove_old_watchers ( igniter , app_name , endpoint ) do
81+ Igniter . update_elixir_file (
82+ igniter ,
83+ "config/dev.exs" ,
84+ fn zipper ->
85+ with { :ok , config_zipper } <-
86+ Common . move_to ( zipper , & endpoint_config? ( & 1 , app_name , endpoint ) ) ,
87+ { :ok , keyword_zipper } <- Function . move_to_nth_argument ( config_zipper , 2 ) ,
88+ { :ok , watchers_zipper } <- CodeKeyword . get_key ( keyword_zipper , :watchers ) ,
89+ { :ok , updated } <- List . remove_from_list ( watchers_zipper , & old_watcher? / 1 ) do
90+ { :ok , updated }
91+ else
92+ _ -> { :ok , zipper }
93+ end
94+ end ,
95+ required?: false
96+ )
97+ end
98+
99+ defp endpoint_config? ( zipper , app_name , endpoint ) do
100+ Function . function_call? ( zipper , :config , 3 ) and
101+ Function . argument_equals? ( zipper , 0 , app_name ) and
102+ Function . argument_equals? ( zipper , 1 , endpoint )
103+ end
104+
105+ defp old_watcher? ( item ) do
106+ Tuple . elem_equals? ( item , 0 , :esbuild ) or Tuple . elem_equals? ( item , 0 , :tailwind )
107+ end
108+
109+ defp update_aliases ( igniter ) do
110+ igniter
111+ |> TaskAliases . modify_existing_alias ( :"assets.setup" , & replace_with_empty / 1 )
112+ |> TaskAliases . modify_existing_alias ( :"assets.build" , & replace_with_build / 1 )
113+ |> TaskAliases . modify_existing_alias ( :"assets.deploy" , & replace_with_deploy / 1 )
114+ end
115+
116+ defp replace_with_empty ( zipper ) , do: { :ok , Common . replace_code ( zipper , [ ] ) }
117+
118+ defp replace_with_build ( zipper ) do
119+ { :ok , Common . replace_code ( zipper , [ "compile" , "volt.build --tailwind" ] ) }
120+ end
121+
122+ defp replace_with_deploy ( zipper ) do
123+ { :ok , Common . replace_code ( zipper , [ "volt.build --tailwind" , "phx.digest" ] ) }
92124 end
93125
94126 # ── Add Volt config ──
95127
96128 defp add_volt_config ( igniter ) do
97129 igniter
98- |> Igniter.Project.Config . configure ( "config.exs" , :volt , [ :entry ] , "assets/js/app.ts" )
99- |> Igniter.Project.Config . configure ( "config.exs" , :volt , [ :outdir ] , "priv/static/assets" )
100- |> Igniter.Project.Config . configure ( "config.exs" , :volt , [ :target ] , :es2020 )
101- |> Igniter.Project.Config . configure ( "config.exs" , :volt , [ :sourcemap ] , :hidden )
102- |> Igniter.Project.Config . configure (
130+ |> ProjectConfig . configure ( "config.exs" , :volt , [ :entry ] , "assets/js/app.ts" )
131+ |> ProjectConfig . configure ( "config.exs" , :volt , [ :outdir ] , "priv/static/assets" )
132+ |> ProjectConfig . configure ( "config.exs" , :volt , [ :target ] , :es2020 )
133+ |> ProjectConfig . configure ( "config.exs" , :volt , [ :sourcemap ] , :hidden )
134+ |> ProjectConfig . configure (
103135 "config.exs" ,
104136 :volt ,
105137 [ :tailwind ] ,
@@ -133,7 +165,7 @@ if Code.ensure_loaded?(Igniter) do
133165
134166 code = Enum . map_join ( format_kw , ",\n " , fn { k , v } -> "#{ k } : #{ inspect ( v ) } " end )
135167
136- Igniter.Project.Config . configure (
168+ ProjectConfig . configure (
137169 igniter ,
138170 "config.exs" ,
139171 :volt ,
@@ -143,7 +175,7 @@ if Code.ensure_loaded?(Igniter) do
143175 end
144176
145177 defp add_lint_config ( igniter ) do
146- Igniter.Project.Config . configure (
178+ ProjectConfig . configure (
147179 igniter ,
148180 "config.exs" ,
149181 :volt ,
@@ -162,29 +194,20 @@ if Code.ensure_loaded?(Igniter) do
162194 end
163195
164196 defp add_formatter_plugin ( igniter ) do
165- Igniter.Project.Formatter . add_formatter_plugin ( igniter , Volt.Formatter )
197+ ProjectFormatter . add_formatter_plugin ( igniter , Volt.Formatter )
166198 end
167199
168- defp add_dev_config ( igniter , app_name ) do
169- endpoint = endpoint_module ( igniter )
170-
171- Igniter.Project.Config . configure (
172- igniter ,
173- "dev.exs" ,
174- app_name ,
175- [ endpoint , :watchers , :volt ] ,
200+ defp add_dev_config ( igniter , app_name , endpoint ) do
201+ watcher =
176202 { :code ,
177203 Sourceror . parse_string! ( """
178204 {Mix.Tasks.Volt.Dev, :run, [~w(--tailwind)]}
179205 """ ) }
180- )
181- |> Igniter.Project.Config . configure (
182- "dev.exs" ,
183- :volt ,
184- [ :server , :prefix ] ,
185- "/assets"
186- )
187- |> Igniter.Project.Config . configure (
206+
207+ igniter
208+ |> ProjectConfig . configure ( "dev.exs" , app_name , [ endpoint , :watchers , :volt ] , watcher )
209+ |> ProjectConfig . configure ( "dev.exs" , :volt , [ :server , :prefix ] , "/assets" )
210+ |> ProjectConfig . configure (
188211 "dev.exs" ,
189212 :volt ,
190213 [ :server , :watch_dirs ] ,
@@ -218,53 +241,56 @@ if Code.ensure_loaded?(Igniter) do
218241 end
219242
220243 defp insert_dev_server_plug ( zipper , endpoint ) do
221- with :error <-
222- Igniter.Code.Common . move_to ( zipper , fn z ->
223- Igniter.Code.Function . function_call? ( z , :plug ) and
224- Igniter.Code.Function . argument_equals? ( z , 0 , Volt.DevServer )
225- end ) ,
226- { :ok , zipper } <- Igniter.Code.Common . move_to ( zipper , & code_reloading? / 1 ) do
244+ with :error <- Common . move_to ( zipper , & has_dev_server_plug? / 1 ) ,
245+ { :ok , zipper } <- Common . move_to ( zipper , & code_reloading? / 1 ) do
227246 { :ok ,
228- Igniter.Code. Common. add_code (
247+ Common . add_code (
229248 zipper ,
230249 """
231250 plug Volt.DevServer, root: "assets"
232251 """ ,
233252 placement: :after
234253 ) }
235254 else
236- { :ok , _ } ->
237- { :ok , zipper }
255+ { :ok , _ } -> { :ok , zipper }
256+ :error -> dev_server_warning ( endpoint )
257+ end
258+ end
238259
239- :error ->
240- { :warning ,
241- """
242- Could not find the code_reloading? section in `#{ inspect ( endpoint ) } `.
243- Please add the plug manually inside `if code_reloading? do`:
260+ defp has_dev_server_plug? ( zipper ) do
261+ Function . function_call? ( zipper , :plug ) and
262+ Function . argument_equals? ( zipper , 0 , Volt.DevServer )
263+ end
244264
245- plug Volt.DevServer, root: "assets"
246- """ }
247- end
265+ defp dev_server_warning ( endpoint ) do
266+ { :warning ,
267+ """
268+ Could not find the code_reloading? section in `#{ inspect ( endpoint ) } `.
269+ Please add the plug manually inside `if code_reloading? do`:
270+
271+ plug Volt.DevServer, root: "assets"
272+ """ }
248273 end
249274
250275 # ── Helpers ──
251276
252277 defp code_reloading? ( zipper ) do
253- Igniter.Code. Function. function_call? ( zipper , :if , 2 ) &&
254- Igniter.Code. Function. argument_matches_predicate? (
278+ Function . function_call? ( zipper , :if , 2 ) &&
279+ Function . argument_matches_predicate? (
255280 zipper ,
256281 0 ,
257- & Igniter.Code. Common. variable? ( & 1 , :code_reloading? )
282+ & Common . variable? ( & 1 , :code_reloading? )
258283 )
259284 end
260285
261286 defp endpoint_module ( igniter ) do
262- app_name = Igniter.Project.Application . app_name ( igniter )
287+ app_name =
288+ igniter
289+ |> Igniter.Project.Application . app_name ( )
290+ |> to_string ( )
291+ |> Macro . camelize ( )
263292
264- app_name
265- |> to_string ( )
266- |> Macro . camelize ( )
267- |> then ( & Module . concat ( [ String . to_atom ( "#{ & 1 } Web" ) , Endpoint ] ) )
293+ Module . concat ( [ String . to_atom ( "#{ app_name } Web" ) , Endpoint ] )
268294 end
269295 end
270296else
0 commit comments