Packages

A test runner and watcher designed for fast interactive development

Current section

Files

Jump to
yokai lib mix tasks watch.ex
Raw

lib/mix/tasks/watch.ex

defmodule Mix.Tasks.Watch do
@moduledoc """
Watches for file changes and automatically runs tests.
## Usage
mix watch [test_patterns] [options]
## Options
* `--watch-folders` (`-w`) - Comma-separated list of folders to watch for changes (default: "lib,test")
* `--test-patterns` (`-t`) - Comma-separated list of test patterns to run (default: "test/**/*_test.exs")
* `--compile-timeout` (`-c`) - Compilation timeout in seconds (default: 30)
## Examples
# Watch default folders and run all tests
mix watch
# Watch specific folders
mix watch --watch-folders lib,test,config
# Run specific test patterns
mix watch --test-patterns "test/unit/**/*_test.exs,test/integration/**/*_test.exs"
# Set custom compile timeout
mix watch --compile-timeout 60
# Run specific test files
mix watch test/my_test.exs test/other_test.exs
# Combine options
mix watch test/unit test/integration -w lib,test -c 45
"""
use Mix.Task
require Logger
@shortdoc "Watches for file changes and runs tests"
@impl Mix.Task
alias Yokai.Options.CLIParser
alias Yokai.Initializer
alias Yokai.Runner
def run(args) do
options =
args
|> CLIParser.parse()
|> Initializer.run()
load_configs()
Yokai.Application.start(:app, options)
{:ok, pid} = FileSystem.start_link(dirs: options.watch_folders)
FileSystem.subscribe(pid)
Logger.debug("Started with: #{inspect(options)}")
run_tests(options)
watch_files(options)
end
defp watch_files(opts) do
receive do
{:file_event, _watcher_pid, {path, _events}} ->
Logger.info("File changed: #{path}")
run_tests(opts)
watch_files(opts)
{:file_event, _watcher_pid, :stop} ->
Logger.info("Watcher stopped.")
end
end
defp run_tests(opts), do: Runner.start(opts)
defp load_configs do
Mix.Task.run("loadconfig")
Mix.Task.run("app.config")
Logger.info("Configurations loaded.")
end
end