Long ago I created a tool called cargo-blinc. It's a cargo subcommand that uses a USB LED light to show the result of running a command defined in a config file. The main purpose was to display live test results while working with code. You can read more details here.

It has some drawbacks and I decided that I'll redesign it. Recently, I open-sourced the initial version of chester.

Drawbacks of cargo-blinc

availability

The first and biggest drawback is that you need to have blink(1) LED light. I'm not sure if it's still possible to get those. The "Buy Now" URL points to the Amazon website where it says "Currently unavailable". Maybe it is still available somewhere, but having to buy hardware equipment to use some software is a big enough pain.

Setup

To be able to use this small USB LED light, your user needs to have rights to access the USB device. It's called the u-dev rule. It's not hard to make it work, I mention how to do that in the README, but that's an additional step you need to do. Even I had trouble with that after I changed distribution. I forgot how to do that. Luckily I inspected the README and the past me was smart enough to mention that there is an additional step to be done. Still, not the best user experience.

Laziness

Even if you have the light, and it's set up correctly, you still need to keep in mind to plug it in when working on your project. Maybe you could plug it in and leave it there even when you are not coding, but for me, this wasn't working. Sometimes I need to pack my laptop, or I'm sitting in a way that dongle sticking out of the USB port is not making it easy.

You could just unplug it when you are not coding and plug it back in when needed. You could also improve your work ergonomics and work at a desk where sticking out a dongle is not a problem, but I'm incredibly lazy. I won't rearrange my apartment just to be able to comfortably sit with something plugged into a USB socket.

Redesign

So I ended up not using this tool. It's a shame because it helps to keep your focus on the code. No cognitive breaks when you want to check if everything is still working after a small refactor. Just keep working and the light will notify you if something is wrong.

client-server architecture

I decided it was time to substitute the LED with something lighter. This time I don't want to stick to any particular frontend. I want a backend server that listens for the changes in the repo, then runs the tests and exposes the results as REST API. This way I'm leaving room for more creative minds to use the API and present the results. It can be a simple desktop widget, it can be IDE extension, or whatever you want. It can be even the same LED light if you want, or it can electrocute you if the tests fail (that would be interesting :D).

unix domain socket

So I did just that. I exposed REST API using Unix Domain Socket (mostly for fun, but also for security reasons). If you don't know what UDS is, it's just a file that acts as an Inter Process Communication socket. This way you are not exposing API to anything outside your machine. Every client needs to have access to the socket file to consume your API. This is exactly what you want for a tool like that. You don't want to expose it to the external world, and you don't need to. This technique is also used by docker - maybe you noticed somewhere the docker.sock thing. That's Unix Domain Socket.

First client

As a first client of chester, I created a project called Always On Stats. It's a small widget displayed in the top right corner of your screen. The widget is implemented with amazing eww. I implemented a script that periodically consumes /check/status, /tests/status and /coverage/status endpoints and changes color depending on the results. When chester detects the change in your project, it sets the status value of check statistic as pending. The widget starts blinking with white and blue colors (the same way as cargo-blinc). When the check finishes with success, the color changes to green, when they fail, it changes to red. When previous stage is finished, the next one starts. In this case the next stage is running tests. When tests are green, then chester checks the tests set - if tests are not changed the coverage stage does not start. If new tests are found or old ones are renamed or removed, coverage starts and finishes with color representing the coverage.

This is the initial implementation:

In the GIF above, you can see that the widget appears when I open the project, and it disappears when I close the projects. It's because I implemented a fish function called h which looks like that:

function h
    if ! pidof chester
        chester > /dev/null &
        sleep 0.5
    end
    set path_to_open "$argv[1]"
    set project_path "$PWD"
    curl --unix-socket /run/user/(id -u)/chester.sock \
        -XPUT -H "Content-Type: application/json" \
        -d "{\"repo_root\": \"$project_path\"}" \
        http://chester/repo/root
    eww open aos
    hx $path_to_open; eww close aos
end

It checks if chester is already running, if not, it starts chester as a background process and sleeps for 0.5 seconds. Then it gets the path I want to open and the current working directory. Next, it sets the repo_root in chester by using curl. Thanks to that, chester changes the directory it listens to for changes. Next, the function opens the aos window (defined in eww.yuck) using eww and starts regular editor hx (it's helix-editor I switched to recently which deserves its own blog post;)). Finally, after ;, the function closes aos, so when I exit helix, the widget disappears.

Future

Right now, chester supports only tests status. The plan is to add more information about the project like code quality. I did some initial research and looks like I will be able to scan the project for metrics like Cyclomatic Complexity, and Halstead metrics - like an effort to maintain the project or difficulty to understand code.

For now, chester is already usable, and I'm starting to work on documentation at least in those parts which won't change much.