AlCheck

Hex.pmHex DocsHex.pm DownloadsCICoveragecheck --green run

A parallel code quality checker for Elixir projects. Runs format, compile, credo, dialyzer, and tests concurrently with smart test partitioning.

Check out how it works in the live showcase

Features

Installation

Add al_check to your list of dependencies in mix.exs:

def deps do
[
{:al_check, "~> 0.1.0"}
]
end

Then install globally:

mix deps.get
mix check.install
# if you use asdf
asdf reshim

Usage

check # Run default checks
check -v # Show version
check --init # Create .check.json with defaults
check --help # Show help
check --fast # Run only fast checks (format, compile, credo)
check --only format,test # Run specific checks
check --only modified_tests # Run only modified/new tests vs base branch
check --only modified_test_modules # Run whole test files modified on branch
check --partitions 4 # Run tests with 4 partitions
check --dir test/foo,test/bar # Run tests from specific directories
check --failed # Re-run only failed tests from previous run
check --fix # Apply auto-fixes
check --watch # Monitor test partition files in real-time
check --coverage # Show coverage report (cached if unchanged)
check --verbose # Print test output directly
check --test-args '--exclude slow' # Pass custom args to mix test (quoted string)
check --repeat 10 # Run tests with --repeat-until-failure

Available Checks

CheckCommand
formatmix format --check-formatted
compilemix compile --warnings-as-errors
compile_testMIX_ENV=test mix compile --warnings-as-errors
dialyzermix dialyzer
credomix credo --all
credo_strictmix credo --strict --only readability --all
testmix test (with parallel partitioning)
modified_testsRuns only changed test lines vs base branch (builtin)
modified_test_modulesRuns whole modified test files vs base branch (builtin)

Workflows

Failed Test Workflow

check --only test # Run tests, failures saved automatically
check --failed # Re-run only the failed tests

Auto-fix Workflow

check --only format,credo # Run checks and store output
check --fix # Apply fixes from stored output

Modified Tests Workflow

check --only modified_tests # Run only changed test lines
check --only modified_test_modules # Run whole changed test files
check --only modified_tests --repeat 5 # Repeat modified tests

modified_tests detects:

Coverage Workflow

check --coverage # Show coverage report (cached if cover/ unchanged)

Test Partitioning

Tests run in parallel partitions (default: 3). Each partition uses its own database.

check --partitions 4 # Run with 4 partitions

Database setup

Each partition needs its own database to avoid deadlocks and connection limit issues. In config/runtime.exs, use MIX_TEST_PARTITION to create per-partition database URLs:

# config/runtime.exs
partition = System.get_env("MIX_TEST_PARTITION", "")
test_database_url =
System.get_env("TEST_DATABASE_URL")
|> URI.parse()
|> then(fn uri ->
db_name = String.trim_leading(uri.path || "", "/")
Map.put(uri, :path, "/#{db_name}#{partition}")
end)
|> URI.to_string()
config :my_app, MyApp.Repo, url: test_database_url

This creates databases like my_app_test1, my_app_test2, etc.

Avoiding DB connection limits

With N partitions, your database needs at least N * pool_size connections. Increase max_connections in PostgreSQL if you see connection errors:

# PostgreSQL config (or docker run command)
postgres -c max_connections=400 -c shared_buffers=2GB

Consider reducing pool_size per partition in config/test.exs:

config :my_app, MyApp.Repo, pool_size: 10

With 3 partitions and pool_size 10, you need at least 30 connections.

Scheduler tuning

AlCheck automatically limits BEAM schedulers per partition to avoid CPU contention: schedulers_online / partitions. With 10 cores and 3 partitions, each gets ~3 schedulers.

Configuration

Create a .check.json in your project root (check --init generates one with defaults):

{
"run": ["format", "compile", "compile_test", "dialyzer", "credo", "credo_strict", "test"],
"fast": ["format", "compile", "compile_test", "credo", "credo_strict"],
"partitions": 3,
"max_concurrency": 10,
"test_args": "--warnings-as-errors",
"default_repeat": 100,
"base_branch": "main",
"coverage": {
"mod": "native",
"limit": 80,
"html": false,
"baseline_cmd": "git show origin/main:coverage.txt"
},
"fix": [
{"run": "mix format"},
{"run": "mix recode", "files": ".check/credo*.txt"}
],
"checks": {
"format": {"name": "Formatting", "run": "mix format --check-formatted"},
"compile": {"name": "Compile", "run": "mix compile --warnings-as-errors"},
"credo": {"name": "Credo", "run": "mix credo --all"},
"modified_tests": {"name": "Modified Tests", "run": "builtin:modified_tests"},
"modified_test_modules": {"name": "Modified Test Modules", "run": "builtin:modified_test_modules"}
}
}

All fields are optional. CLI flags override config values.

Key config options

KeyDescription
runChecks to run by default (without --only or --fast)
fastChecks to run with --fast
base_branchGit branch for modified test detection (auto-detects main/master if not set)
checksCustom check definitions (replaces built-in checks, test partitions always added)
fixCommands to run with --fix

Custom checks

Each check has a run string (shell command) and optional name:

"sobelow": {"name": "Security", "run": "mix sobelow --config"}

Use builtin: prefix for Elixir-powered checks:

"modified_tests": {"run": "builtin:modified_tests"}

Use {base_branch} placeholder in shell commands — replaced at runtime:

"my_check": {"run": "git diff {base_branch}... --stat"}

Coverage

"coverage": {
"mod": "native",
"limit": 80,
"html": false,
"baseline_cmd": "git show origin/main:coverage.txt"
}
KeyDescription
mod"native" (built-in --cover) or "coveralls" (excoveralls)
limitMinimum coverage %. Fails if below
htmlGenerate full HTML report (default: false, kills early after getting %)
baseline_cmdShell command returning baseline coverage % for delta comparison

Fix commands

"fix": [
{"run": "mix format"},
{"run": "mix recode", "files": ".check/credo*.txt"}
]

files is a glob pointing to output files from previous checks. File paths are extracted from their contents and passed as arguments to the command. Supports globs like .check/credo*.txt to match multiple files.

Output Files

AlCheck creates a .check/ directory:

FileDescription
.check/credo.txtCredo output for auto-fix
.check/credo_strict.txtStrict credo output for auto-fix
.check/check_tests.txtMerged test output from all partitions
.check/test_partition_N.txtIndividual partition outputs
.check/failed_tests.txtFailed test locations
.check/coverage_cache.*Cached coverage results
.check/test_args.txtSaved test args for --failed

Requirements

Documentation

Full documentation is available at https://hexdocs.pm/al_check.

License

This project is licensed under the MIT License - see the LICENSE file for details.