Where to put complexity
When thinking about where to put complexity, I use the following guidelines:
1) Make the system do less (do less, better) ... is better than ... 2) Documentation of limitations ... is better than ... 3) Expose configuration/extension points ... is better than ... 4) Make it magic.
For example, I was working on some cli tool that needed to make ssh connections to various services. The first pass at this just followed 1) and did the simple thing regarding configuration - just use the standard
~/.ssh/config file. If it didn’t exist, error out. If it was misconfigured, error out. The tool was simple, and did one thing well.
However, over time the ssh configuration required got more complicated, and/or had to change. More and more people unfamiliar with the inner workings of the tool and/or ssh got caught out. Clearly, we needed to try and take away some of the pain of managing this - take some complexity from users into the tool. But which approach to take?
One approach suggested was to make the tool inspect the ssh config, and rewrite it to be “correct”. Or else if missing to generate it. However, this quickly leads down the rabbithole of unexpected behaviour - what if someone had deliberately modified their config and the tool changed it? Maybe it should have a separate config file? More and more complex to maintain.
In the end we went with the short-term approach of adding documentation to explain what the limitations are, and how to rectify any errors. It’s critical however to make sure that the documentation is intuitively discoverable. Man pages, –help flags, sanely located online documentation, standardised approaches etc. It’s worth noting that configuration for this is set up very few times, but that day-to-day usage is common and should be the simplest.