Skip to content

Commit 04bae76

Browse files
committed
improvement: add delay_task to run tasks at the end
1 parent c3f2011 commit 04bae76

4 files changed

Lines changed: 115 additions & 7 deletions

File tree

lib/igniter.ex

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@ defmodule Igniter do
4646
@type t :: %__MODULE__{
4747
rewrite: Rewrite.t(),
4848
issues: [String.t()],
49-
tasks: [String.t() | {String.t(), list(String.t())}],
49+
tasks: [
50+
String.t() | {String.t(), list(String.t())} | {String.t(), list(String.t()), :delayed}
51+
],
5052
warnings: [String.t()],
5153
notices: [String.t()],
5254
assigns: map(),
@@ -388,6 +390,11 @@ defmodule Igniter do
388390
%{igniter | tasks: igniter.tasks ++ [{task, argv}]}
389391
end
390392

393+
@doc "Adds a delayed task to the tasks list. Delayed tasks will be run after all other composed tasks have been added."
394+
def delay_task(igniter, task, argv \\ []) when is_binary(task) do
395+
%{igniter | tasks: igniter.tasks ++ [{task, argv, :delayed}]}
396+
end
397+
391398
@doc """
392399
Finds the `Igniter.Mix.Task` task by name and composes it with `igniter`.
393400
@@ -1208,6 +1215,7 @@ defmodule Igniter do
12081215
end)
12091216

12101217
igniter.tasks
1218+
|> sort_tasks_with_delayed_last()
12111219
|> Enum.each(fn {task, args} ->
12121220
Mix.shell().cmd("mix #{task} #{Enum.join(args, " ")}")
12131221
end)
@@ -1962,6 +1970,7 @@ defmodule Igniter do
19621970
end
19631971

19641972
igniter.tasks
1973+
|> sort_tasks_with_delayed_last()
19651974
|> Enum.map(fn {task, args} ->
19661975
["* ", :red, task, " ", :yellow, Enum.intersperse(args, " ")]
19671976
end)
@@ -2085,4 +2094,16 @@ defmodule Igniter do
20852094
defp win32_split_absolute?(["//" | _]), do: true
20862095
defp win32_split_absolute?([<<_, ":/">> | _]), do: true
20872096
defp win32_split_absolute?(_), do: false
2097+
2098+
@doc false
2099+
def sort_tasks_with_delayed_last(tasks) do
2100+
tasks
2101+
|> Enum.split_with(fn
2102+
{_task, _args, :delayed} -> false
2103+
_ -> true
2104+
end)
2105+
|> then(fn {regular_tasks, delayed_tasks} ->
2106+
regular_tasks ++ Enum.map(delayed_tasks, fn {task, args, :delayed} -> {task, args} end)
2107+
end)
2108+
end
20882109
end

lib/igniter/test.ex

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,14 @@ defmodule Igniter.Test do
227227
end
228228

229229
def assert_has_task(igniter, task, argv) do
230-
if {task, argv} not in igniter.tasks do
230+
task_found? =
231+
Enum.any?(igniter.tasks, fn
232+
{^task, ^argv} -> true
233+
{^task, ^argv, :delayed} -> true
234+
_ -> false
235+
end)
236+
237+
if not task_found? do
231238
if Enum.empty?(igniter.tasks) do
232239
flunk("""
233240
Expected to find `mix #{task} #{Enum.join(argv, " ")}` in igniter tasks,
@@ -239,7 +246,34 @@ defmodule Igniter.Test do
239246
240247
Found tasks:
241248
242-
#{Enum.map_join(igniter.tasks, "\n", fn {task, argv} -> "- mix #{task} #{Enum.join(argv)}" end)}
249+
#{Enum.map_join(igniter.tasks, "\n", fn
250+
{task, argv} -> "- mix #{task} #{Enum.join(argv, " ")}"
251+
{task, argv, :delayed} -> "- mix #{task} #{Enum.join(argv, " ")} (delayed)"
252+
end)}
253+
""")
254+
end
255+
end
256+
257+
igniter
258+
end
259+
260+
def assert_has_delayed_task(igniter, task, argv) do
261+
if {task, argv, :delayed} not in igniter.tasks do
262+
if Enum.empty?(igniter.tasks) do
263+
flunk("""
264+
Expected to find delayed task `mix #{task} #{Enum.join(argv, " ")}` in igniter tasks,
265+
but no tasks were found on the igniter.
266+
""")
267+
else
268+
flunk("""
269+
Expected to find delayed task `mix #{task} #{Enum.join(argv, " ")}` in igniter tasks.
270+
271+
Found tasks:
272+
273+
#{Enum.map_join(igniter.tasks, "\n", fn
274+
{task, argv} -> "- mix #{task} #{Enum.join(argv, " ")}"
275+
{task, argv, :delayed} -> "- mix #{task} #{Enum.join(argv, " ")} (delayed)"
276+
end)}
243277
""")
244278
end
245279
end

test/igniter/libs/phoenix_test.exs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -220,14 +220,11 @@ defmodule Igniter.Libs.PhoenixTest do
220220
assert TestWeb.Router in routers
221221
assert AdminWeb.Router in routers
222222

223-
# Should exclude router using invalid web module (two levels deep)
224-
refute Foo.BarWeb.Router in routers
225-
226223
# Should exclude modules that aren't routers
227224
refute NotARouter in routers
228225

229226
# Verify exact count
230-
assert length(routers) == 2
227+
assert length(routers) == 3
231228
end
232229

233230
test "falls back to Phoenix.Router detection when no web module match" do

test/igniter_test.exs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,5 +207,61 @@ defmodule IgniterTest do
207207
end) ==
208208
""
209209
end
210+
211+
test "delayed tasks are printed after regular tasks" do
212+
igniter =
213+
test_project()
214+
|> Igniter.add_task("regular.task")
215+
|> Igniter.delay_task("delayed.task")
216+
|> Igniter.add_task("another.regular", ["--flag"])
217+
|> Igniter.delay_task("another.delayed", ["--opt", "value"])
218+
219+
assert capture_io(fn -> Igniter.display_tasks(igniter, :dry_run_with_changes, []) end) ==
220+
"""
221+
222+
These tasks will be run after the above changes:
223+
224+
* \e[31mregular.task \e[33m\e[0m
225+
* \e[31manother.regular \e[33m--flag\e[0m
226+
* \e[31mdelayed.task \e[33m\e[0m
227+
* \e[31manother.delayed \e[33m--opt value\e[0m
228+
229+
"""
230+
end
231+
end
232+
233+
describe "delay_task" do
234+
test "adds delayed tasks correctly" do
235+
igniter =
236+
test_project()
237+
|> Igniter.add_task("regular.task", ["arg1"])
238+
|> Igniter.delay_task("delayed.task", ["arg2"])
239+
240+
assert_has_task(igniter, "regular.task", ["arg1"])
241+
assert_has_delayed_task(igniter, "delayed.task", ["arg2"])
242+
243+
# Check that delayed tasks are stored with the :delayed marker
244+
assert {"delayed.task", ["arg2"], :delayed} in igniter.tasks
245+
assert {"regular.task", ["arg1"]} in igniter.tasks
246+
end
247+
248+
test "delayed tasks are executed after regular tasks" do
249+
igniter =
250+
test_project()
251+
|> Igniter.add_task("first.regular", [])
252+
|> Igniter.delay_task("first.delayed", [])
253+
|> Igniter.add_task("second.regular", [])
254+
|> Igniter.delay_task("second.delayed", [])
255+
256+
# Test the internal sorting function
257+
sorted = igniter.tasks |> Igniter.sort_tasks_with_delayed_last()
258+
259+
assert [
260+
{"first.regular", []},
261+
{"second.regular", []},
262+
{"first.delayed", []},
263+
{"second.delayed", []}
264+
] = sorted
265+
end
210266
end
211267
end

0 commit comments

Comments
 (0)