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.
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:
int
: Any and just a integer value.float
: Any floating point number, in human-readable
notation.string
: Any non-binary data.stringarray
(or maybe just array
,
list
): A list of strings, with each string on one
line.boolean
: A truth-value that is determined by the
existence of a file.file
: Any file.directory
: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.
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)!
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.
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↩︎
my library doesn’t currently implement this in this way, but it’s something I’m looking to get to.↩︎
though it seems preferable↩︎
modulo DBMS↩︎