92 lines
1.9 KiB
Elixir
92 lines
1.9 KiB
Elixir
# SPDX-License-Identifier: Apache-2.0
|
|
# SPDX-FileCopyrightText: 2021 The Elixir Team
|
|
|
|
defmodule CoverageRecorder do
|
|
def maybe_record(suite_name) do
|
|
if enabled?() do
|
|
record(suite_name)
|
|
|
|
true
|
|
else
|
|
false
|
|
end
|
|
end
|
|
|
|
def enable_coverage do
|
|
_ = :cover.stop()
|
|
{:ok, pid} = :cover.start()
|
|
|
|
cover_compile_ebins()
|
|
|
|
pid
|
|
end
|
|
|
|
def cover_dir, do: Path.join(root_dir(), "cover")
|
|
|
|
defp enabled? do
|
|
case System.fetch_env("COVER") do
|
|
{:ok, truthy} when truthy in ~w[1 true yes y] ->
|
|
true
|
|
|
|
_ ->
|
|
false
|
|
end
|
|
end
|
|
|
|
defp root_dir, do: Path.join(__DIR__, "../../..")
|
|
defp ebins, do: root_dir() |> Path.join("lib/*/ebin") |> Path.wildcard()
|
|
|
|
defp record(suite_name) do
|
|
file = Path.join(cover_dir(), "ex_unit_#{suite_name}.coverdata")
|
|
|
|
enable_coverage()
|
|
|
|
System.at_exit(fn _status ->
|
|
File.mkdir_p!(cover_dir())
|
|
|
|
:ok = :cover.export(String.to_charlist(file))
|
|
end)
|
|
end
|
|
|
|
defp cover_compile_ebins do
|
|
relevant_beam_files()
|
|
|> Enum.map(&String.to_charlist/1)
|
|
|> :cover.compile_beam()
|
|
|> Enum.each(fn
|
|
{:ok, _module} ->
|
|
:ok
|
|
|
|
{:error, reason} ->
|
|
raise "Failed to cover compile with reason: #{inspect(reason)}"
|
|
end)
|
|
end
|
|
|
|
defp relevant_beam_files do
|
|
ebins()
|
|
|> Enum.flat_map(fn ebin ->
|
|
ebin |> Path.join("*.beam") |> Path.wildcard()
|
|
end)
|
|
|> Enum.reject(&skip_from_coverage?/1)
|
|
end
|
|
|
|
@to_skip [
|
|
# Tested via the CLI only
|
|
:elixir_sup,
|
|
:iex,
|
|
Kernel.CLI,
|
|
Mix.CLI,
|
|
Mix.Compilers.Test,
|
|
Mix.Tasks.Test,
|
|
Mix.Tasks.Test.Coverage,
|
|
|
|
# Bootstrap
|
|
:elixir_bootstrap,
|
|
Kernel.SpecialForms
|
|
]
|
|
|
|
defp skip_from_coverage?(file) do
|
|
mod = file |> Path.basename(".beam") |> String.to_atom()
|
|
mod in @to_skip or match?({:docs_v1, _, _, _, _, %{deprecated: _}, _}, Code.fetch_docs(mod))
|
|
end
|
|
end
|