I’m writing a mix task that acts as a watcher, running other tasks when files change.
I have most of it working, but I don’t seem to be able to run the compile
task—it seems to be silently ignored.
The function that does the running looks like this:
defp run_tasks(tasks) do
Logger.info "watch is running: #{Enum.join(tasks, ", ")}"
for task <- tasks do
Logger.info task
change_env(task)
Mix.Task.run(task, (if task == "compile", do: ["--force"], else: []))
Mix.Task.reenable(task)
end
end
(I hacked the —force option in there to see if it would make a difference—it doesn’t)
I see output like this
[Play/watcher] mix watch
Compiled lib/watcher.ex
Compiled lib/watch/notifier.ex
Generated watcher.app
23:47:54.118 [info] watch is running: compile, test
23:47:54.118 [info] compile
23:47:54.119 [info] test
.
Finished in 0.03 seconds (0.03s on load, 0.00s on tests)
1 tests, 0 failures
The compile task generates nothing, and doesn’t actually compile (I add syntax errors to files and save them).
So, is there some magic to get this to work?
Cheers
Dave
--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
We are having a similar discussion on another issue. What should be the best course of action: clear up how tasks (there is a private API that clears all tasks on the Mix.TasksServer) or manually clean up what you want?
Also, it is worth pointing out that simply recompiling in the same process will likely not work when you are changing a GenServer or the messages between process because the old ones will continue running. You likely want to stop the application, compile it and start it again.
So, to add to the confusion…
I changed the runner to call Mix.Task.clear
before running the test
task.
The good news—it now compiles before it runs the tests.
The bad news—it crashes the second time I alter a file:
[Play/watcher] mix watch •[master]
Compiled lib/watch.ex
Compiled lib/watch/notifier.ex
Generated watch.app
#### at this point I touch a file.... ####
11:13:57.038 [info] watch is running: test
11:13:57.038 [info] test
lib/watch.ex:1: warning: redefining module Mix.Tasks.Watch
lib/watch/notifier.ex:1: warning: redefining module Mix.Tasks.Watch.Notifier
Compiled lib/watch.ex
Compiled lib/watch/notifier.ex
Generated watch.app
.
Finished in 0.03 seconds (0.03s on load, 0.00s on tests)
1 tests, 0 failures
Randomized with seed 189048
### and now I touch another file... ###
11:14:00.733 [info] watch is running: test
11:14:00.733 [info] test
lib/watch.ex:1: warning: redefining module Mix.Tasks.Watch
** (EXIT from #PID<0.47.0>) killed
I feel like I’m fighting the wrong battle here. Is there a better way to do this?
Dave
Ahhh.
This only happens when I watch the actual watcher—running it as a dependency in another app seems to work.
But, now it can’t find the test files the second time around:
[tmp/wobble] mix watch
watch is running: test
lib/watch.ex:1: warning: redefining module Mix.Tasks.Watch
lib/watch/notifier.ex:1: warning: redefining module Mix.Tasks.Watch.Notifier
==> watch
Compiled lib/watch.ex
Compiled lib/watch/notifier.ex
Generated watch.app
lib/wobble.ex:1: warning: redefining module Wobble
==> wobble
Compiled lib/wobble.ex
Generated wobble.app
1) test the truth (WobbleTest)
test/wobble_test.exs:4
Assertion with == failed
code: 1 + 1 == 99
lhs: 2
rhs: 99
stacktrace:
test/wobble_test.exs:5
Finished in 0.03 seconds (0.03s on load, 0.00s on tests)
1 tests, 1 failures
Randomized with seed 938036
watch is running: test
Finished in 0.00 seconds
0 tests, 0 failures
Randomized with seed 820046
>
> That's because the test files were already required. You can use Code.loaded_files and Code.unload_files to clean up the require cache but at this point you are really looking for trouble and already defined warnings. :)
>
so is it basically impossible to run a watch task from within mix?