View Source Mix.Shell.Process (Mix v1.19.0-dev)

Mix shell that uses the current process mailbox for communication.

This module provides a Mix shell implementation that uses the current process mailbox for communication instead of IO.

As an example, when Mix.shell().info("hello") is called, the following message will be sent to the calling process:

{:mix_shell, :info, ["hello"]}

This is mainly useful in tests, allowing us to assert if given messages were received or not instead of performing checks on some captured IO. There is also a flush/1 function responsible for flushing all :mix_shell related messages from the process inbox.

Examples

The first step is to set the Mix shell to this module:

Mix.shell(Mix.Shell.Process)

Then if your Mix task calls:

Mix.shell().info("hello")

You should be able to receive it in your tests as long as they run in the same process:

assert_receive {:mix_shell, :info, [msg]}
assert msg == "hello"

You can respond to prompts in tests as well:

send(self(), {:mix_shell_input, :prompt, "Pretty cool"})
Mix.shell().prompt("How cool was that?!")
#=> "Pretty cool"

Summary

Functions

Executes the given command and forwards its messages to the current process.

Forwards the error to the current process.

Flushes all :mix_shell and :mix_shell_input messages from the current process.

Forwards the message to the current process.

Prints the current application if it was not printed yet.

Forwards the message to the current process.

Forwards the message to the current process.

Functions

cmd(command, opts \\ [])

Executes the given command and forwards its messages to the current process.

error(message)

Forwards the error to the current process.

flush(callback \\ fn x -> x end)

Flushes all :mix_shell and :mix_shell_input messages from the current process.

If a callback is given, it is invoked for each received message.

Examples

flush(&IO.inspect/1)

info(message)

Forwards the message to the current process.

prompt(message)

Forwards the message to the current process.

It also checks the inbox for an input message matching:

{:mix_shell_input, :prompt, value}

If one does not exist, it will abort since there was no shell process inputs given. value must be a string.

Examples

The following will answer with "Meg" to the prompt "What's your name?":

# The response is sent before calling prompt/1 so that prompt/1 can read it
send(self(), {:mix_shell_input, :prompt, "Meg"})
Mix.shell().prompt("What's your name?")

yes?(message, options \\ [])

Forwards the message to the current process.

It also checks the inbox for an input message matching:

{:mix_shell_input, :yes?, value}

If one does not exist, it will abort since there was no shell process inputs given. value must be true or false.

Example

# Send the response to self() first so that yes?/2 will be able to read it
send(self(), {:mix_shell_input, :yes?, true})
Mix.shell().yes?("Are you sure you want to continue?")