Skip to content

Conversation

@hubertwas
Copy link
Contributor

I changed the directory where built files are stored for the interpreter from $HOME to $XDG_CACHE_HOME according to the XDG specification. Solves #663

home <- getHomeDirectory
return (joinPath home kkbuild)
-- instead use `$XDG_CACHE_HOME/koka` if in the interpreter
getXdgDirectory XdgCache "koka"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think "koka" should be kkbuild here as that includes the koka version and hash (as we cannot mix object and kki files across compiler versions and certain settings).

Is it ensured (well, somewhat implied would be enough) that XdgCache has execute permission?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hadn't thought of that, I don't see any guarantee in the spec. To fix it I propose:

  1. The directory from $KOKA_ROOT is used
  2. If the env variable doesn't exist, it falls back to XdgCache
  3. If XdgCache doesn't have executable privileges, $HOME is used.

Would that be fine?

@TimWhiting
Copy link
Collaborator

TimWhiting commented Jul 19, 2025

It looks like from the list here: https://wiki.archlinux.org/title/XDG_Base_Directory, that most programming languages are migrating to using something like or $KOKA_ROOT with a fallback on XDG_DATA_DIR. Including Haskell.

Previously, the interpreter stored built files in the $HOME directory of
the user. To conform to the XDG specification this was changed to $XDG_CACHE_HOME
@hubertwas hubertwas force-pushed the push-yvmpormttzsz branch from 6486ce0 to 3b63abc Compare July 20, 2025 09:21
If $KOKA_ROOT exists but is "", we probably still want to treat it as if
it didn't exists, because it's a degenerate value, that users
often use to clear out an environment variable.
@hubertwas
Copy link
Contributor Author

It looks like from the list here: https://wiki.archlinux.org/title/XDG_Base_Directory, that most programming languages are migrating to using something like or $KOKA_ROOT with a fallback on XDG_DATA_DIR. Including Haskell.

Implemented as suggested.

@TimWhiting
Copy link
Collaborator

Use the kkbuild var instead of a string

@daanx
Copy link
Member

daanx commented Jul 20, 2025

It is important to get this right. To me it is unclear what getXdgDirectory XdgData kkbuild returns if no XDG environment variables are set? What is returned if XDG_DATA_HOME is set? Also, @TimWhiting , I do not see XDG_DATA_DIR -- just XDG_DATA_DIRS (should we pick the first one?) or XDG_DATA_HOME ? What should we do if the returned getXdgDirectory XdgData kkbuild does not exist -- should we create it or use the getHomeDirectory / kkbuild ?

Maybe we should check the environment variables explicitly and still use the current solution if none of these are set? (as on Windows for example). Maybe we should explicitly check the directory for execute permission and issue a warning if we can't execute there.

@TimWhiting
Copy link
Collaborator

TimWhiting commented Jul 20, 2025

Agreed, this needs to be correct & tested before merging. @kyepskee if you don't have access to a machine for each Windows/MacOS/Linux, let us know and we can test it out. It seems Haskell only differentiates between Windows/Posix, so just two would be enough for this probably.

Yeah, I meant XDG_DATA_HOME.

The Haskell Docs don't explicitly say that there is a guarantee of returning a directory in all cases. But it does mention default paths for both Windows and Posix.
https://hackage.haskell.org/package/directory-1.3.9.0/docs/System-Directory.html

Looking closer at the code it seems to always give it the default fallback. .local/share / %APPDATA%.
Windows: https://github.com/haskell/directory/blob/master/System/Directory/Internal/Windows.hsc
Posix: https://github.com/haskell/directory/blob/master/System/Directory/Internal/Posix.hsc

We should also add "koka" to the path prior to kkbuild to keep things contained relative to other apps. I'm assuming we recursively create the kkbuild directory when building the files, so creating the directory should not be necessary, but correct me if I'm wrong.

It is mentioned that this directory should be created with permissions 700 to only let the current user access it.

Maybe we should check the environment variables explicitly and still use the current solution if none of these are set? (as on Windows for example). Maybe we should explicitly check the directory for execute permission and issue a warning if we can't execute there.

That's also a valid solution. Given the above which would you rather do?

@hubertwas
Copy link
Contributor Author

Use the kkbuild var instead of a string

I kind of don't like using a hidden directory there for no good reason.

What should we do if the returned getXdgDirectory XdgData kkbuild does not exist -- should we create it or use the getHomeDirectory / kkbuild ?

Do you mean if $XDG_DATA_HOME doesn't exist? I think it basically has to exist if the user's system is functioning, it might even be better to throw an exception. If we don't want to do that then we should fall back to $HOME.

I suggest we

  1. Check $KOKA_ROOT and use that. Create it if it doesn't exist.
  2. If 1. is impossible, issue a warning and fall back to getXdgDirectory XdgData "koka" / kkbuild. Create it if it doesn't exist.
  3. If 2. is impossible, issue a warning and fall back to $HOME / kkbuild.
  4. If 3. is impossible, throw an exception.

By impossible, I mean we cannot create directories with sufficient privileges.

Agreed, this needs to be correct & tested before merging. @kyepskee if you don't have access to a machine for each Windows/MacOS/Linux,

I can test it on Linux only. Should I also add some tests? I don't know how I would make those honestly.

Also, it would be simpler to skip XdgData and just add the $KOKA_ROOT var, but that's a bit worse.

@TimWhiting
Copy link
Collaborator

TimWhiting commented Jul 20, 2025

Use the kkbuild var instead of a string

I kind of don't like using a hidden directory there for no good reason.

Sorry, I didn't check closely - I was thinking it was the full build-directory (i.e. with the compiler version / hash) due to a previous comment from Daan on this PR, but this is just for the top-level build folder. kkbuild == ".koka".

I agree that since XdgData is already typically in a hidden directory, we don't need to nest another hidden, I think just "koka" is fine there (no kkbuild), if Daan is okay with that.

However, for the fallback on $HOME I would say we should definitely make that hidden (i.e. use kkbuild).

I can test it on Linux only. Should I also add some tests? I don't know how I would make those honestly.

We unfortunately don't have these kinds of tests yet. I think some manual testing for this should be fine.

Also, it would be simpler to skip XdgData and just add the $KOKA_ROOT var, but that's a bit worse.

The original issue is to conform to XDG specifications which I think is generally useful and expected, and what most languages are migrating towards. I see no reason to not make both changes.

@hubertwas
Copy link
Contributor Author

I've added checks for existence and executability of $XDG_DATA_HOME falling back to $HOME, although I think those are pathological cases and shouldn't even be checked probably. I've decided against creating directories inside getKokaBuildDir in the end. The algorithm is:

  1. if $KOKA_ROOT exists, return it.
  2. if it doesn't, return $XDG_DATA_HOME/koka if $XDG_DATA_HOME exists and is executable.
  3. if 2. doesn't happen issue a warning and fall back to $HOME.

I've checked all three of these paths on Linux.

This means that the directory won't have permissions 700 as that is not strictly required. Implementing it would require doing conditional compilation and checking the host OS (it requires System.Posix.Files) Should I add that?

@TimWhiting TimWhiting force-pushed the dev branch 3 times, most recently from 2c83d90 to 00399ab Compare August 13, 2025 15:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants