Discussion:
XDG_STATE_HOME
Allison Lortie
2016-12-23 15:32:55 UTC
Permalink
hi,

I apologise in advance for the novel below.

Take a look in your ~/.local/share/. It's probably a mess.

We're basically using this directory for two things right now, and I
think that only one of them is appropriate.

1) We are using it as the "user's layer" for XDG_DATA_DIRS

2) We are using it as a dumping ground for application state


It's worth mentioning that usage #2 is not specifically endorsed by the
specification itself. It says that "XDG_DATA_HOME defines the base
directory relative to which user specific data files should be stored"
and goes to quite some lengths to talk about how it is basically a
higher-priority "user-specific" version of XDG_DATA_DIRS. It never
talks about it as being an appropriate place to dump writable
application state data.

But here we are. Everyone does this, because they think that ~/.config/
is not an appropriate place to be putting stuff that's not really
configuration (and I agree).

Further: due to the dual usage of XDG_DATA_HOME for XDG_DATA_DIRS type
stuff (applications/, icons/, fonts/, etc.) and random application
state, some people (myself included) hesitate to fully embrace it as
"the top XDG_DATA_DIR". GLib, for example, still has two separate APIs
for this variable, and never treats XDG_DATA_HOME as the top layer of
XDG_DATA_DIRS.

For some time (years) I've wanted to clean up this mess and introduce a
proper, documented, place for application state information. In fact,
I've received many pleas for this from several ISVs since some years
ago, who port an app from another platform, and just want one directory
that they can use for everything. Since we've never documented what
this place is, some are (rightly) apprehensive about just using
~/.local/share/ and contributing to the problem.

So let's try this:

I'd like to introduce the XDG_STATE_HOME variable. It would default to
~/.var/. Just as ~/.local/share is the user's version of
/usr/local/share, ~/.var/ is the user's version of /var. Applications
that wish to store unstructured state data (bookmarks, cookies, game
save files, internal databases, etc.) should create a subdirectory under
this directory thus:

XDG_STATE_HOME + "/app/" + app_id

and store their state there.

For example, you might see ~/.var/app/org.gnome.gedit/.

We could also imagine ~/.var/lib/ subdirectories for use by system
components (read: not apps) or "well known" files, such as things like
recently-used.xbel.

Meanwhile, I think we should strengthen the language in the spec about
how XDG_DATA_HOME should absolutely be considered the top layer of
XDG_DATA_DIRS, and that compliant applications and libraries should
always allow the user's verion of a file found here to take precedence
over those found at the system level. The expected use for this
directory would then be *exclusively* for things like icons, desktop
files, gsettings schemas, fonts, etc.

One day we might also dream about moving the hilariously inappropriate
~/.local/share/Trash/ to ~/.var/trash/ or even ~/.cache/ to
~/.var/cache/. See [1] for information on back-compat.

As for migration of application data: it's my opinion that we could be
somewhat neutral on this point. We certainly will not automatically
move any application data by a specification change, or even a (eg.
GLib) library change. Applications would have the choice to follow the
new convention or not, but if they did, we should maybe give some
pointers on how to handle the migration. Again, see [1].

Next on the wish list, I guess, would be introduction of language into
the spec to suggest that apps also only create properly named
(org.gnome.gedit style) directories under ~/.config/ as well, again
using [1]. This is a separate topic, though.

I welcome everyone's thoughts on this topic. I expect that we will be
discussing this well into the new year. :)

Allison



[1] Backwards compatibility is important for two reasons:

1. applications which want to keep their data from older versions

2. "common" directories which will be accessed by apps and libraries
under both the new and the old conventions

I propose the following trick to handle both cases. Normally, an app
computes the effective 'dirname' and then does something like:

dirname = (compute);
if not exists dirname:
mkdir_with_parents(dirname)
...use dirname...

Here is a nice trick for "moving" to a new place:

new_dirname = (compute); // the new location

if not exists new_dirname:
// make the parents, but not the dir itself
mkdir_with_parents(parent(new_dirname))

// check if the old directory exists:
old_dirname = (compute); // the former location
if exists old_dirname:
make_relative_symlink(old_dirname, new_dirname);
else:
mkdir(new_dirname)

...use new_dirname...


