I implemented cargo subcommand, which allows running set of commands and notify about the results of those commands via USB LED notification light — blink(1). I published the tool today. The code is here.

Why

I'm a fan of TDD while developing a software. The main gain here is better, cleaner design of your software and, as a side effect, you get the tests.

It's sooo much nicer to work with code that has high coverage. The feeling of the safety is priceless — especially while performing large refactor.

The pain point here is that you need to switch context very often. You are making small change in the code, then switch to run the tests and verify results. Switch back to the code, make another small change and, again, switch to run tests. I decided to make it a little easier.

Origins

Some time ago I bought blink(1) USB notification light. I wasn't really using it until I started to learn Rust. I've got inspired by posts about embedded Rust on reddit. This project isn't really embedded software, but I wanted to play with some hardware, so I used the opportunity to dust off blink(1).

Second inspiration was infinitest. It's a test runner which can be integrated with IDEs via plugins. It automatically runs tests after each change and shows the results in some way — depending on the plugin.

I thought it would be very useful to have LED light which, after a file change, starts blinking with some color to notify that the tests started running, then changes to red if the tests fail or green if everything is fine. That's what I've done.

Demo

how to use

If you want to play with it just do:

cargo install cargo-blinc

, then:

cargo blinc --init ./blinc.toml

First command downloads cargo-blinc and the second uses it to initialize config file. Default configuration looks like this:

[[task]]
cmd = "cargo"
args = ["check"]

[[task]]
cmd = "cargo"
args = ["test"]

[colors]
pending = ["blue", "blank"]
failure = "red"
success = "green"

[env]

First we have defined a [[task]]. We can have multiple tasks. All of them will be executed by cargo-blinc in the order they exist in the config file. In this case we have two tasks: cargo check and cargo test.

The [colors] section describes how blink(1) should notify us about the state of our tasks' execution. While our tasks are being executed, the pending part of [[colors]] is in play. Here we will get blinking blue light. When any of the tasks fail, then we get color defined under success key, otherwise, the color will be defined by failure key. You can find more about colors here.

The [env] section allows to set any environment variables, e.g.:

[env]
RUST_LOG = "debug"
RUST_TEST_THREADS = "1"

That's all about configuration. Then I just do:

cargo watch -x blinc

If you don't use cargo-watch, you can find more info here.

Library

I extracted the logic which controls the blink(1) to a separate crate. You can find it here. I used cool blinkrs crate which knows how to talk to this small device.

This deserves its own blog post though :).