Skip to content

Commit

Permalink
move procs in os to appdirs
Browse files Browse the repository at this point in the history
  • Loading branch information
ringabout committed Oct 20, 2022
1 parent de5dce4 commit 2d19110
Show file tree
Hide file tree
Showing 2 changed files with 149 additions and 141 deletions.
144 changes: 3 additions & 141 deletions lib/pure/os.nim
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ export osdirs
import std/private/ossymlinks
export ossymlinks

import std/private/osappdirs
export osappdirs

import std/private/oscommon

include system/inclrtl
Expand Down Expand Up @@ -100,148 +103,7 @@ export envvars
import std/private/osseps
export osseps

proc getHomeDir*(): string {.rtl, extern: "nos$1",
tags: [ReadEnvEffect, ReadIOEffect].} =
## Returns the home directory of the current user.
##
## This proc is wrapped by the `expandTilde proc`_
## for the convenience of processing paths coming from user configuration files.
##
## See also:
## * `getConfigDir proc`_
## * `getTempDir proc`_
## * `expandTilde proc`_
## * `getCurrentDir proc`_
## * `setCurrentDir proc`_
runnableExamples:
assert getHomeDir() == expandTilde("~")

when defined(windows): return getEnv("USERPROFILE") & "\\"
else: return getEnv("HOME") & "/"

proc getConfigDir*(): string {.rtl, extern: "nos$1",
tags: [ReadEnvEffect, ReadIOEffect].} =
## Returns the config directory of the current user for applications.
##
## On non-Windows OSs, this proc conforms to the XDG Base Directory
## spec. Thus, this proc returns the value of the `XDG_CONFIG_HOME` environment
## variable if it is set, otherwise it returns the default configuration
## directory ("~/.config/").
##
## An OS-dependent trailing slash is always present at the end of the
## returned string: `\\` on Windows and `/` on all other OSs.
##
## See also:
## * `getHomeDir proc`_
## * `getTempDir proc`_
## * `expandTilde proc`_
## * `getCurrentDir proc`_
## * `setCurrentDir proc`_
when defined(windows):
result = getEnv("APPDATA")
else:
result = getEnv("XDG_CONFIG_HOME", getEnv("HOME") / ".config")
result.normalizePathEnd(trailingSep = true)

proc getCacheDir*(): string =
## Returns the cache directory of the current user for applications.
##
## This makes use of the following environment variables:
##
## * On Windows: `getEnv("LOCALAPPDATA")`
##
## * On macOS: `getEnv("XDG_CACHE_HOME", getEnv("HOME") / "Library/Caches")`
##
## * On other platforms: `getEnv("XDG_CACHE_HOME", getEnv("HOME") / ".cache")`
##
## **See also:**
## * `getHomeDir proc`_
## * `getTempDir proc`_
## * `getConfigDir proc`_
# follows https://crates.io/crates/platform-dirs
when defined(windows):
result = getEnv("LOCALAPPDATA")
elif defined(osx):
result = getEnv("XDG_CACHE_HOME", getEnv("HOME") / "Library/Caches")
else:
result = getEnv("XDG_CACHE_HOME", getEnv("HOME") / ".cache")
result.normalizePathEnd(false)

proc getCacheDir*(app: string): string =
## Returns the cache directory for an application `app`.
##
## * On Windows, this uses: `getCacheDir() / app / "cache"`
## * On other platforms, this uses: `getCacheDir() / app`
when defined(windows):
getCacheDir() / app / "cache"
else:
getCacheDir() / app


when defined(windows):
type DWORD = uint32

when defined(nimPreviewSlimSystem):
import std/widestrs

proc getTempPath(
nBufferLength: DWORD, lpBuffer: WideCString
): DWORD {.stdcall, dynlib: "kernel32.dll", importc: "GetTempPathW".} =
## Retrieves the path of the directory designated for temporary files.

template getEnvImpl(result: var string, tempDirList: openArray[string]) =
for dir in tempDirList:
if existsEnv(dir):
result = getEnv(dir)
break

template getTempDirImpl(result: var string) =
when defined(windows):
getEnvImpl(result, ["TMP", "TEMP", "USERPROFILE"])
else:
getEnvImpl(result, ["TMPDIR", "TEMP", "TMP", "TEMPDIR"])

proc getTempDir*(): string {.rtl, extern: "nos$1",
tags: [ReadEnvEffect, ReadIOEffect].} =
## Returns the temporary directory of the current user for applications to
## save temporary files in.
##
## On Windows, it calls [GetTempPath](https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppathw).
## On Posix based platforms, it will check `TMPDIR`, `TEMP`, `TMP` and `TEMPDIR` environment variables in order.
## On all platforms, `/tmp` will be returned if the procs fails.
##
## You can override this implementation
## by adding `-d:tempDir=mytempname` to your compiler invocation.
##
## **Note:** This proc does not check whether the returned path exists.
##
## See also:
## * `getHomeDir proc`_
## * `getConfigDir proc`_
## * `expandTilde proc`_
## * `getCurrentDir proc`_
## * `setCurrentDir proc`_
const tempDirDefault = "/tmp"
when defined(tempDir):
const tempDir {.strdefine.}: string = tempDirDefault
result = tempDir
else:
when nimvm:
getTempDirImpl(result)
else:
when defined(windows):
let size = getTempPath(0, nil)
# If the function fails, the return value is zero.
if size > 0:
let buffer = newWideCString(size.int)
if getTempPath(size, buffer) > 0:
result = $buffer
elif defined(android): result = "/data/local/tmp"
else:
getTempDirImpl(result)
if result.len == 0:
result = tempDirDefault
normalizePathEnd(result, trailingSep=true)