The effect is that "new" users in a clean home directory (or those who
manually take steps to "clean house") would start using only the new
paths, while existing users with data from before the transition would
have their files left in place, and the new version of the app would
follow a symlink. This has a lot of nice properties:

- we don't annoy the user by moving data around

- backup exclude lists continue to work

- the described algorithm is race-free

- the 'old' apps don't see any symlink, so they won't break because of
it

- after the 1st run (ie: dir exists) it's just as efficient as before

There is a drawback: one claim of this system is that it allows 'new'
and 'old' app versions to continue to share the directory. If the 'new'
version is the first to start, however, the new directory will be
created, and the old directory will be completely left alone. When the
old version starts, it will create the old version, as a completely
separate directory. I consider this case to be rare for application
data, since downgrades and multiple versions are uncommon.

This problem might be an issue if we decide to move directories like
cache or trash, since it will be quite common to have a mix of
applications following 'new' and 'old' conventions installed. If the
'new' apps run first, we end up with two separate directories. For
cache, I guess this is no big problem (since sharing cached data is
rare, and even in the case of things like thumbnails, failing to share
is not a huge problem). For trash, we might have to be more careful,
however, and it may be worth introducing specific language to the spec.
David Faure
2016-12-26 13:25:46 UTC
Permalink
Hello Allison,
Post by Allison Lortie
Take a look in your ~/.local/share/. It's probably a mess.
How did you know? :-)

[...]
Post by Allison Lortie
One day we might also dream about moving the hilariously inappropriate
~/.local/share/Trash/ to ~/.var/trash/ or even ~/.cache/ to
~/.var/cache/. See [1] for information on back-compat.
I don't think we want to move ~/.cache at all.

~/.cache is something you can wipe away, exclude from backups, and you won't
have lost anything.
On the other hand, if you lose your future ~/.var, then you will have lost
bookmarks, cookies, and so on. So that one, you do want in your backup.

IMHO the primary reason for a clean directory structure is to be backup-
friendly. The only other reason I can think of is, well, that we all have a
bit of OCD with such issues :-)

One thing to note though: by using XDG_DATA_HOME for many things which are not
initially thought of as a local override of a global dir, it still
automatically opens the door for that. For instance bookmarks: we mostly think
of them as local-only, but by saving bookmarks in XDG_DATA_HOME we
automatically support pre-installing a bookmark file globally as a starting
point for first-time users.

But yeah there are many things for which it doesn't make sense to have global
data (recently visited links or files, autosave files, filemanager per-directory
view state, locally stored calendar events, etc.), which would fit well into
your ~/.var idea.

And indeed, the trash dir too, although you're right that migration will be
problematic. Maybe we should start with changing implementations to support
both dirs for a few years, and only then start ignoring the old one?

Conclusion: the tricky bit is going to be documenting exactly what goes into
~/.var. "Application data for which it will not be ever be useful for it to be
an override of a system-wide version of the data" doesn't read well ;)

And the question of "what is config and what is state" will pop up for sure
(I move a toolbar and Qt stores this as a binary blob, is that config or
state?). Config is user settings (etc. configuration dialogs) while state is
"other stuff apps want to save, which is not just a cache" ?

(where "cache" means: anything that only exists for performance reasons and
that can be thrown away)
--
David Faure, ***@kde.org, http://www.davidfaure.fr
Working on KDE Frameworks 5
Allison Lortie
2017-01-03 16:43:39 UTC
Permalink
hi David,

Thanks for your reply. I'm back from holidays now :)
Post by David Faure
Post by Allison Lortie
One day we might also dream about moving the hilariously inappropriate
~/.local/share/Trash/ to ~/.var/trash/ or even ~/.cache/ to
~/.var/cache/. See [1] for information on back-compat.
I don't think we want to move ~/.cache at all.
I agree that this is useful, but it would be just as easy to blacklist
~/.var/cache from backups as it is to do ~/.cache/. This is backup
*and* OCD friendly. :)
Post by David Faure
One thing to note though: by using XDG_DATA_HOME for many things which are not
initially thought of as a local override of a global dir, it still
automatically opens the door for that. For instance bookmarks: we mostly think
of them as local-only, but by saving bookmarks in XDG_DATA_HOME we
automatically support pre-installing a bookmark file globally as a starting
point for first-time users.
Interesting. I didn't consider pushing in this other direction as well.
In practice, I guess this probably doesn't make sense unless you have:

