# 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