diff --git a/README.md b/README.md index 9ccfb62..cf16c5a 100644 --- a/README.md +++ b/README.md @@ -207,6 +207,9 @@ func main() { // ConfigFile takes one parameter which must contain the name of the file, // but it can also contain a set of parent directories. If the directories // don't exist, they will be created relative to the base config directory. + // It is recommended for files to be saved inside an application directory + // relative to the base directory rather than directly inside the base + // directory (e.g. `appname/config.yaml` instead of `appname-config.yaml`). configFilePath, err := xdg.ConfigFile("appname/config.yaml") if err != nil { log.Fatal(err) diff --git a/base_dirs.go b/base_dirs.go index 0cdca02..65f3e3f 100644 --- a/base_dirs.go +++ b/base_dirs.go @@ -78,5 +78,5 @@ func (bd baseDirectories) searchCacheFile(relPath string) (string, error) { } func (bd baseDirectories) searchRuntimeFile(relPath string) (string, error) { - return pathutil.Search(relPath, []string{bd.runtime}) + return pathutil.Search(relPath, pathutil.Unique([]string{bd.runtime, os.TempDir()})) } diff --git a/doc.go b/doc.go index ddbaae4..22ba478 100644 --- a/doc.go +++ b/doc.go @@ -48,6 +48,9 @@ XDG Base Directory // ConfigFile takes one parameter which must contain the name of the file, // but it can also contain a set of parent directories. If the directories // don't exist, they will be created relative to the base config directory. + // It is recommended for files to be saved inside an application directory + // relative to the base directory rather than directly inside the base + // directory (e.g. `appname/config.yaml` instead of `appname-config.yaml`). configFilePath, err := xdg.ConfigFile("appname/config.yaml") if err != nil { log.Fatal(err) diff --git a/xdg.go b/xdg.go index 059d695..f4f1d4f 100644 --- a/xdg.go +++ b/xdg.go @@ -202,8 +202,11 @@ func SearchCacheFile(relPath string) (string, error) { // SearchRuntimeFile searches for the specified file in the runtime search path. // The relPath parameter must contain the name of the runtime file, and -// optionally, a set of parent directories (e.g. appname/app.pid). If the -// file cannot be found, an error specifying the searched path is returned. +// optionally, a set of parent directories (e.g. appname/app.pid). The runtime +// file is also searched in the operating system's temporary directory in order +// to cover cases in which the runtime base directory does not exist or is not +// accessible. If the file cannot be found, an error specifying the searched +// paths is returned. func SearchRuntimeFile(relPath string) (string, error) { return baseDirs.searchRuntimeFile(relPath) } diff --git a/xdg_test.go b/xdg_test.go index 53d0604..47b1392 100644 --- a/xdg_test.go +++ b/xdg_test.go @@ -202,6 +202,7 @@ func TestInvalidPaths(t *testing.T) { func TestNonExistentRuntimeDir(t *testing.T) { var ( + runtimeFiles = []string{"app.pid", "appname/app.pid"} envRuntimeDirVar = "XDG_RUNTIME_DIR" originalRuntimeDir = xdg.RuntimeDir nonExistentRuntimeDir = filepath.Join(xdg.Home, "runtime") @@ -212,7 +213,18 @@ func TestNonExistentRuntimeDir(t *testing.T) { xdg.Reload() require.Equal(t, nonExistentRuntimeDir, xdg.RuntimeDir) - p, err := xdg.RuntimeFile("app.pid") - require.NoError(t, err) - require.Equal(t, filepath.Clean(os.TempDir()), filepath.Dir(p)) + for _, runtimeFile := range runtimeFiles { + suggestedPath, err := xdg.RuntimeFile(runtimeFile) + require.NoError(t, err) + require.Equal(t, true, strings.HasPrefix(suggestedPath, os.TempDir())) + + f, err := os.Create(suggestedPath) + require.NoError(t, err) + require.NoError(t, f.Close()) + defer os.Remove(suggestedPath) + + foundPath, err := xdg.SearchRuntimeFile(runtimeFile) + require.NoError(t, err) + require.Equal(t, suggestedPath, foundPath) + } }