Where Nerves-related Mix tasks are defined?
Tags: elixir, nerves, raspberrypi, iot
Published: 2024-01-15 20:03:19


Nerves comes with a number of powerful and convenient Mix tasks.

https://nerves-project.org/

Since I have not used many of those Mix tasks, first I want to learn what Mix tasks are available for my Nerves projects.

The Nerves project is made up of separate per-scope sub-projects. So Mix tasks are maintained in different repositories. It is great for maintainability, but finding source code can be a bit hard without prior knowledge. For that reason, it is nice to familiarize ourselves with Nerves sub-projects by casually visiting them.

## Mix

In case, somebody is new to Mix, here is some info.

Mix is a build tool that provides tasks such as creating, compiling, testing, and managing dependencies for Elixir projects.

https://hexdocs.pm/mix/Mix.html

https://elixirschool.com/en/lessons/basics/mix

## Enumerating Mix tasks in Elixir project

First of let's try and enumerate Mix tasks available for your Nerves project. We can achieve that just by running `mix help`.

As an example, let's try it under the [nerves_livebook](https://github.com/nerves-livebook/nerves_livebook/blob/main/README.md) project.

```bash:terminal
cd path/to/nerves_livebook

mix help
```

At this point, the results include non-Nerves Mix tasks. As I counted the number of lines, it was a total of 65. It might vary depending on projects.

```bash:terminal
mix help | wc -l
```

## Filtering down to only Nerves-related Mix tasks

I simply ran `grep` and was able to narrow it down to only Nerves related Mix tasks!

```bash:terminal
mix help | grep 'mix' | grep -iE 'nerves|firmware'
```

The results are as follows.

```bash
mix burn                    # Write a firmware image to an SDCard
mix compile.nerves_package  # Nerves Package Compiler
mix firmware                # Build a firmware bundle
mix firmware.burn           # Build a firmware bundle and write it to an SDCard
mix firmware.gen.gdb        # Generates a helper shell script for using gdb to analyze core dumps
mix firmware.gen.script     # Generates a shell script for pushing firmware updates
mix firmware.image          # Create a firmware image file
mix firmware.metadata       # Print out metadata for the current firmware
mix firmware.patch          # Build a firmware patch
mix firmware.unpack         # Unpack a firmware bundle for inspection
mix local.nerves            # Checks for updates to nerves_bootstrap
mix nerves.artifact         # Creates system and toolchain artifacts for Nerves
mix nerves.artifact.details # Prints Nerves artifact details
mix nerves.clean            # Cleans dependencies and build artifacts
mix nerves.info             # Prints Nerves information
mix nerves.new              # Creates a new Nerves application
mix nerves.system.shell     # Enter a shell to configure a custom system
mix nerves_key.device       # Simulate NervesKey device key creation
mix nerves_key.signer       # Manages NervesKey signing keys
mix upload                  # Uploads firmware to a Nerves device over SSH
```

In case we want to learn the innerworkings of the commands later, it is nice to know where their souce code is located.

## Where Nerves-related Mix tasks are defined

This was more difficult than I had imagined. Nerves projects are packaged by concern. Therefore, various features are managed in different repositories.

The nerves package's [README.md](https://github.com/nerves-project/nerves/blob/main/README.md) explains what each repository is responsible for with a comprehensive listing.

> Our project is spread over many repositories in order to focus on a limited scope per repository.
>
> This repository (nerves-project/nerves) is an entrance to Nerves and provides the core tooling and documentation.

Here are the packages that define Nerves-related Mix tasks.

### nerves package
https://hexdocs.pm/nerves

```bash
mix burn                    # Write a firmware image to an SDCard
mix compile.nerves_package  # Nerves Package Compiler
mix firmware                # Build a firmware bundle
mix firmware.burn           # Build a firmware bundle and write it to an SDCard
mix firmware.gen.gdb        # Generates a helper shell script for using gdb to analyze core dumps
mix firmware.image          # Create a firmware image file
mix firmware.metadata       # Print out metadata for the current firmware
mix firmware.patch          # Build a firmware patch
mix firmware.unpack         # Unpack a firmware bundle for inspection
mix nerves.artifact         # Creates system and toolchain artifacts for Nerves
mix nerves.artifact.details # Prints Nerves artifact details
mix nerves.clean            # Cleans dependencies and build artifacts
mix nerves.info             # Prints Nerves information
mix nerves.system.shell     # Enter a shell to configure a custom system
```

### nerves_bootstrap package

https://hexdocs.pm/nerves_bootstrap

```bash
mix local.nerves            # Checks for updates to nerves_bootstrap
mix nerves.new              # Creates a new Nerves application
```

### nerves_key package

https://hexdocs.pm/nerves_key

```bash
mix nerves_key.device       # Simulate NervesKey device key creation
mix nerves_key.signer       # Manages NervesKey signing keys
```

### ssh_subsystem_fwup package

https://hexdocs.pm/ssh_subsystem_fwup

```bash
mix firmware.gen.script     # Generates a shell script for pushing firmware updates
mix upload                  # Uploads firmware to a Nerves device over SSH
```

:tada::tada::tada:

## Wrapping up

To be honest, I have never used most of the Mix tasks I saw today yet. If you have any cool techniques using them, please share!