# Savepoint: A CLI for TDD

## Метаданные

- **Канал:** No Boilerplate
- **YouTube:** https://www.youtube.com/watch?v=ZBa3BK4Efcw
- **Дата:** 14.05.2026
- **Длительность:** 7:03
- **Просмотры:** 35,041

## Описание

👉Get Rust training from Let’s Get Rusty: https://letsgetrusty.com/start-with-tris
Hi folks, I've just published a tiny command-line tool called Savepoint. It's a command watcher that commits when you fix errors, automating a TDD workflow. I hope it's handy!
https://github.com/NamtaoProductions/savepoint

❤️ If you would like to support what I do, I have set up a patreon here: https://www.patreon.com/noboilerplate - Thank you!  
📄 All my videos are built in compile-checked markdown, transcript sourcecode available here https://github.com/NamtaoProductions/namtao-com this is also where you'll find links to everything mentioned.
🖊️ Corrections are in the pinned ERRATA comment.
👕 Bad shirts available here https://noboilerplate.org/

🙏🏻 CREDITS & PROMO  
My name is Tris Oaten and I produce fast, technical videos.  
Follow me here https://namtao.com/@noboilerplate  
Website for the show: https://noboilerplate.org  
Come chat to me on my discord server: https://discord.gg/mCY2bBmDKZ  

If you like sci-fi, I also produce a hopepunk podcast narrated by a little AI, videos written in Rust! https://www.lostterminal.com  
If urban fantasy is more your thing, I also produce a podcast of wonderful modern folktales https://www.modemprometheus.com
I just finished Season 2 of The Phosphene Catalogue, if you like mysteries and art, check it out! https://phosphenecatalogue.com/
  
👏🏻 Special thanks to my patreon sponsors:  
- Jaycee,  
And to all my patrons!

## Содержание

### [0:00](https://www.youtube.com/watch?v=ZBa3BK4Efcw) Segment 1 (00:00 - 05:00)

Hi friends, my name is Tris and this is no boiler plate where I focus on fast technical videos. I've got a little project for you that's ready to use today, but first story time. A few years ago, I was a mid-level developer working in a new team. Like happens now and then when you are writing software, I had got myself tied up in a problem and seemed to be going round in circles. I couldn't figure out what I was doing wrong. So, I asked one of the senior developers for help. She came over and the conversation went something like this. I started explaining what I had done that had led to the issue, but she politely but firmly didn't want to hear it. What she wanted us to do was start over, revert to the last working commit and try again. I was horrified. We would be wasting hours of work, I thought, but I was wrong. She was trying to save me from the sunk cost fallacy. We stashed my changes and built it all up from scratch again and I was astonished. Not only did this not take the hours it had originally taken me to tie myself up in knots, but we didn't even trip over the same bugs. Something about the knowledge of what not to do that I'd gained from my previous attempt, plus the clean room approach to solving the issue again, worked surprisingly well. When I asked her where she had learned this horrible but effective technique, she said TDD, test-driven development. In TDD, you build the tests and code iteratively and complementarily to each other. Improve the tests until they fail, then improve the code so the tests pass. I know the method usually has three parts, red, green, refactor, but I don't need to tell you to refactor for the same reason breathe. My senior colleague said that very often in her own work, she would make a commit at this point, a known good state to fall back to, so she wouldn't have far to go if she tied herself in knots and needed to revert to a previous state to try again. At the time, I thought two things. One, this sounded to me exactly like getting to a safe point in a video game and two, I bet this process could be automated. I forgot all about these thoughts until today. I dedicate my video scripts to the public domain. Everything you see here, script, links, and images are part of a markdown document available freely on GitHub and my website namtao. com. So, on that note, I have just published a tiny command line tool called savepoint. It's a command watcher that commits when you fix errors. Here's a demo. To use it, specify the file type you want to watch for changes and the command to watch. This would typically be your fastest unit test suite, or if writing in a language like Rust where if it compiles, it probably works, just your build command. Savepoint executes the command on first run, which is good practice in TDD, so you know you're in a known good state before you start coding. In this example, I yarn tests have passed and checkpoint is monitoring the code for changes using no CPU and almost no RAM while watching. Let's improve our tests to make the code fail. Okay, great. Savepoint picked up our changes, rerun the test command, and it's failed as expected. In TDD, when your tests fail, you improve your code to make them pass. And when we do, Savepoint picks up the changes, reruns the test command, which now passes. Because we've transitioned from a failing state to a passing state, Savepoint makes a Git commit of this known good code. Having done so, it returns to watching for further changes. It does all this without user interaction, looping forever, tick-tocking between failing and passing. You run it once at the start of the day and forget about it until it's time to squash your commits and push your changes. Squashing related commits into an atomic change that can be better understood in a PR or selectively applied in a future debugging situation is good practice generally. But as Savepoint will create multiple small commits as your tests pass, it is vital to clean up those into a single commit before you push. It's possible that I or a kind contributor will automate this in Savepoint in the future. Indeed, there have already been many improvements and changes implemented suggested by my patrons who see these videos before everyone else. It's just me running this channel, and I'm so grateful to everyone for supporting me on this wild adventure. If you'd like to see and give feedback on my videos up to a week early, as well as get private Discord access and even your name in the credits, it would be very kind of you to check my Patreon. I'm also offering a limited number of mentoring slots. If you'd like one-to-one tuition on Obsidian, personal organization, web programming, creative production, or anything that I talk about in my videos, do sign up and let's chat. The core functionality of Save Point is so simple. Before writing in Rust, I prototyped Save Point using Nushell. I write all my scripts in Nu, which is a Rust-like statically typed shell and language. Whereas for my interactive terminal shell, I still prefer Fish. Finally, a shell for the '90s, now written in Rust. Nushell is a delight to prototype quick scripts like this in. Nushell speedruns side quest. Structured data, batteries included, Rust-like errors. Perfection. Okay, back to the Nushell prototype. As you can see, Save Point is doing nothing particularly clever. I'm using a hidden file as a semaphore. Nu magically handles all logs passing in the main signature. If the command exits with an error and the error file exists, that means we just fixed the previous error and it's time to auto commit. And then we block until files are modified again. The most

