ExQuality.Aliases (ExQuality v0.13.0)

View Source

Detects when a project's Mix aliases shadow a task a stage shells out to.

Mix resolves aliases before tasks, so mix sobelow in a project whose mix.exs says

aliases: [sobelow: ["cmd --app web mix sobelow --config"]]

runs the alias and ignores every switch a stage passed. The stage then measures something other than what it asked for, and the failure is quiet: a report that was never written, or a suite run twice and counted twice.

The task names ExQuality shells out to are exactly the ones projects most like to alias - credo, dialyzer, format, sobelow, deps.unlock, test.coverage - so a stage whose parsing depends on its exact invocation asks here first, and refuses to run rather than reporting a number about a command it did not issue.

Detection, not bypass: silently ignoring a project's alias is its own surprise, and naming it gives the reader the choice.

test is deliberately not on the list

A test: alias (["ecto.create --quiet", "ecto.migrate", "test"]) is near-universal and running it is correct - it does the setup the suite needs. test.coverage is different: it is pure aggregation, and an alias on it runs the suite a second time before aggregating.

Summary

Functions

Returns an :error result for a stage that will not run because its task is aliased, naming the alias and what to do about it.

Returns true when the project defines a Mix alias with this task's name.

Functions

shadowed(name, task)

@spec shadowed(String.t(), String.t()) :: ExQuality.Stage.result()

Returns an :error result for a stage that will not run because its task is aliased, naming the alias and what to do about it.

The suggested rename is <task>.all, which is a name Mix will not resolve to the real task and which reads as "the project's own wrapper".

iex> result = ExQuality.Aliases.shadowed("Sobelow", "sobelow")
iex> result.summary
"mix sobelow is aliased in mix.exs"

shadowing?(task)

@spec shadowing?(String.t() | atom()) :: boolean()

Returns true when the project defines a Mix alias with this task's name.

Safe to call outside a Mix project, where there are no aliases to shadow anything.

iex> ExQuality.Aliases.shadowing?("no.such.task")
false