Directories, Configuration Files and Configurations Files as Directories

Monday, 9 September 2019

One of the inconsistencies in Unix and other modern systems, is where the structured hierarchy directories end, and where the freely formatted file begins. Sadly not too many people tend to think about where the line should be drawn, which is certainly a case-to-case question.

As an example, I’ve been thinking about “configurations files”, and where the line should be drawn in this case. This is also interesting, since configuration files have historically been a kind of problem that Unix-like systems had to struggle with. You have colon-delimited formats like in /etc/passwd, per-line options like in /etc/ssh/ssh_config. Emacs doesn’t even have a configuration file, but a complete programming language, that runs a “initialisation script” (~/.emacs.d./init.el) when started. Some choose JSON, others YAML and yet others TOML, each which can be cleverly used or abused depending on how it’s applied. Then there are those that seeing all the chaos and confusion, abandon this approach, and instead

But it seems as though none if this is necessary, especially if one recalls the Unix maxim “everything is a file”: I’ve recently been playing with the concept of structuring configurations as files within a base directory, and it seems to work well. I would like to introduce my solution, and then discuss advantages and disadvantages I see, hoping to start a discussion on the plausibility of this idea.

It should be noted that this is not completely new. Many Plan9 tools exposed some of their functionality through the file system, allowing editors like Acme to have tools change or process the content of a buffer or it’s tag-line by editing virtual files. Hence the main difference here is that we are not working with virtual file systems, but just regular/any file system.

Practical Example

I have implemented this approach in Go, and published it under the name “dirconf”1. I will not go into the details of this specific implementation, since that would have more to do with Go than the idea itself, Instead I will focus the files and conventions it tries to use.

In accordance with the XDG specification, this library will attempt to use the directory under $XDG_CONFIG_HOME/[name of the current binary], usually ~/.config/something, where something is the program in use.

In this directory, the hierarchical value server -> listen-on or users -> john-> age could be simply found in the files ~/.config/something/server/listen-on and ~/.config/something/users/john/age respectively. The latter file could just contain the number 43. Any non-number would result in a error.

Another interesting example would be boolean values, that would be represented by the existence or absence of a file, or any more complex data such as images that could just as easily be placed in the configuration, as compared to classical in-file formats.

The last thing worth mentioning would be that I currently write out a .schema file. It’s content more closely resemble a classical configuration file, usually looking something like this2:

int users/*/age
url server/listen-on
bool    active

(note that there is a “tab” between the two columns)

This type specification could be used by a editor or other tool, to easily let a user know what file expects what content, and avoid errors before configuration parsing. I currently had following types in mind:

Whether or not this should actually be a plain file, should also be though of. It could also make sense to have .schema be it’s own directory, and have a as file to content, so variable to type setting in there.

What role file extensions, especially with richer media would play (are profile.jpg, profile.png and profile.gif all different keys or not), would have to be discussed.

Advantages

Disadvantages


I would love to hear more opinions on the subject that I could add here. Just send me an Email or a message. I’m currently inclined (and biased) to think that there is something to this approach, but I’m open to be convinced otherwise, or informed about other examples that tried something like this (failures or successes)!


Updates

2019-09-11

I have since writing this article reworked the dirconf library for go, and it seems to be in a more or less stable state. The .schema file looks like a better way to forward, for the simplicity of creating a dirconf editor, but the types/typenames are as of now not stable.


  1. As of writing, I should point out that this is still a very experimental implementation, that one shouldn’t rely on. Most of the code was just recently rewritten on a bus ride home, around one o’clock in the morning, and hence some of the design decisions will be still reconsidered↩︎

  2. my library doesn’t currently implement this in this way, but it’s something I’m looking to get to.↩︎

  3. though it seems preferable↩︎

  4. modulo DBMS↩︎