3 ms·
> When config files were written not to be easy to parse, but to make it easier for human beings to configure software Config files have always been a variant
by bonzini 1y ago
> When config files were written not to be easy to parse, but to make it easier for human beings to configure software
Config files have always been a variant of key-value or section-key-value, except that we used to have ad hoc (and probably buggy, inconsistent, incomplete or all three) rules for quoting; array items separated by a mix of spaces, commas or something else; comments (semicolon, percent, sharp) different for each program. Case sensitivity was also a crap shoot, sometimes different between keys and values.
These days TOML (which more or less just works) just works. I have mixed feelings about YAML but certainly I would not swap it with endless variants of sendmail's m4 madness.
- bonzini 1y ago> These days TOML (which more or less just works) just works The second "just works" should have been "is almost always enough".
- 0xbadcafebee 1y agoThere's a universe of config files out there that are not key-value. Most exist for specific applications. It can be hard to configure specific functionality, so developers gave users a particular way to express it. Again with the TOML vs YAML? Ya'll can't come up with anything but another version of the same old thing? You don't need to do the same thing everyone else does with a tiny twist. Think outside the box. Expand your mind! Sure, Sendmail/M4 was a pain in the ass. Postfix was more along the lines of key-value. But Exim had its own rule format, and Qmail took simplicity to the extreme by creating a different file for all the different options. How about an X11 config file? Nginx? Puppet? Bind? Fstab? Vimrc? Rsyslog? Netrc? Cups? Pppd? Iptables? Apt? Cron? Sysctl? SSH? Just name a program on Linux that wasn't created in the last 15 years and it will have a different config file format, tailored to the users and use cases of that application. And none of them are JSON, YAML, or TOML. You don't have to make yours completely unique, but you also don't have to go "oh well, there's only 3 formats to choose from, I guess I will have to settle for one of those". DO YOUR OWN THING! It's your program! Don't be a slave to convention!
- bonzini 1y ago> How about an X11 config file? Nginx? Puppet? Bind? Fstab? Vimrc? Rsyslog? Netrc? Cups? Pppd? Iptables? Apt? Cron? Sysctl? SSH? X11, ssh, Cups are 100% section-key-value or key-value and could be served by TOML easily. Some of these are just programming languages (vimrc, udev, nginx) or shell scripts (iptables) in disguise. By all means keep those. Some are tables (cron, fstab, apt, netrc, syslogd are the ones I recognize). I suppose that's a third category but in the end they're also section-key-value (see systemd timer and mount units) and the bespoke format for the user is just one possible tradeoff between readability and conciseness. A lot of the formats you mentioned do have quoting issues, that would go away with a standardized configuration format.
- 0xbadcafebee 1y agoYou're missing the point, man. Can you replace these configs with TOML, or JSON, or YAML? Sure. With enough key-values you could replace anything. But what's the user experience like? Those generic formats are not designed for a great user experience, they're designed to be generic. So they end up being at best mildly irritating, and at worst wildly frustrating. Here's an SSH config: Include ~/.ssh/my-org/* Host *.co.uk ProxyCommand ssh bastion@my-uk-server.co.uk nc %h %p 2> /dev/null Host newServer HostName newServer.url User adminuser Port 2222 IdentityFile ~/.ssh/id_rsa.key Host anotherServer.tld HostName anotherServer.url User mary Port 2222 Now write that as TOML: [global] include-files = ~/.ssh/my-org/* [host.match-co-uk] host-match = *.co.uk proxy-command = ssh bastion@my-uk-server.co.uk nc %h %p 2> /dev/null [host.match-new-server] hostname-match = newServer hostname = newServer.url user = adminuser port = 2222 identityfile = ~/.ssh/id_rsa.key [host.match-another-server] host-match = anotherServer.tld hostname = anotherServer.url user = mary port = 2222 The SSH config can be read easily, written easily, is easy to understand, and the functionality and format are tied together so you can do more complex things easier. On top of that, the SSH file can be changed around to load includes before or after other lines, to change how they match. The TOML one not only takes longer to write, but it lacks the kind of functionality that the SSH config has to both declare a new block, define its internal name, and specify a config glob, all with the same string. And you can't change how or when includes are loaded or what they overload without adding some kind of "priority" key-value, and then having to read each entry, do some math, change all the values to load different things at different places. (and looking back, I actually screwed up the TOML config, because it was so confusing!) Don't choose a generic solution if it's going to give the user a pain in the ass. If you don't care about the user, then you're part of the enshittification of technology.