proc expandTilde*(path: string): string {.
tags: [ReadEnvEffect, ReadIOEffect].} =
Expand Down
146 changes: 146 additions & 0 deletions lib/std/private/osappdirs.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
include system/inclrtl
import std/envvars
import std/private/ospaths2

proc getHomeDir*(): string {.rtl, extern: "nos$1",
tags: [ReadEnvEffect, ReadIOEffect].} =
## Returns the home directory of the current user.
##
## This proc is wrapped by the `expandTilde proc`_
## for the convenience of processing paths coming from user configuration files.
##
## See also:
## * `getConfigDir proc`_
## * `getTempDir proc`_
## * `expandTilde proc`_
## * `getCurrentDir proc`_
## * `setCurrentDir proc`_
runnableExamples:
assert getHomeDir() == expandTilde("~")

when defined(windows): return getEnv("USERPROFILE") & "\\"
else: return getEnv("HOME") & "/"

proc getConfigDir*(): string {.rtl, extern: "nos$1",
tags: [ReadEnvEffect, ReadIOEffect].} =
## Returns the config directory of the current user for applications.
##
## On non-Windows OSs, this proc conforms to the XDG Base Directory
## spec. Thus, this proc returns the value of the `XDG_CONFIG_HOME` environment
## variable if it is set, otherwise it returns the default configuration
## directory ("~/.config/").
##
## An OS-dependent trailing slash is always present at the end of the
## returned string: `\\` on Windows and `/` on all other OSs.
##
## See also:
## * `getHomeDir proc`_
## * `getTempDir proc`_
## * `expandTilde proc`_
## * `getCurrentDir proc`_
## * `setCurrentDir proc`_
when defined(windows):
result = getEnv("APPDATA")
else:
result = getEnv("XDG_CONFIG_HOME", getEnv("HOME") / ".config")
result.normalizePathEnd(trailingSep = true)

proc getCacheDir*(): string =
## Returns the cache directory of the current user for applications.
##
## This makes use of the following environment variables:
##
## * On Windows: `getEnv("LOCALAPPDATA")`
##
## * On macOS: `getEnv("XDG_CACHE_HOME", getEnv("HOME") / "Library/Caches")`
##
## * On other platforms: `getEnv("XDG_CACHE_HOME", getEnv("HOME") / ".cache")`
##
## **See also:**
## * `getHomeDir proc`_
## * `getTempDir proc`_
## * `getConfigDir proc`_
# follows https://crates.io/crates/platform-dirs
when defined(windows):
result = getEnv("LOCALAPPDATA")
elif defined(osx):
result = getEnv("XDG_CACHE_HOME", getEnv("HOME") / "Library/Caches")
else:
result = getEnv("XDG_CACHE_HOME", getEnv("HOME") / ".cache")
result.normalizePathEnd(false)

proc getCacheDir*(app: string): string =
## Returns the cache directory for an application `app`.
##
## * On Windows, this uses: `getCacheDir() / app / "cache"`
## * On other platforms, this uses: `getCacheDir() / app`
when defined(windows):
getCacheDir() / app / "cache"
else:
getCacheDir() / app


when defined(windows):
type DWORD = uint32

when defined(nimPreviewSlimSystem):
import std/widestrs

proc getTempPath(
nBufferLength: DWORD, lpBuffer: WideCString
): DWORD {.stdcall, dynlib: "kernel32.dll", importc: "GetTempPathW".} =
## Retrieves the path of the directory designated for temporary files.

template getEnvImpl(result: var string, tempDirList: openArray[string]) =
for dir in tempDirList:
if existsEnv(dir):
result = getEnv(dir)
break

template getTempDirImpl(result: var string) =
when defined(windows):
getEnvImpl(result, ["TMP", "TEMP", "USERPROFILE"])
else:
getEnvImpl(result, ["TMPDIR", "TEMP", "TMP", "TEMPDIR"])

proc getTempDir*(): string {.rtl, extern: "nos$1",
tags: [ReadEnvEffect, ReadIOEffect].} =
## Returns the temporary directory of the current user for applications to
## save temporary files in.
##
## On Windows, it calls [GetTempPath](https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppathw).
## On Posix based platforms, it will check `TMPDIR`, `TEMP`, `TMP` and `TEMPDIR` environment variables in order.
## On all platforms, `/tmp` will be returned if the procs fails.
##
## You can override this implementation
## by adding `-d:tempDir=mytempname` to your compiler invocation.
##
## **Note:** This proc does not check whether the returned path exists.
##
## See also:
## * `getHomeDir proc`_
## * `getConfigDir proc`_
## * `expandTilde proc`_
## * `getCurrentDir proc`_
## * `setCurrentDir proc`_
const tempDirDefault = "/tmp"
when defined(tempDir):
const tempDir {.strdefine.}: string = tempDirDefault
result = tempDir
else:
when nimvm:
getTempDirImpl(result)
else:
when defined(windows):
let size = getTempPath(0, nil)
# If the function fails, the return value is zero.
if size > 0:
let buffer = newWideCString(size.int)
if getTempPath(size, buffer) > 0:
result = $buffer
elif defined(android): result = "/data/local/tmp"
else:
getTempDirImpl(result)
if result.len == 0:
result = tempDirDefault
normalizePathEnd(result, trailingSep=true)

0 comments on commit 2d19110

Please sign in to comment.