Inspired to repost by https://lobste.rs/s/osumtf/some_tiny_personal_programs_i_ve_written
To bring this full circle, on the “tiny personal programs” thread, I mention a URL shortener I wrote while I was learning Go. Another post of yours (Writing Go CLIs With Just Enough Architecture) inspired me to rewrite it from scratch with a cleaner overall structure. So, thanks for that.
Great to hear! :-)
Thanks for the link!
Can’t help but notice the lack of mention of Cobra or Viper. Especially when there is a sizable section on the flag package.
I’ve used cobra a couple times now, and see no reason to stop. As a new Gopher I’m still trying to figure out Viper. I wonder what the author’s thoughts on these are.
I find myself making quite a few of these, just like the OP. Most recently I started a new CLI to display kanban boards in the terminal from my Nextcloud Deck instance.
I don’t like Cobra or Viper. They seem way too complicated for what they do. The Go standard library flags are fine. A thing a lot of people don’t know is that it accepts -option or --option. If you want short named flags, you can just make two flags point to the same variable. I wrote an extension to the flag package (inspired by @peterbourgon’s ff package) that can read environment variables in as flags and just use that exclusively. I also don’t really believe in subcommands. Just ship two binaries for your two commands. There are very few spaces where Go is a good fit and the storage space matters (if the storage space matters, you’re probably in Rust territory anyway).
Two comments: first, I think I accidentally flagged this while trying to reply. Sorry (and ping @pushcx). I’m still figuring out if I can unflag it.
I can’t speak for the OP, but so far I’m happy just to use flag from the standard library. I don’t mind the lack of long flags, and I like sticking to Go’s standard library and default community style as much as possible. (Update: as @carlmjohnson points out in his comment, I was wrong to imply that you can’t have long options: flag treats -option and --option as equivalent. I think I’ve learned and forgotten this several times already.)
My only complaint about the flag package in the standard library is that I’d like more fine-grained control over where usage messages go. If a user asks for help, then the usage should appear on stdout, but if the usage is printed as the result of user error, then I’d like to send it to stderr. You can do this using the standard library, but it takes a bit of wrangling: https://paste.sr.ht/~telemachus/c1b0b50040dbee19924441d0e1fd39b89eedfc09.
The “rank-em” program, with the issue that a normal sorting algorithm is too many comparisons, reminds me of a tool my co-founder @rafd made, Decidedly. It uses a merge-insertion sort to minimize the number of comparisons, which makes it actually reasonable to pairwise-rank a bunch of choices.
I started with heap sort using Go’s heap package, but found that tedious, so switched to binary insertion sort. Reading the Wiki, it sounds like it might be worth switching to merge insertion if I ever work on it again.