Packages

Multi-surface application runtime for Elixir. One TEA module renders to terminal, browser (LiveView), SSH, and MCP (agents). 30+ widgets, flexbox + CSS grid, AI agent runtime, distributed swarm with CRDTs, time-travel debugging, session recording, sandboxed REPL, and agentic commerce.

Current section

Files

Jump to
raxol lib mix tasks raxol.check.ex
Raw

lib/mix/tasks/raxol.check.ex

defmodule Mix.Tasks.Raxol.Check do
@moduledoc """
Run comprehensive quality checks on the Raxol codebase.
This task runs multiple quality checks in sequence:
1. Compilation check
2. Format check
3. Credo analysis
4. Dialyzer (if available)
5. Security audit
6. Test suite
## Usage
mix raxol.check [OPTIONS]
## Options
* `--only CHECKS` - Run only specific checks (comma-separated)
* `--skip CHECKS` - Skip specific checks (comma-separated)
* `--strict` - Run all checks in strict mode
* `--quick` - Run only fast checks (skip dialyzer)
## Examples
# Run all checks
mix raxol.check
# Run only format and compile checks
mix raxol.check --only compile,format
# Skip dialyzer
mix raxol.check --skip dialyzer
# Quick check (no dialyzer)
mix raxol.check --quick
"""
use Mix.Task
require Logger
@shortdoc "Run comprehensive quality checks"
@all_checks [:compile, :format, :credo, :dialyzer, :security, :test]
@quick_checks [:compile, :format, :credo, :test]
@impl Mix.Task
def run(args) do
{opts, _, _} =
OptionParser.parse(args,
strict: [
only: :string,
skip: :string,
strict: :boolean,
quick: :boolean
]
)
checks = determine_checks(opts)
Mix.shell().info("Running Raxol quality checks: #{inspect(checks)}")
Mix.shell().info("")
results = Enum.map(checks, &run_check/1)
print_summary(results)
if Enum.any?(results, fn {_, status} -> status != :ok end) do
Mix.raise("Some checks failed")
end
end
defp determine_checks(opts) do
cond do
opts[:only] ->
parse_check_list(opts[:only])
opts[:quick] ->
@quick_checks
true ->
checks = @all_checks
if opts[:skip] do
skip = parse_check_list(opts[:skip])
Enum.reject(checks, &(&1 in skip))
else
checks
end
end
end
defp parse_check_list(str) do
str
|> String.split(",")
|> Enum.map(&String.trim/1)
|> Enum.map(&String.to_atom/1)
end
defp run_check(:compile) do
Mix.shell().info("==> Running compilation check...")
try do
System.put_env("TMPDIR", "/tmp")
System.put_env("SKIP_TERMBOX2_TESTS", "true")
System.put_env("MIX_ENV", "test")
Mix.Task.run("compile", ["--warnings-as-errors"])
Mix.shell().info(" ✓ Compilation successful")
{:compile, :ok}
rescue
e ->
Mix.shell().error(" ✗ Compilation failed: #{Exception.message(e)}")
{:compile, :error}
end
end
defp run_check(:format) do
Mix.shell().info("==> Checking code formatting...")
case Mix.shell().cmd("mix format --check-formatted") do
0 ->
Mix.shell().info(" ✓ Code is properly formatted")
{:format, :ok}
_ ->
Mix.shell().error(" ✗ Code formatting issues found")
Mix.shell().info(" Run 'mix format' to fix")
{:format, :warning}
end
end
defp run_check(:credo) do
Mix.shell().info("==> Running Credo analysis...")
if Code.ensure_loaded?(Credo) do
case Mix.shell().cmd("mix credo --strict") do
0 ->
Mix.shell().info(" ✓ Credo analysis passed")
{:credo, :ok}
_ ->
Mix.shell().error(" ✗ Credo found issues")
{:credo, :warning}
end
else
Mix.shell().info(" ⚠ Credo not available")
{:credo, :skipped}
end
end
defp run_check(:dialyzer) do
Mix.shell().info("==> Running Dialyzer...")
if Code.ensure_loaded?(Dialyxir) do
case Mix.shell().cmd("mix dialyzer") do
0 ->
Mix.shell().info(" ✓ Dialyzer analysis passed")
{:dialyzer, :ok}
_ ->
Mix.shell().error(" ✗ Dialyzer found issues")
{:dialyzer, :warning}
end
else
Mix.shell().info(" ⚠ Dialyzer not available")
{:dialyzer, :skipped}
end
end
defp run_check(:security) do
Mix.shell().info("==> Running security audit...")
if Code.ensure_loaded?(Sobelow) do
case Mix.shell().cmd("mix sobelow --config") do
0 ->
Mix.shell().info(" ✓ Security audit passed")
{:security, :ok}
_ ->
Mix.shell().error(" ✗ Security issues found")
{:security, :warning}
end
else
Mix.shell().info(" ⚠ Sobelow not available")
{:security, :skipped}
end
end
defp run_check(:test) do
Mix.shell().info("==> Running test suite...")
System.put_env("TMPDIR", "/tmp")
System.put_env("SKIP_TERMBOX2_TESTS", "true")
System.put_env("MIX_ENV", "test")
case Mix.shell().cmd(
"mix test --exclude slow --exclude integration --exclude docker"
) do
0 ->
Mix.shell().info(" ✓ All tests passed")
{:test, :ok}
_ ->
Mix.shell().error(" ✗ Some tests failed")
{:test, :error}
end
end
defp run_check(unknown) do
Mix.shell().error("Unknown check: #{unknown}")
{unknown, :error}
end
defp print_summary(results) do
Mix.shell().info("")
Mix.shell().info("=================")
Mix.shell().info("Check Summary:")
Mix.shell().info("=================")
Enum.each(results, fn {check, status} ->
status_str =
case status do
:ok -> "✓ PASSED"
:warning -> "⚠ WARNING"
:error -> "✗ FAILED"
:skipped -> "⊘ SKIPPED"
end
Mix.shell().info(" #{check}: #{status_str}")
end)
Mix.shell().info("")
end
end