SvelixirNew. Bootstrap
(svelixir_new v0.11.0)
Copy Markdown
The mix svelixir.new sequence, with every effect injected.
It lives here rather than in Mix.Tasks.Svelixir.New.run/1 for a coverage
reason that is structural, not stylistic: @impl Mix.Task fixes run/1's
arity at 1, so there is no parameter through which a fake runner could reach
the sequence. Measured with the sequence inlined in run/1, 12 of 14 relevant
lines were reachable only from a @tag :toolchain test that
ExUnit.start(exclude:) removes from the coverage run, and rescuing them with
coveralls-ignore blew the 5% budget several times over.
The call order is load-bearing
The generator probe must precede any dependency work, because
mix deps.compile prunes every archive off the code path
(Code.delete_paths(current_paths -- loaded_paths)). Measured: archive paths
go from three entries to [] across that one call, after which
Mix.Task.get("phx.new") returns nil even though phx_new is installed on
disk.
Patching and config-writing precede dependency work too, so a project whose
mix.exs cannot be patched is never compiled against a dep it does not
declare.
Summary
Functions
The real effects.
Runs the bootstrap. See this module's documentation for the ordering rules.
Types
@type effects() :: %{ getenv: (-> %{optional(String.t()) => String.t()}), lookup: SvelixirNew.Shell.lookup(), generator: (String.t(), [String.t()] -> any()), runner: SvelixirNew.Shell.runner(), shell: module() }
Functions
@spec defaults() :: effects()
The real effects.
@spec run(SvelixirNew.Options.t(), effects()) :: :ok
Runs the bootstrap. See this module's documentation for the ordering rules.