-
-
Notifications
You must be signed in to change notification settings - Fork 54
/
os.clj
80 lines (71 loc) · 2.96 KB
/
os.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
(ns orchard.util.os
"Operating system specific utilities.
This is a port of BaseDirectories.java in soc/directories-jvm.
https://github.com/soc/directories-jvm"
{:author "Masashi Iizuka"
:added "0.5"}
(:require [clojure.java.io :as io]
[clojure.string :as str])
(:import (java.io BufferedReader)))
(def os-name
(str/lower-case (System/getProperty "os.name")))
(def os-type
(condp #(str/includes? %2 %1) os-name
"linux" ::linux
"mac" ::mac
"windows" ::windows
"bsd" ::bsd
::not-supported))
(def file-separator (System/getProperty "file.separator"))
(defn- run-commands
[expected-result-lines commands]
(let [commands ^"[Ljava.lang.String;" (into-array String commands)
builder (ProcessBuilder. commands)
process (.start builder)]
(with-open [reader ^BufferedReader (io/reader (.getInputStream process))]
(try
(doall (repeatedly expected-result-lines #(.readLine reader)))
(finally
(.destroy process))))))
(defn- get-win-dirs
[guids]
(let [commands (concat ["& {"
"[Console]::OutputEncoding = [System.Text.Encoding]::UTF8"
"Add-Type @\\\""
"using System;"
"using System.Runtime.InteropServices;"
"public class Dir {"
" [DllImport(\\\"shell32.dll\\\")]"
" private static extern int SHGetKnownFolderPath([MarshalAs(UnmanagedType.LPStruct)] Guid rfid, uint dwFlags, IntPtr hToken, out IntPtr pszPath);"
" public static string GetKnownFolderPath(string rfid) {"
" IntPtr pszPath;"
" if (SHGetKnownFolderPath(new Guid(rfid), 0, IntPtr.Zero, out pszPath) != 0) return \\\"\\\";"
" string path = Marshal.PtrToStringUni(pszPath);"
" Marshal.FreeCoTaskMem(pszPath);"
" return path;"
" }"
"}"
"\\\"@"]
(map #(str "[Dir]::GetKnownFolderPath(\\\"" % "\\\")") guids)
["}"])]
(run-commands (count guids) ["powershell.exe" "-Command" (str/join "\n" commands)])))
(defn cache-dir
"Returns the path to the user's cache directory.
macOS : $HOME/Library/Caches
Windows: FOLDERID_LocalAppData\\cache
Others : $XDG_CACHE_HOME or $HOME/.cache"
{:added "0.5"}
[]
(case os-type
::mac
(str/join file-separator [(System/getProperty "user.home")
"Library"
"Caches"])
::windows
(-> ["F1B32785-6FBA-4FCF-9D55-7B8E7F157091"]
get-win-dirs
first)
(let [cache-home (System/getenv "XDG_CACHE_HOME")]
(if (str/blank? cache-home)
(str (System/getProperty "user.home") file-separator ".cache")
cache-home))))