Packages
mneme
0.10.0
0.10.2
0.10.1
0.10.0
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0
0.9.0-alpha.1
0.9.0-alpha.0
0.8.2
0.8.1
0.8.0
0.7.0
0.6.1
0.6.0
0.5.1
0.5.0
0.4.3
0.4.2
0.4.1
0.4.0
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.3.0-rc.1
0.3.0-rc.0
0.2.7
0.2.6
0.2.5
0.2.4
0.2.3
0.2.2
0.2.1
0.2.0
0.1.6
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
0.0.5
0.0.4
0.0.3
0.0.2
0.0.1
Snapshot testing tool using familiar assertions
Current section
Files
Jump to
Current section
Files
lib/mix/tasks/mneme.install.ex
example = "MIX_ENV=test mix mneme.install"
defmodule Mix.Tasks.Mneme.Install do
@shortdoc "Sets up Mneme in your project."
@moduledoc """
#{@shortdoc}
Running this command will automatically patch the following:
* `mix.exs` - Adds Mneme's tasks to `:preferred_cli_env`
* `.formatter.exs` - Adds `:mneme` to `:import_deps`
* `test/test_helper.exs` - Adds `Mneme.start()` after `ExUnit.start()`
## Example
Since your `:mneme` dependency is usually specified with `only: :test`,
this task should be run with `MIX_ENV=test`.
```shell
$ #{example}
Igniter:
Update: .formatter.exs
1 1 |# Used by "mix format"
2 2 |[
3 - | inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
3 + | inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"],
4 + | import_deps: [:mneme]
4 5 |]
5 6 |
Update: mix.exs
...|
8 8 | elixir: "~> 1.17",
9 9 | start_permanent: Mix.env() == :prod,
10 - | deps: deps()
10 + | deps: deps(),
11 + | preferred_cli_env: ["mneme.test": :test, "mneme.watch": :test]
11 12 | ]
12 13 | end
...|
Update: test/test_helper.exs
1 1 |ExUnit.start()
2 + |Mneme.start()
Proceed with changes? [y/n]
```
"""
use Igniter.Mix.Task
alias Igniter.Code.Function
@example example
def info(_argv, _composing_task) do
%Igniter.Mix.Task.Info{
# Groups allow for overlapping arguments for tasks by the same author
# See the generators guide for more.
group: :mneme,
# dependencies to add
adds_deps: [],
# dependencies to add and call their associated installers, if they exist
installs: [],
# An example invocation
example: @example,
# A list of environments that this should be installed in.
only: [:test],
# a list of positional arguments, i.e `[:file]`
positional: [],
# Other tasks your task composes using `Igniter.compose_task`, passing in the CLI argv
# This ensures your option schema includes options from nested tasks
composes: [],
# `OptionParser` schema
schema: [],
# Default values for the options in the `schema`.
defaults: [],
# CLI aliases
aliases: [],
# A list of options in the schema that are required
required: []
}
end
@doc false
@impl Igniter.Mix.Task
def igniter(igniter) do
igniter
|> update_preferred_cli_env()
|> update_import_deps()
|> update_test_helper()
end
defp update_preferred_cli_env(igniter) do
Igniter.update_elixir_file(igniter, "mix.exs", fn zipper ->
# First, try to update a keyword literal in the project
with {:ok, zipper} <- Function.move_to_def(zipper, :project, 0),
{:ok, zipper} <-
Igniter.Code.Keyword.put_in_keyword(
zipper,
[:preferred_cli_env, :"mneme.test"],
:test
),
{:ok, zipper} <-
Igniter.Code.Keyword.put_in_keyword(
zipper,
[:preferred_cli_env, :"mneme.watch"],
:test
) do
{:ok, zipper}
else
_ ->
# Second, try to update a local function containing a keyword literal.
# This handles `[preferred_cli_env: preferred_cli_env()]`.
with {:ok, zipper} <- Function.move_to_def(zipper, :project, 0),
{:ok, zipper} <- Igniter.Code.Keyword.get_key(zipper, :preferred_cli_env),
true <- Function.function_call?(zipper),
{call_name, _, call_args} <- zipper.node,
{:ok, zipper} <- move_to_def_or_defp(zipper, call_name, length(call_args)),
{:ok, zipper} <-
Igniter.Code.Keyword.put_in_keyword(zipper, [:"mneme.watch"], :test) do
{:ok, zipper}
else
_ ->
{:error,
"Unable to update `:preferred_cli_env` to include `[\"mneme.watch\": :test]"}
end
end
end)
end
defp update_import_deps(igniter) do
Igniter.Project.Formatter.import_dep(igniter, :mneme)
end
defp update_test_helper(igniter) do
Igniter.update_elixir_file(igniter, "test/test_helper.exs", fn zipper ->
with :error <- Function.move_to_function_call(zipper, {Mneme, :start}, :any),
{:ok, zipper} <- Function.move_to_function_call(zipper, {ExUnit, :start}, :any) do
{:ok, Igniter.Code.Common.add_code(zipper, "Mneme.start()")}
else
_ -> {:ok, zipper}
end
end)
end
defp move_to_def_or_defp(zipper, call_name, arity) do
with :error <- Igniter.Code.Function.move_to_def(zipper, call_name, arity) do
Igniter.Code.Function.move_to_defp(zipper, call_name, arity)
end
end
end