I have needed a tool to manage my local Ubuntu and Debian mirrors. Aptly is probably the best tool available to do the job right now. However, none of the available tools are actually great. Most are in varying degrees of non-maintenance or throw out hordes of errors because they look for every file variation even though the Ubuntu and Debian mirror creation tools only release 1 or 2 variations.
Why the new tool?
Since I run several physical and virtual machines on my local network, I need a local software mirror. I am also packaging a few updated or tweaked Debian packages, so I need a storage location for those packages. As a result, I am mirroring the stable and testing versions of Debian, and all the versions of Ubuntu back to the current LTS, Focal Fossa. Add to those a few extra repositories I mirror, PPA’s basically, and my maintenance scripts are getting ridiculous. I am getting tired of directly modifying that massive pile of shell scripting every time a new distro release happens. To help with that, I have released a new tool that will create the non-PPA chunk of the shell scripts from scratch.
After trying to build the same piece of software in Go, PHP, and actual proper shell, this time, I decided to try Rust. The result was pretty interesting. Importing dynamic data structures from any configuration file sucks. While I spent about 12 hours figuring out that the TOML would take longer than I originally wanted to implement. The hard-coded configuration took about 16 hours to build and test. You can get a copy from https://github.com/rrbrussell/aptly_manager.
I would describe using Rust so far as enjoyable frustration. I use a code, run, evaluate, repeat development cycle. While
cargo build is not as fast as
go build, it is quick enough that I can work at a fairly productive rate. When I understand the language in front of me. The completion of the first sub-command to the final v0.1.0 took about one, maybe two hours. I rapidly completed the last part compared to the fourteen or fifteen hours I spent bumbling around parsing command lines and figuring out Rust’s borrow checker.
Again Why Rust?
I am more familiar with Go, PHP, Java, and C# now than with Rust. However, even accounting for the learning curve, I prefer Rust. First off, it integrates better into Linux than C# or .NET. This would not be a big issue, except I like using one language for most tasks, and it appears to be easier to get Rust and GTK working on Windows than C# and GTK working on Linux. There are a couple of larger projects that I have on the back burner. My options for those projects boil down to three options
- using PHP for the back end, with a .NET UI,
- use .NET for both the front and back ends,
- use Rust for both the front and back ends.
Go unfortunately does not work for any of the options because it does not support dynamically loaded plugins or have a useable GUI library available. Rust may not fully support dynamically loading plugins, but it is probably as safe and idiot-proof as Go and supports generics. Rust supports C’s foreign function interface natively, so the worst case is I may write the plugin management code in C and everything else in Rust.