We are no longer in control of our home directories.

My own home directory contains 25 ordinary files and 144 hidden files. The
dotfiles contain data that doesn’t belong to me: it belongs to the programmers
whose programs decided to hijack the primary location designed as a storage for
my personal files. I can’t place those dotfiles anywhere else and they will
appear again if I try to delete them. All I can do is sit here knowing that in
the darkness, behind the scenes, they are there. Waiting in silence. Some of
those programmers decided to additionally place some normal files and
directories in the same place. Those are clearly visible every time I execute
ls in my home directory. It is beyond me why my home directory ended up up
containing a node_modules directory, package-lock.json, a yarn.lock file
(I have never even consciously used yarn!), some 2 strange log files
origination from some Java software clearly using an H2 database, and a
Desktop directory. That last one has been created by Steam, which is quite
unfortunate as I simply do not have a desktop or a desktop environment on my
machine. I dread the day in which I will hear a loud knock on my door and one
of those programmers will barge in informing me that he is going to store a
piece of his furniture in the middle of my living room, If I don’t mind.

To those of you reading this: I beg you. Avoid creating files or directories of
any kind in your user’s $HOME directory in order to store your configuration
or data. This practice is bizarre at best and it is time to end it. I am sorry
to say that many (if not most) programs are guilty of doing this while there
are significantly better places that can be used for storing per-user program
data.

Even if we will never be able to solve this problem – due to the historical
baggage, backward compatibility, software no longer receiving updates or
programming villains storing the files wherever they want just to see the world
burn – we can at least try to follow some sane practices. While the mistake of
introducing the mere concept of a “hidden” file
can’t
be undone anymore, we can at least try to mitigate its results.

This particular problem has been noticed and solved a long time ago with the
creation of XDG Base Directory Specification. The
specification defines a set of environment variables pointing programs to a
directory in which their data or configuration should be stored. It is up to
the user to set those variables so if the variables are not available the
programs are expected to default to a directory defined by the standard and not
the user’s home directory.

User-level variables

$XDG_DATA_HOME

$XDG_DATA_HOME defines the base directory relative to which user specific
data files should be stored. If $XDG_DATA_HOME is either not set or empty, a
default equal to $HOME/.local/share should be used.

Example usage: storing plugins downloaded by the user, databases created by
your program, user’s input history, bookmarks, emails, and so on.

$XDG_CONFIG_HOME

$XDG_CONFIG_HOME defines the base directory relative to which user specific
configuration files should be stored. If $XDG_CONFIG_HOME is either not set
or empty, a default equal to $HOME/.config should be used.

You should use this directory to store user-specific configuration files for
your program. You will most likely want to create a default configuration file
with sane and sensible default values the first time your program is executed.

$XDG_CACHE_HOME

$XDG_CACHE_HOME defines the base directory relative to which user specific
non-essential data files should be stored. If $XDG_CACHE_HOME is either not
set or empty, a default equal to $HOME/.cache should be used.

Example: caching thumbnails generated by your file manager, songs that the user
of a music straming software is often listening to, and so on. Your program
should continue to function without any problems if this directory is removed
by the user. Ensure that the files that are no longer needed are properly
removed. Remember that exceeding the sensible amount of storage space used by
your files will most likely upset the user who will quickly track down your
program as a culprit.

$XDG_RUNTIME_DIR

$XDG_RUNTIME_DIR defines the base directory relative to which user-specific
non-essential runtime files and other file objects (such as sockets, named
pipes, …) should be stored.

The specification lists a series of requirements that have to be fulfilled by
this directory. As described by the specification you should use this directory
to store sockets and similar files used for communication.

System-level variables

$XDG_CONFIG_DIRS

$XDG_CONFIG_DIRS defines the preference-ordered set of base directories to
search for configuration files in addition to the $XDG_CONFIG_HOME base
directory. The directories in $XDG_CONFIG_DIRS should be seperated with a
colon ‘:’.

If $XDG_CONFIG_DIRS is either not set or empty, a value equal to /etc/xdg
should be used.

This directory should be used for storing system-wide configuration files that
can be overwriten by user-specific configuration files. This directory would
most likely be populated during the installation process.

$XDG_DATA_DIRS

$XDG_DATA_DIRS defines the preference-ordered set of base directories to
search for data files in addition to the $XDG_DATA_HOME base directory. The
directories in $XDG_DATA_DIRS should be seperated with a colon ‘:’.

If $XDG_DATA_DIRS is either not set or empty, a value equal to
/usr/local/share/:/usr/share/ should be used.

Example: storing plugins or themes that can be used by all users of your
program. This directory would most likely be populated during the installation
process.

How does this work in practice?

Using the standard is very simple. Read the relevant environment variable and
use the default paths defined by the standard if it is missing. You should then
append a program-specific directory name to it and create the entire directory
tree to store your data.

As an example if you were to store configuration files you should use
$XDG_CONFIG_HOME/your-program as your base configuraion directory instead of
just storing your files directly in $XDG_CONFIG_HOME. Remember to never
hardcode the directories to the default values defined by the standard. Read
the environment variable first to allow the user to move those directories if
needed.

You can easily migrate your existing programs to use this standard. In order to
do so start using the standard when creating new files but keep also checking
the old location of the files when reading them. This will allow you to migrate
without breaking the program for the users with the configuration or data files
that were created by a previous version of your program.

Read the standard to find out more and have a look at the directory hierarchy
which is almost certain to be already present in your home directory. In
reality a cross-platform library allowing you to get a directory for storing
your data will be available for your programming language of choice. On Linux
and similar systems, this library will surely use the XDG Base Directory
Specification.

2019-02-01

Read More

Advertisements