### [5:00](https://www.youtube.com/watch?v=ZBa3BK4Efcw&t=300s) Segment 2 (05:00 - 07:00)

important realization I had when rewriting this into the final Rust program you can download today is that the logic is way simpler than these nested if statements suggest. It's a state machine with two states, but only one important transition. If the test command passes after previously failing, all other transitions are effectively no-ops. Passing tests when they already passed is a no-op. Failing tests when they were already failing is a no-op. Tests failing when they used to pass is a state change, but nothing happens yet. And only when tests pass after previously failing does something happen. We commit the changes. I actually wrote the first Rust version before figuring this out. I threw away most of that complex code after this realization. I won't walk you through the full code. You can imagine what the implementation looks like, and you can read it on GitHub if you're really curious. But I want to highlight the clarity of structure here. Firstly, it was natural to model the two states of this little state machine with Rust's enums. Then I attached the state to the safe point struct, which is the long-lived app object, including the test program and args supplied by the user, as well as a bunch of flags from the command line. Finally, I implemented on the safe point struct the state transition methods pass and fail, themselves called by the test method depending on the exit code of the user's test command. I'm glossing over a lot of UI and helper functions that don't really matter here, of course. That's it. I hope this little utility becomes an invaluable addition to your daily toolbox. Please report any issues you find or improvements you'd like to see. If you're a Rust developer, I would be delighted to review PRs, too. And if you're not a Rust developer, I can highly recommend the course by friend of the channel and sponsor of today's video, Let's Get Rusty. I don't know if you know, but I'm a tutor in Let's Get Rusty's Rust Accelerator course. I'm host of one of the weekly code clinics. In addition to being a fellow Rust YouTuber, Bogdan runs Rust training, both corporate and personal, with a new cohort starting next month. Visit Let's Get Rusty. com/startwithtrish, link in the pinned comment, to find out more about the training. And thanks so much to Let's Get Rusty for sponsoring this video.

---
*Источник: https://ekstraktznaniy.ru/video/51613*