Usage
Summary
This library works by resolving a few key directories and saving the results to variables, namely:
- Data,
DATA_HOMEandDATA_DIRS - Config, with
CONFIG_HOMEandCONFIG_DIRS - Executables, with
BIN_HOME - State data, with
STATE_HOME - Cached data, with
CACHE_HOME - Runtime data, with
RUNTIME_DIR
While it is possible to use these variables directly, it is recommended that you make use of the accessor functions instead, which all follow this pattern:
accessor() # Give the base directory(ies)
accessor(parts...) # Give the base directory(ies) joined with parts
accessor(proj::Project) # Give the base directory(ies) for proj
accessors(proj::Project, parts...) # proj directory(ies) joined with partsWhere accessor is a stand-in for the particular named directory being resolved. Two boolean keyword arguments are often supported:
create, to create the path when it does not exist. This is different to simply piping the returned path intomkpathin that it: a. Takes care to create the base directory with the appropriate mode (700) b. Creates the directory component of the path with the default mode (usually755) c. If the path is to a file (i.e. the path does not end with/),touches the file.existent, to filter the list of provided paths to ones that exist (when applicable)
To give appropriate project-specific directories we can use a BaseDirs.Project:
BaseDirs.Project — Type ProjectA representation of a "Project", namely the essential components of naming information used to produce platform-appropriate project paths.
Project(name::Union{AbstractString, Module};
org::AbstractString="julia", qualifier::AbstractString="lang")The information needed, and the platforms that make use of it, are as follows:
name, the name of the project (Linux, MacOS, Windows)org("julia"), the organisation the project belongs to (MacOS, Windows)qualifier("org"), the nature of the organisation, usually a TLD (MacOS)
The resulting "project path components" take one of the following forms:
| Platform | Project path form |
|---|---|
| Linux | "$org/$name" |
| MacOS | "$qualifier.$org.$name" |
| Windows | "$org\$name" |
The user and system forms of the various accessor functions are split into the User and System modules, with combined accessors in the XDG namespace. This essentially creates a tree of accessor functions:
- User
dataconfigbinstatecacheruntimefontsapplications
- System
dataconfigfontsapplications
dataconfigfontsapplications
The User submodule also provides a number of other "user folder" accessors, namely:
desktopdownloadsdocumentsmusicpicturesvideostemplatespublic
Example usage
julia> using BaseDirs
julia> BaseDirs.CONFIG_HOME
"/home/tec/.config"
julia> BaseDirs.User.config()
"/home/tec/.config"
julia> BaseDirs.User.config("sub", "dir/")
"/home/tec/.config/sub/dir/"
julia> BaseDirs.User.config(BaseDirs.Project("mything"), "config.conf", create=true)
"/home/tec/.config/mything/config.conf"Variables
While listed for reference, these variables are not part of the public API.
Base directories
BaseDirs.DATA_HOME — ConstantDATA_HOME (XDG_DATA_HOME)
The single base directory relative to which user-specific data files should be written.
Default values
| Linux | MacOS | Windows |
|---|---|---|
~/.local/share | ~/Library/ApplicationSupport | RoamingAppData |
BaseDirs.DATA_DIRS — ConstantDATA_DIRS (XDG_DATA_DIRS)
The set of preference ordered base directories relative to which data files should be searched.
Default values
| Linux | MacOS | Windows |
|---|---|---|
/usr/local/share | /Library/ApplicationSupport | ProgramData |
/usr/share |
BaseDirs.CONFIG_HOME — ConstantCONFIG_HOME (XDG_CONFIG_HOME)
The single base directory relative to which user-specific configuration files should be written.
Default values
| Linux | MacOS | Windows |
|---|---|---|
~/.local/config | ~/Library/ApplicationSupport | RoamingAppData |
BaseDirs.CONFIG_DIRS — ConstantCONFIG_DIRS (XDG_CONFIG_DIRS)
The set of preference ordered base directories relative to which data files should be searched.
Default values
| Linux | MacOS | Windows |
|---|---|---|
/etc/xdg | /Library/ApplicationSupport | ProgramData |
BaseDirs.BIN_HOME — ConstantBIN_HOME (XDG_BIN_HOME)
The single base directory relative to which user-specific executables should be written.
Default values
| Linux | MacOS* | Windows* |
|---|---|---|
~/.local/bin | ~/.local/bin | \bin |
/opt/local/bin | RoamingAppData\bin | |
/usr/local/bin | AppData\bin | |
| current working dir |
* The first of these directories that exists is used.
This is not yet standardised by the XDG, see freedesktop.org/xdg-specs#14 for more information.
BaseDirs.STATE_HOME — ConstantSTATE_HOME (XDG_STATE_HOME)
The single base directory relative to which user-specific state data should be written.
This should contain state data that should persist between (application) restarts, but that is not important or portable enough to the user that it should be stored in DATA_HOME. It may contain:
- actions history (logs, history, recently used files, …)
- current state of the application that can be reused on a restart (view, layout, open files, undo history, …)
Default values
| Linux | MacOS | Windows |
|---|---|---|
~/.local/state | ~/Library/ApplicationSupport | LocalAppData |
BaseDirs.CACHE_HOME — ConstantCACHE_HOME (XDG_CACHE_HOME)
The single base directory relative to which user-specific non-essential (cached) data should be written.
Default values
| Linux | MacOS | Windows |
|---|---|---|
~/.cache | ~/Library/Caches | LocalAppData\cache |
BaseDirs.RUNTIME_DIR — ConstantRUNTIME_DIR (XDG_RUNTIME_DIR)
The single base directory relative to which user-specific runtime files and other file objects should be placed. . Applications should use this directory for communication and synchronization purposes and should not place larger files in it.
Default values
| Linux | MacOS | Windows |
|---|---|---|
/run/user/$UID | ~/Library/ApplicationSupport | LocalAppData |
User directories
BaseDirs.DESKTOP_DIR — ConstantDESKTOP_DIR (XDG_DESKTOP_DIR)
The user's desktop directory.
BaseDirs.DOWNLOAD_DIR — ConstantDOWNLOAD_DIR (XDG_DOWNLOAD_DIR)
The user's downloads directory.
BaseDirs.DOCUMENTS_DIR — ConstantDOCUMENTS_DIR (XDG_DOCUMENTS_DIR)
The user's documents directory.
BaseDirs.PICTURES_DIR — ConstantPICTURES_DIR (XDG_PICTURES_DIR)
The user's pictures directory.
BaseDirs.VIDEOS_DIR — ConstantVIDEOS_DIR (XDG_VIDEOS_DIR)
The user's videos directory.
BaseDirs.TEMPLATES_DIR — ConstantTEMPLATES_DIR (XDG_TEMPLATES_DIR)
The user's templates directory.
BaseDirs.PUBLICSHARE_DIR — ConstantPUBLICSHARE_DIR (XDG_PUBLICSHARE_DIR)
The user's public directory.
Other directories
BaseDirs.APPLICATIONS_DIRS — ConstantAPPLICATIONS_DIRS
A list of locations in which application files may be found/placed.
BaseDirs.FONTS_DIRS — ConstantFONTS_DIRS
A list of locations in which font files may be found.
Functions
User
BaseDirs.User — ModuleBaseDirs.User
This module containes accessor functions for user-specific directories.
Base directory accessors
The functions data, config, state, cache, and runtime produce a String.
User directory accessors
The functions desktop, downloads, music, videos, templates, public produce a String.
Other accessors
The functions fonts and applications produce a Vector{String}.
Unlike the System and "combined" (BaseDirs.*) accessors, the Base and User accessors here return a single directory (String).
BaseDirs.User.data — Functiondata(; create) -> String # the user configuration directory
data([mod::Module or proj::Project], parts...; create) # a [project-specific] user configuration pathLocate the user configuration directory, or a path within it.
A project or module can be optionally provided as the first argument, in which case the returned path is scoped to the project or module.
The returned path is determined by the value of BaseDirs.DATA_HOME, which see.
Keyword arguments
create::Bool(defaultfalse), whether the path should be created if it does not exist. Paths ending in/are interpreted as directories, and all other paths are considered files. This takes care to create the base directories with the appropriate permissions (700).
BaseDirs.User.config — Functionconfig(; create) -> String # the user configuration directory
config([mod::Module or proj::Project], parts...; create) # a [project-specific] user configuration pathLocate the user configuration directory, or a path within it.
A project or module can be optionally provided as the first argument, in which case the returned path is scoped to the project or module.
The returned path is determined by the value of BaseDirs.CONFIG_HOME, which see.
Keyword arguments
create::Bool(defaultfalse), whether the path should be created if it does not exist. Paths ending in/are interpreted as directories, and all other paths are considered files. This takes care to create the base directories with the appropriate permissions (700).
BaseDirs.User.bin — Functionbin(; create) -> String # the executables directory
bin([mod::Module or proj::Project], parts...; create) # a [project-specific] executables pathLocate the executables directory, or a path within it.
A project or module can be optionally provided as the first argument, in which case the returned path is scoped to the project or module.
The returned path is determined by the value of BaseDirs.BIN_HOME, which see.
Keyword arguments
create::Bool(defaultfalse), whether the path should be created if it does not exist. Paths ending in/are interpreted as directories, and all other paths are considered files. This takes care to create the base directories with the appropriate permissions (700).
When create is true and the path referrs to a file, chmod is called to ensure that all users who can read the file can execute it.
BaseDirs.User.state — Functionstate(; create) -> String # the state data directory
state([mod::Module or proj::Project], parts...; create) # a [project-specific] state data pathLocate the state data directory, or a path within it.
A project or module can be optionally provided as the first argument, in which case the returned path is scoped to the project or module.
The returned path is determined by the value of BaseDirs.STATE_HOME, which see.
Keyword arguments
create::Bool(defaultfalse), whether the path should be created if it does not exist. Paths ending in/are interpreted as directories, and all other paths are considered files. This takes care to create the base directories with the appropriate permissions (700).
BaseDirs.User.cache — Functioncache(; create) -> String # the cached data directory
cache([mod::Module or proj::Project], parts...; create) # a [project-specific] cached data pathLocate the cached data directory, or a path within it.
A project or module can be optionally provided as the first argument, in which case the returned path is scoped to the project or module.
The returned path is determined by the value of BaseDirs.CACHE_HOME, which see.
Keyword arguments
create::Bool(defaultfalse), whether the path should be created if it does not exist. Paths ending in/are interpreted as directories, and all other paths are considered files. This takes care to create the base directories with the appropriate permissions (700).
BaseDirs.User.runtime — Functionstate(; create) -> String # the runtime information directory
state([mod::Module or proj::Project], parts...; create) # a [project-specific] runtime information pathLocate the runtime information directory, or a path within it.
A project or module can be optionally provided as the first argument, in which case the returned path is scoped to the project or module.
The returned path is determined by the value of BaseDirs.STATE_HOME, which see.
Keyword arguments
create::Bool(defaultfalse), whether the path should be created if it does not exist. Paths ending in/are interpreted as directories, and all other paths are considered files. This takes care to create the base directories with the appropriate permissions (700).
BaseDirs.User.desktop — Functiondesktop(parts...) -> StringJoin the desktop directory with zero or more path components (parts).
The desktop directory is based on the variable BaseDirs.DESKTOP_DIR, which see.
BaseDirs.User.downloads — Functiondownloads(parts...) -> StringJoin the downloads directory with zero or more path components (parts).
The downloads directory is based on the variable BaseDirs.DOWNLOADS_DIR, which see.
BaseDirs.User.documents — Functiondocuments(parts...) -> StringJoin the documents directory with zero or more path components (parts).
The documents directory is based on the variable BaseDirs.DOCUMENTS_DIR, which see.
BaseDirs.User.music — Functionmusic(parts...) -> StringJoin the music directory with zero or more path components (parts).
The music directory is based on the variable BaseDirs.MUSIC_DIR, which see.
BaseDirs.User.pictures — Functionpictures(parts...) -> StringJoin the pictures directory with zero or more path components (parts).
The pictures directory is based on the variable BaseDirs.PICTURES_DIR, which see.
BaseDirs.User.videos — Functionvideos(parts...) -> StringJoin the videos directory with zero or more path components (parts).
The videos directory is based on the variable BaseDirs.VIDEOS_DIR, which see.
BaseDirs.User.templates — Functiontemplates(parts...) -> StringJoin the templates directory with zero or more path components (parts).
The templates directory is based on the variable BaseDirs.TEMPLATES_DIR, which see.
BaseDirs.User.public — Functionpublic(parts...) -> StringJoin the public directory with zero or more path components (parts).
The public directory is based on the variable BaseDirs.PUBLIC_DIR, which see.
BaseDirs.User.fonts — Functionfonts(; create, existent) -> Vector{String} # all user fonts directories
fonts([mod::Module or proj::Project], parts...; create, existent) # a [project-specific] user fonts pathLocate all user fonts directories, or a path within it.
A project or module can be optionally provided as the first argument, in which case the returned path is scoped to the project or module.
Keyword arguments
create::Bool(defaultfalse), whether the path should be created if it does not exist. Paths ending in/are interpreted as directories, and all other paths are considered files. This takes care to create the base directories with the appropriate permissions (700).existent::Bool(defaultfalse), filter out paths that do not exist.
BaseDirs.User.applications — Functionapplications(; create, existent) -> Vector{String} # all user applications directories
applications([mod::Module or proj::Project], parts...; create, existent) # a [project-specific] user applications pathLocate all user applications directories, or a path within it.
A project or module can be optionally provided as the first argument, in which case the returned path is scoped to the project or module.
Keyword arguments
create::Bool(defaultfalse), whether the path should be created if it does not exist. Paths ending in/are interpreted as directories, and all other paths are considered files. This takes care to create the base directories with the appropriate permissions (700).existent::Bool(defaultfalse), filter out paths that do not exist.
System
BaseDirs.System — ModuleBaseDirs.System
This module contains accessor functions for system directories.
Base directory accessors
The functions data and config produce a Vector{String}.
Other accessors
The functions fonts and applications produce a Vector{String}.
See also: BaseDirs.User.
BaseDirs.System.data — Functiondata(; create, existent) -> Vector{String} # all system configuration directories
data([mod::Module or proj::Project], parts...; create, existent) # a [project-specific] system configuration pathLocate all system configuration directories, or a path within it.
A project or module can be optionally provided as the first argument, in which case the returned path is scoped to the project or module.
The returned path is determined by the value of BaseDirs.DATA_DIRS, which see.
Keyword arguments
create::Bool(defaultfalse), whether the path should be created if it does not exist. Paths ending in/are interpreted as directories, and all other paths are considered files. This takes care to create the base directories with the appropriate permissions (700).existent::Bool(defaultfalse), filter out paths that do not exist.
BaseDirs.System.config — Functionconfig(; create, existent) -> Vector{String} # all system configuration directories
config([mod::Module or proj::Project], parts...; create, existent) # a [project-specific] system configuration pathLocate all system configuration directories, or a path within it.
A project or module can be optionally provided as the first argument, in which case the returned path is scoped to the project or module.
The returned path is determined by the value of BaseDirs.CONFIG_DIRS, which see.
Keyword arguments
create::Bool(defaultfalse), whether the path should be created if it does not exist. Paths ending in/are interpreted as directories, and all other paths are considered files. This takes care to create the base directories with the appropriate permissions (700).existent::Bool(defaultfalse), filter out paths that do not exist.
BaseDirs.System.fonts — Functionfonts(; create, existent) -> Vector{String} # all system fonts directories
fonts([mod::Module or proj::Project], parts...; create, existent) # a [project-specific] system fonts pathLocate all system fonts directories, or a path within it.
A project or module can be optionally provided as the first argument, in which case the returned path is scoped to the project or module.
Keyword arguments
create::Bool(defaultfalse), whether the path should be created if it does not exist. Paths ending in/are interpreted as directories, and all other paths are considered files. This takes care to create the base directories with the appropriate permissions (700).existent::Bool(defaultfalse), filter out paths that do not exist.
BaseDirs.System.applications — Functionapplications(; create, existent) -> Vector{String} # all system applications directories
applications([mod::Module or proj::Project], parts...; create, existent) # a [project-specific] system applications pathLocate all system applications directories, or a path within it.
A project or module can be optionally provided as the first argument, in which case the returned path is scoped to the project or module.
Keyword arguments
create::Bool(defaultfalse), whether the path should be created if it does not exist. Paths ending in/are interpreted as directories, and all other paths are considered files. This takes care to create the base directories with the appropriate permissions (700).existent::Bool(defaultfalse), filter out paths that do not exist.
Combined
BaseDirs.data — Functiondata(; create, existent) -> Vector{String} # all user and system configuration directories
data([mod::Module or proj::Project], parts...; create, existent) # a [project-specific] user and system configuration pathLocate all user and system configuration directories, or a path within it.
A project or module can be optionally provided as the first argument, in which case the returned path is scoped to the project or module.
The returned path is determined by the value of BaseDirs.DATA_HOME, and BaseDirs.DATA_DIRS, which see.
Keyword arguments
create::Bool(defaultfalse), whether the path should be created if it does not exist. Paths ending in/are interpreted as directories, and all other paths are considered files. This takes care to create the base directories with the appropriate permissions (700).existent::Bool(defaultfalse), filter out paths that do not exist.
BaseDirs.config — Functionconfig(; create, existent) -> Vector{String} # all user and system configuration directories
config([mod::Module or proj::Project], parts...; create, existent) # a [project-specific] user and system configuration pathLocate all user and system configuration directories, or a path within it.
A project or module can be optionally provided as the first argument, in which case the returned path is scoped to the project or module.
The returned path is determined by the value of BaseDirs.CONFIG_HOME, and BaseDirs.CONFIG_DIRS, which see.
Keyword arguments
create::Bool(defaultfalse), whether the path should be created if it does not exist. Paths ending in/are interpreted as directories, and all other paths are considered files. This takes care to create the base directories with the appropriate permissions (700).existent::Bool(defaultfalse), filter out paths that do not exist.
BaseDirs.fonts — Functionfonts(; create, existent) -> Vector{String} # all user and system fonts directories
fonts([mod::Module or proj::Project], parts...; create, existent) # a [project-specific] user and system fonts pathLocate all user and system fonts directories, or a path within it.
A project or module can be optionally provided as the first argument, in which case the returned path is scoped to the project or module.
Keyword arguments
create::Bool(defaultfalse), whether the path should be created if it does not exist. Paths ending in/are interpreted as directories, and all other paths are considered files. This takes care to create the base directories with the appropriate permissions (700).existent::Bool(defaultfalse), filter out paths that do not exist.
BaseDirs.applications — Functionapplications(; create, existent) -> Vector{String} # all user and system applications directories
applications([mod::Module or proj::Project], parts...; create, existent) # a [project-specific] user and system applications pathLocate all user and system applications directories, or a path within it.
A project or module can be optionally provided as the first argument, in which case the returned path is scoped to the project or module.
Keyword arguments
create::Bool(defaultfalse), whether the path should be created if it does not exist. Paths ending in/are interpreted as directories, and all other paths are considered files. This takes care to create the base directories with the appropriate permissions (700).existent::Bool(defaultfalse), filter out paths that do not exist.
Precompilation
Since these directories are resolved using runtime information, as tempting and easy as it may be to include a snippet like this in your package:
const MY_CACHE = BaseDirs.User.cache(BaseDirs.Project("MyPkg"))When this is evaluated during precompilation, it "bakes in" the runtime environment at that particular point in time, making the result potentially invalid in the future (and no longer relocatable).
In response to this risk, BaseDirs aggressively warns when calls that use runtime information are evaluated during precompilation. Excpect to see a message like this in response to any potential misuse:
┌ Warning: A base directory is being computed during precompilation.
│ This is dangerous, as results depend on the live system configuration.
│
│ It is recommended that you invoke BaseDirs as required in
│ function bodies, rather than at the top level. Calls are very
│ cheap, and you can always pass the result of a live call around.
│
│ If you have verified that this call was not assigned to a global constant,
│ you can silence this warning with BaseDirs.@promise_no_assign.
└ @ BaseDirs ~/.julia/dev/MyPkg/src/MyPkg.jl:42Note that the path displayed at the end of the warning (~/.julia/dev/MyPkg/src/MyPkg.jl:42 in the example) identifies the suspicious callsite in MyPkg, rather than the line within BaseDirs that produces the warning. If you've checked how this call occurs and verified it's unfounded, you can suppress spurious warnings by wrapping the parent call in the precompilation workload with @promise_no_assign.
BaseDirs.@promise_no_assign — Macro@promise_no_assign exprEvaluate expr, while promising that none of the results of BaseDirs will be assigned to any global constants.
This macro is intended for use in other package's precompilation scripts, to suppress the spurious warnings about global constant assignments. It will itself warn when used outside precompilation.
Examples
Within a precompilation workload:
BaseDirs.@promise_no_assign MyPkg.somecall()Alternatively, you could mark a larger block as safe with begin ... end:
BaseDirs.@promise_no_assign begin
...
MyPkg.somecall()
...
end