Poor Man Zettel: a CLI

3 minute read

On the 18th of October, I released to the public a small private project called pmz.

In a previous post, I wrote about my approach to Zettelkasten method and discussed why I had my own flow instead of using other software full of features I do not need nor am interested in using.

Also recently I decided I wanted to learn how to code in Go and to get out of the tutorial-zone. I needed a pet project, and I’m pretty bad coming up with ideas for these. But then I remembered about my post and thought about automating most of the things I do in my note taking system with Go, leveraging Cobra, thus building a nice and re-usable CLI.

Go + Cobra + Viper = <3

This combination results in a very interesting and productive stack to build CLIs in Go. No wonder Cobra and Viper are the two most used frameworks to build CLIs in Go. According to their GitHub pages, lots of known software makes use of them to build their CLIs.

Their approach is very straightforward, as well as how to use. More importantly, I found this project to be pretty well documented in all use cases I have implemented so far.

Learning Go

I would consider myself an intermediate Go programmer. I’m passed the basics, although I need more practice. Although I understand their interface concepts and like them, I still need some more practical experience in those, creating my own and implementing my own. Another thing I would like to invest more time into, as it is a core advantage of the language, is concurrency patterns.

Building robust, reliable and readable software seems very easy with Go and I enjoy many of the features it provides. The fact that, for most things at least, there is only one way of doing things, it really helps building concise, predictable software.

Lots of people complain about the error handling that makes code repetitive, but I can see lots of benefits from this:

  1. Code becomes predictable, since you know functions generally return a value that specifies whether that call resulted in an error or not.
  2. You manage errors at the source (you should at least), thus if everything throws an error, you are automatically managing the error at the source.
  3. If we were to follow clean code recommendations, we need to reduce the size of our methods and properly split responsibilities over several methods. If your functions are full of if error != nil statements it probably means they are doing lots of procedures in a single function. Might make sense to split that function into multiple ones. My strategy on this, is to try and keep error handling logic to a maximum of two. If there 3 or more, maybe that needs to be split into different methods.

After learning the language’s basics and syntax, my struggle was then on how to organise code. Coming from a Java and Python school, you kind of get used to organise things in directories and packages are also a visual way to organise code. Procedural programming is different, and this was a huge part of my problems. Coding with Cobra and reading their examples helped me make sense of how things should work and how packages work. I guess this is why learning while doing is generally appraised by many.

Future of the project

It’s not yet done - is there any project ever done!? The core features, creating a new note and searching notes, are, albeit a very rudimentary version 1.

Since I’m a search freak and I want to add more possibilities to the searching feature, this will surely be revisited. I want to be able to do searches in note’s contents, case sensitive (currently it only supports case sensitive), notes created within date ranges or specific dates, and maybe even a few more things. Searching is definitely key to connect knowledge in a project like this.

Another key aspect I want to implement is saving and pulling changes from and into the local copy, respectively.

Those two features will be my next priorities, just to say I have a working version 1. As I will start using this more and more, the search review will come later, as well as other outstanding issues that will come up.

Feel free to use this project, fork it, modify it, suggest features and what-not. Would really love to see some insights from the community, as well as get your input in my code.

Thanks for reading, I’ll see you next time

comments powered by Disqus