On Software: Configuration

These are a few thoughts (from the point of view as an user and also as a developer) on handling configuration data for [application] software.

Introduction: On configuration (or setup) in general

First off, some key insights:

Documentation & Automation

This is more a very general observation on configuring and settings things up, but it seems to fit here (and at the moment probably better than anywhere else on this site, as far as I could see after a quick search):

It’s something that I have discovered again and again over the years for…:

The challenge

One is invested in a topic, focused on how to do it, maybe automate steps of it, and to ease the whole process. And it works fine now — at the moment, while you’r doing and testing it anyways…

Then: Time passes and the “thing” doesn’t need to be set-up or changed again for weeks, months, years.

But at some point in the future, it may come up again: The “thing” needs to be set up/configured anew, for example preparing an application or environment/infrastructure from scratch, on a new computer.

And then you (at least I do, still too often) realize one or more of the following items:

  1. The once so obvious steps are not so obvious anymore and partially forgotten now.
    You should have jotted it down…

  2. Or, even if you wrote it down: The notes are maybe too terse or too verbose.
    Either way: It’s hard/laborious to understand…

  3. You may even have a helper script to automate a lot of the steps, but it requires a very specific environment or expects certain input data.
    Things that were given back then (when the script was initially developed).
    Or it was simply fresh in your own memory from doing/testing it so often; or the details were just an entry away in the terminal’s history away.
    But not anylonger, months/years later…

A solution?

I haven’t (yet?) found the (or a) solution that is completely foolproof.
But I attempt to follow these approaches:

  1. Write things down That is actually the easiest tip tip for me: I’ve (always) tried to document many things, in some kinds of knowledge bases; be it for myself, or at work (for future me or my colleagues, when I’m not available), or in public (e.g. on this site).
    That works and helps pretty well; but also covers not 100% of cases…

  2. It’s a bit harder to find the best level of detail for documentation.
    In general, I tend write too much and to go too deep (typical “brain dumping syndrom” 😄): It’s often not necessary (or only as a footnote) and distracts — even myself, on a second look after a while.

    Therefore I try to look over the documentation once in a while (even if I don’t really need it right now) and ask myself if would be happy with it nowadays (mind you, maybe its for something that needs to be done quickly or under stress!).
    And then revise, if needed: Make it longer/shorter, restructure it, …

  3. Regarding automation, I try to apply the same principle: Check and revise the code occasionally.
    But I also learned that I require more energy and dedication to understand such code (again), compared to simply reading/checking a Todo-List or a “How to…” text.

    And when I’m again in the zone/flow, I must not forget why I was here in the first place:
    To maybe simplify the whole damn thing a bit, so that is still easy to use(!), without first re-learning all the implementation details!


Enable to import/export settings

As an user (and also administrator), I really like it when applications offer (easily detectable and usable!) ways to export and import its settings:
I still use many programs which are installed and configured locally and once the program is customized to my liking (e.g. keyboard shortcuts, fonts, GUI adjustments, etc.), I want to save that work, in case the program needs to be set up again on another machine (be it a second computer or a replacement for a damaged device).

When such a feature is not available (or simply not documented), I try to help myself by using workarounds like manually copying files from the user’s home directory (e.g. under %AppData% or other places) or from the program folder; sometimes even dumping registry values).
But that is of course not an optimal solution, because then I always have the nagging feeling: “Is that all? Or are there more settings stored somewhere else on my system?”.

In general I’d prefer single files in text format (instead of binary blobs), but I also know that this is sometimes not possible, and that some programs (need to) use directories with multiple files in different formats in it (also known as “profiles”).

The bottom line is that ideally a program should offer something like Settings → Export… and Settings → Import… to generate/select configuration formats (files or folders). And it’s also a good idea to offer it via a command-line interface: That can also come in handy if one needs to build automatic and unattended installation scripts for software deployment.


File format for storing configuration data

As an user, I’d prefer to be able to export/import and keep my preferences & settings in a distinct unit, separate from the actual software; ideally as something that resolves to text files (some assets may need to be stored in binary, but I’m talking about a general case here).

There are a lot of formats for saving and exchanging configuration and data; but I will only go into some details for INI, XML and JSON, because although I’m aware of the newer formats like TOML or YAML, I don’t think that they offer anything significantly different from the more common formats mentioned before.

Quick comparison and reasoning

For very simple settings, I may use still the INI format, but for more elaborate stuff, I would try my luck with JSON, since XML is in my opinion too complicated and verbose, at least for elementary things.

JSON Sample Data

{
    "Key 1" : "Some random string value",
    "Key 2" : 100,
    "Key 3" : 1.5,
    "Key 4" : true,
    "Key 5" : false,
    "Key 6" : null,
    
    "Key 7":
    [
        1,
        "abc",
        15.25,
        {
            "Entry A": 256,
            "Entry B":
            {
                 "a": 1,
                 "b": "foo",
                 "c": ["abc", "def"]
            }
        }
    ],
    
    "Product Information":
    [
        0,
        { "xyz" : 1 },
        3,
        
        {
            "Value 1": "Blah blubb",
            "Value 2": "Blah blubber",
            
            "Products":
            [
                [
                    "Item 1",
                    "Item 2",
                    "Item 3"
                ],
                
                [
                    "Item A",
                    "Item B",
                    "Item C"
                ],
                
                {
                    "Details":
                    [
                        {
                            "Name"       : "Foo",
                            "Version"    : 1,
                            "Description": "A short description of product \"Foo\"."
                        },
                        
                        {
                            "Name"       : "Bar",
                            "Version"    : 1,
                            "Description": "A short description of product \"Bar\"."
                        }
                    ]                
                }
            ]
        },
        
        "ABC",
        2,
        9999
    ]
}

Remarks