Search code examples
elixircross-platform

How Can I Find Default User Directories in Elixir


In many programming languages, there is a library call (part of the base packages or an external module) to locate the user's home directory, the documents directory, the configuration directory, and so forth, that isn't platform-specific. As an example of one that I've used recently for another language, Rust has "dirs." Is there an Elixir equivalent?

For example, I run a server on my local machine to handle some tasks, and recently wrote a client for it---a simple console application that sends a TCP request and gets a response---in Elixir. I would like to pull the port number from the existing configuration file, if the file exists, so that the value isn't hard-coded. I could do something like this, of course.

Path.join(System.user_home!(), ".config")

I guess System.user_home() is a start, itself, but not really sufficient. It'll fail miserably on a Windows machine, for example.

Searching the web turned up examples in plenty of non-Elixir languages, ways to search the current directory for a file in Elixir, and how to get the most out of the config directory in a Phoenix project, but nothing that I could see for just getting the configuration (or a similar) directory.

So, assuming that this has been done before (and I have to assume it has been, given how established Elixir has become), what's the current method for retrieving the user's configuration folder?


Solution

  • Not fully Elixir, but there is Erlang functions for that - filename:basedir/{2,3}

    This function take the type of the directory as a first argument, which is one of the following atoms:

    • user_cache
    • user_config
    • user_data
    • user_log
    • site_config
    • site_data

    And application name (also as atom) as a second argument.

    Third argument may be a map containing:

    • os - OS type used for the paths creation, there are 3 recognisable values - windows, darwin (macOS), and linux (which will use XDG Base Directory Spec). Any other value will be treated as linux. If not provided, then OS is automatically detected by os:type/0 call.
    • author - used only on Windows
    • version - used only on Windows