Snag Rewrite
In the early days when I started learning Go, I wasn’t very familiar with its idioms. Like most beginners, I experimented by building small projects. One of those projects was Snag.
The idea behind Snag was simple: it watched the current directory and checked whether a file had been modified. If a change was detected, it would automatically compile the code.
However, there was a major limitation. The compile commands were hard-coded directly into the source code. This made the tool impractical and limited it to only a few languages such as C/C++, Python, and Go. Because of this design choice, the project had several issues and wasn’t an ideal implementation.
At that time I also wasn’t familiar with GitHub, so the project never made it there.
Now things are different. I have spent much more time working with Go, learning its idioms, and understanding how to write more idiomatic and maintainable code. Because of that, I decided to rewrite the project from scratch.
So welcome to my blog on Snag — Rewrite, where I will discuss the improvements and design decisions I plan to implement in the new version.
Old Snag Abilities
The original version of Snag did not have many features. Its primary responsibility was simple: detect file modifications and react accordingly.
But this raises an interesting question: how does Snag detect file changes?
To understand this, we need to look at how Linux tracks file and directory updates.
Linux provides a subsystem called inotify, which monitors filesystem events such as file creation, modification, and deletion. Tools and applications can subscribe to these events to react whenever something changes in the filesystem. In the Go implementation, I used the package fsnotify.
This library internally uses the inotify API on Linux to watch filesystem events. With it, Snag was able to detect when files were modified and trigger the appropriate action.
Now let’s look at what I plan to improve in the new version.
My Plans for the New Version
For the rewrite, I want to make the project more flexible, testable, and scalable. Here are the main ideas I plan to implement.
1. Decoupling Configuration from Logic
In the previous version, build commands were hard-coded in the source code. This made the tool rigid and difficult to adapt for different projects.
In the rewrite, I plan to introduce a configuration file. This file will allow users to specify:
- Files or directories to ignore
- Commands to run when files change
- Other project-specific behavior
You can think of it as something similar to a Makefile. The difference is that instead of manually running commands, Snag will automatically trigger them when relevant files are modified.
This allows developers to focus on writing code rather than repeatedly running build commands.
2. Concurrency and Context
This time I want to take advantage of one of Go’s strongest features: concurrency.
I plan to run commands using goroutines so that processes can execute independently. At the same time, I will manage these processes using context.
This approach solves an important problem.
Imagine a file changes while the previous build process is still running. Instead of tracking PIDs (process IDs) manually, I can simply cancel the running task using the context. Once the previous process is cancelled, a new one can start immediately.
This makes the system cleaner and avoids the complexity of manual process management.
3. Recursive Watching
Another improvement will be recursive directory watching.
At startup, Snag will walk through the entire directory tree and attach watchers to all subdirectories. Additionally, if a new directory is created while the program is running, a watcher will be added dynamically.
This ensures that changes anywhere in the project are detected automatically.
Final Thoughts
These are the core ideas behind the rewrite of Snag. My goal is to turn it into a more robust and flexible tool.
You can think of Snag as a language-agnostic hot reloader. Instead of being tied to a specific language, it relies on its configuration file to determine what files to watch and what commands to execute.
Hopefully, this rewrite will not only improve the tool but also make it a solid project to showcase on my resume.