How do you handle your resource paths?

Hello everyone,
I wanted to ask this here to make good use of people’s prod experience, as most of my projects are hobby programs. I have a program that loads data from a path. And I would like for that program to support different install hierarchies e.g. “portable” with everything under one dir, or part of a system, where the packager decides where everything should be.

How do you usually approach resource resolution?

I can think of a couple approaches:

  • store permutations of where the file could be; /share/..., /usr/share/..., ~/.local/share/... which seems like the worst idea in general
  • make paths build-time params; interface with dune somehow to have it fill templates in your code upon dune install is one way of doing this.
  • make paths runtime params provided in environment and via flags
  • some mix of the above

Then there’s also the consideration for how to express those paths across windows/unix-likes with their different filesystem quirks

package maintainer insight is especially appreciated!

1 Like

Have you seen directories? I think this library fits your use-case pretty well.

3 Likes

Dune has a mechanism for that kind of file that you’d want to install and then load in your application after installation, via the `sites’ notion : How to load additional files at runtime — dune documentation

3 Likes

dune sites look brilliant! They’re like option 2 but way nicer and more automated. Impressive

That’s one useful library. Especially seeing how they handle windows and macos. Starred ^^

In order to make odig and omod relocatable I simply use environment variables which when unspecified default to standard unix directories resolved relative to the executable path (you can also specify them explicitely on the cli).

The latter can be brittle to determine but Sys.executable_name does a reasonably good job at trying to do that for you and seems to work reasonably well in practice.

For example here’s the configuration interface and implementation of omod.

If the data you need to store exists in one of the XDG defined directories you should definitively use the convention which is easy to implement yourself.

I would personally avoid using that directories library for unix cli tools since it doesn’t store stuff on macOS where you would expect unix tooling to store stuff; it’s right for double-clickable end-user apps though.

5 Likes

If the data you need to store exists in one of the XDG defined directories you should definitively use the convention which is easy to implement yourself.

On Windows, I wouldn’t say it is easy, you have to write C bindings to use the SHGetKnownFolderPath function, which is to my knownledge the only way to access the user’s settings.

I would personally avoid using that directories library for unix cli tools since it doesn’t store stuff on macOS where you would expect unix tooling to store stuff; it’s right for double-clickable end-user apps though.

On macOS, it follows apple’s Standard Directories guidelines. You may not expect this but other people may.

Actually in the future, I plan to change the API a little bit to provide a list of path instead of a single one. Thus it’ll support you use case of having linux paths on macOS but only when the application tries to read your files. When the application decides where to write files, the apple’s guidelines will still come first.

For a double clickable app that’s totally what I would expect. But for unix cli tooling, absolutely none of the ones I use does that on macOS for configuration – so I’m not sure why anyone would expect that.

Besides macos’ Library directory is an inconvenient mess for editing configuration files by hand. Not to mention synchronizing them over different unix machines.