1) a standard for bookmarks used across the entire desktop
2) support for expanding ~ (so the one in /usr can talk about your
homedir)
3) support for whiteouts so users can delete "system" bookmarks

either way, quite far out of scope with what is being discussed here...
but possible.
Post by David Faure
And indeed, the trash dir too, although you're right that migration will be
problematic. Maybe we should start with changing implementations to support
both dirs for a few years, and only then start ignoring the old one?
More or less, yes. This is exactly what I was thinking. Trash may very
well be unique here.
Post by David Faure
Conclusion: the tricky bit is going to be documenting exactly what goes into
~/.var. "Application data for which it will not be ever be useful for it to be
an override of a system-wide version of the data" doesn't read well ;)
I think of it more as "something that the system isn't interested in" or
"something that is not, conceptually, being 'installed' in any sense".
Fonts, icons, desktop files, mime data, etc. are all very clearly in one
category while application data is very clearly in another. The only
thing that blurs the line a bit, imho, is application plugins (which
are, indeed, "installed", but still app-specific).
Post by David Faure
And the question of "what is config and what is state" will pop up for sure
(I move a toolbar and Qt stores this as a binary blob, is that config or
state?). Config is user settings (etc. configuration dialogs) while state is
"other stuff apps want to save, which is not just a cache" ?
Indeed: I think the bigger problem for app authors will be deciding
between ~/.var/ vs. ~/.config/ but I think it is fairly easy to explain
that one. Also: some people just don't care. A big part of this is
providing a nice place that is *not* ~/.config/ for people who can't be
bothered to split out their config from their state. We've clearly lost
the war of trying to force that separation on everyone.


I'll start drafting a patch to the spec over the next couple of days.


Thanks for the feedback,

Allison
David Faure
2017-01-04 09:11:20 UTC
Permalink
Post by Allison Lortie
hi David,
Thanks for your reply. I'm back from holidays now :)
Post by David Faure
Post by Allison Lortie
One day we might also dream about moving the hilariously inappropriate
~/.local/share/Trash/ to ~/.var/trash/ or even ~/.cache/ to
~/.var/cache/. See [1] for information on back-compat.
I don't think we want to move ~/.cache at all.
I agree that this is useful, but it would be just as easy to blacklist
~/.var/cache from backups as it is to do ~/.cache/. This is backup
*and* OCD friendly. :)
I disagree. It's useful to be able to copy ~/.var from one machine to the next
(I need application state) without bringing the caches along (they can be
recreated). If we don't make the directory structure convenient and we rely on
blacklists then we might as well make a big mess ;)
Post by Allison Lortie
Post by David Faure
One thing to note though: by using XDG_DATA_HOME for many things which are not
initially thought of as a local override of a global dir, it still
automatically opens the door for that. For instance bookmarks: we mostly think
of them as local-only, but by saving bookmarks in XDG_DATA_HOME we
automatically support pre-installing a bookmark file globally as a starting
point for first-time users.
Interesting. I didn't consider pushing in this other direction as well.
1) a standard for bookmarks used across the entire desktop
Not necessarily. This was about bookmarks for one specific navigator.
Still useful.
Post by Allison Lortie
2) support for expanding ~ (so the one in /usr can talk about your
homedir)
I'm talking about web bookmarks, not filemanager bookmarks.
Post by Allison Lortie
3) support for whiteouts so users can delete "system" bookmarks
The bookmarks being XML (XBEL standard), there is no merging happening. Only
one file is loaded. As long as there is no local file, the global file is picked
up. As soon as you create a local file (which is done by saving the memory
representation, so the first version will include the global bookmarks)
Post by Allison Lortie
either way, quite far out of scope with what is being discussed here...
but possible.
My point is that it is already possible, and is a reason for thinking twice
before moving too many things from ~/.local/share to ~/.var.
Unless we add XDG_STATE_DIRS for global dirs but it seems wrong,
for things that are actually state and not user data.
On the other hand there are of course other ways to achieve this, if less
convenient (e.g. copying the initial file by hand).
Post by Allison Lortie
Post by David Faure
Conclusion: the tricky bit is going to be documenting exactly what goes into
~/.var. "Application data for which it will not be ever be useful for it to be
an override of a system-wide version of the data" doesn't read well ;)
I think of it more as "something that the system isn't interested in" or
"something that is not, conceptually, being 'installed' in any sense".
Fonts, icons, desktop files, mime data, etc. are all very clearly in one
category while application data is very clearly in another.
Ah, that is another way to draw the line indeed.
With that approach, all "user data" (bookmarks, events...) would go to ~/.var
too then.
I didn't think of it that way initially but I see the point: ~/.var is unique
to the user (my own bookmarks etc.) while ~/.local/share would be limited to
stuff I installed, which I could reinstall if needed.
Post by Allison Lortie
The only thing that blurs the line a bit, imho, is application plugins
(which are, indeed, "installed", but still app-specific).
Plugins are architecture specific anyway so shouldn't they be in some sort of
"lib64/plugins" directory? Note that plugins are not all app-specific, they can
also be shared because loaded by a library. Anyhow I'm not sure why we're
suddenly talking about plugins (and not executables, shared libs and
everything else that is part of actually installing applications - but that
doesn't typically happen in ~/.config, ~/.local or ~/.var anyway).
Post by Allison Lortie
Post by David Faure
And the question of "what is config and what is state" will pop up for sure
(I move a toolbar and Qt stores this as a binary blob, is that config or
state?). Config is user settings (etc. configuration dialogs) while state is
"other stuff apps want to save, which is not just a cache" ?
Indeed: I think the bigger problem for app authors will be deciding
between ~/.var/ vs. ~/.config/ but I think it is fairly easy to explain
that one.
Well, let's see how you explain it so it's un-ambiguous :-)
Post by Allison Lortie
Also: some people just don't care. A big part of this is
providing a nice place that is *not* ~/.config/ for people who can't be
bothered to split out their config from their state.
You mean, for apps that don't split config from state, your expectation is that
they will just move everything to ~/.var? What do we gain from that? And if
they don't bother, they also won't bother changing the current situation ;)
--
David Faure, ***@kde.org, http://www.davidfaure.fr
Working on KDE Frameworks 5
Markus Raab
2017-01-06 19:51:44 UTC
Permalink
Hi List,
Post by Allison Lortie
~/.var
Why ~/.var and not ~/.local/var? And why not saying that FHS applies to
~/.local? It simply would be the quaternary hierarchy for local data, specific
for this host and user.

best regards,
--
Markus Raab https://www.libelektra.org
Technische Universität Wien ***@markus-raab.org
Institut für Computersprachen Phone: (+431) 58801/185185
Argentinierstr. 8, 1040 Wien, Austria FAX: (+431) 58801/18598

DVR 0005886
Thomas Koch
2017-04-09 17:29:39 UTC
Permalink
The discussion about a STATE dir is at least 8 years old now:

https://wiki.debian.org/XDGBaseDirectorySpecification section "Proposal: STATE
directory" and linked mail threads in this list.

Please, give the world a standard dir in $HOME to save state!

I found this thread because stebalien@ had the same complaint on github:
"One thing I'm really not happy about is the spec's lack of an XDG_STATE_DIR."

https://github.com/syl20bnr/spacemacs/issues/3589

Never give up hope.

Thomas
Steven Allen
2017-04-10 22:00:50 UTC
Permalink
Actually, after reading that proposal, that's not exactly what I was
thinking. My complaint is that the current system mixes state (e.g.,
recentf, email, trash, etc.) with program data (icons, themes, fonts,
etc.) in XDG_DATA_HOME.

I ran across this issue because I need to store the spacemacs code,
spacemacs stat (recent file list, auto save files, etc.), and spacemacs
config (managed by the user). According to a strict reading of the spec,
the code could go in `XDG_CACHE_DIR` (it *can* be re-downloaded) but
that's mildly absurd (re-downloading/compiling is a non-trivial
operation). So, disregarding that option, I have a pigeonhole problem: I
have three things and two places to put them.

So, there really should be either:

1. A separate STATE dir for storing state:
/usr/{share,lib} -> XDG_DATA_DIR
/var/lib -> XDG_STATE_DIR (`~/.local/state`)
2. A separate LIB dir for storing "code" and "shared" data:
/usr/{share,lib} -> XDG_LIB_DIR

Some programs like python are solving this by putting program data in
`~/.local/lib` (option 2) but personally, I think option 1 is more
correct (and leaves icons, trash etc. where they are).

Loading...