distros.nim 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. #
  2. #
  3. # Nim's Runtime Library
  4. # (c) Copyright 2016 Andreas Rumpf
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. ## This module implements the basics for Linux distribution ("distro")
  10. ## detection and the OS's native package manager. Its primary purpose is to
  11. ## produce output for Nimble packages like::
  12. ##
  13. ## To complete the installation, run:
  14. ##
  15. ## sudo apt-get libblas-dev
  16. ## sudo apt-get libvoodoo
  17. ##
  18. ## The above output could be the result of a code snippet like:
  19. ##
  20. ## .. code-block:: nim
  21. ##
  22. ## if detectOs(Ubuntu):
  23. ## foreignDep "lbiblas-dev"
  24. ## foreignDep "libvoodoo"
  25. ##
  26. from strutils import contains, toLowerAscii
  27. when not defined(nimscript):
  28. from osproc import execProcess
  29. type
  30. Distribution* {.pure.} = enum ## the list of known distributions
  31. Windows ## some version of Windows
  32. Posix ## some Posix system
  33. MacOSX ## some version of OSX
  34. Linux ## some version of Linux
  35. Ubuntu
  36. Debian
  37. Gentoo
  38. Fedora
  39. RedHat
  40. OpenSUSE
  41. Manjaro
  42. Elementary
  43. Zorin
  44. CentOS
  45. Deepin
  46. ArchLinux
  47. Antergos
  48. PCLinuxOS
  49. Mageia
  50. LXLE
  51. Solus
  52. Lite
  53. Slackware
  54. Androidx86
  55. Puppy
  56. Peppermint
  57. Tails
  58. AntiX
  59. Kali
  60. SparkyLinux
  61. Apricity
  62. BlackLab
  63. Bodhi
  64. TrueOS
  65. ArchBang
  66. KaOS
  67. WattOS
  68. Korora
  69. Simplicity
  70. RemixOS
  71. OpenMandriva
  72. Netrunner
  73. Alpine
  74. BlackArch
  75. Ultimate
  76. Gecko
  77. Parrot
  78. KNOPPIX
  79. GhostBSD
  80. Sabayon
  81. Salix
  82. Q4OS
  83. ClearOS
  84. Container
  85. ROSA
  86. Zenwalk
  87. Parabola
  88. ChaletOS
  89. BackBox
  90. MXLinux
  91. Vector
  92. Maui
  93. Qubes
  94. RancherOS
  95. Oracle
  96. TinyCore
  97. Robolinux
  98. Trisquel
  99. Voyager
  100. Clonezilla
  101. SteamOS
  102. Absolute
  103. NixOS
  104. AUSTRUMI
  105. Arya
  106. Porteus
  107. AVLinux
  108. Elive
  109. Bluestar
  110. SliTaz
  111. Solaris
  112. Chakra
  113. Wifislax
  114. Scientific
  115. ExTiX
  116. Rockstor
  117. GoboLinux
  118. BSD
  119. FreeBSD
  120. OpenBSD
  121. DragonFlyBSD
  122. Haiku
  123. const
  124. LacksDevPackages* = {Distribution.Gentoo, Distribution.Slackware,
  125. Distribution.ArchLinux}
  126. var unameRes, releaseRes, hostnamectlRes: string ## we cache the result of the 'uname -a'
  127. ## execution for faster platform detections.
  128. template unameRelease(cmd, cache): untyped =
  129. if cache.len == 0:
  130. cache = (when defined(nimscript): gorge(cmd) else: execProcess(cmd))
  131. cache
  132. template uname(): untyped = unameRelease("uname -o", unameRes)
  133. template release(): untyped = unameRelease("lsb_release -d", releaseRes)
  134. template hostnamectl(): untyped = unameRelease("hostnamectl", hostnamectlRes)
  135. proc detectOsImpl(d: Distribution): bool =
  136. case d
  137. of Distribution.Windows: ## some version of Windows
  138. result = defined(windows)
  139. of Distribution.Posix: result = defined(posix)
  140. of Distribution.MacOSX: result = defined(macosx)
  141. of Distribution.Linux: result = defined(linux)
  142. of Distribution.Ubuntu, Distribution.Gentoo, Distribution.FreeBSD,
  143. Distribution.OpenBSD:
  144. result = ("-" & $d & " ") in uname()
  145. of Distribution.RedHat:
  146. result = "Red Hat" in uname()
  147. of Distribution.BSD: result = defined(bsd)
  148. of Distribution.ArchLinux:
  149. result = "arch" in toLowerAscii(uname())
  150. of Distribution.OpenSUSE:
  151. result = "suse" in toLowerAscii(uname()) or "suse" in toLowerAscii(release())
  152. of Distribution.GoboLinux:
  153. result = "-Gobo " in uname()
  154. of Distribution.OpenMandriva:
  155. result = "mandriva" in toLowerAscii(uname())
  156. of Distribution.Solaris:
  157. let uname = toLowerAscii(uname())
  158. result = ("sun" in uname) or ("solaris" in uname)
  159. of Distribution.Haiku:
  160. result = defined(haiku)
  161. else:
  162. let dd = toLowerAscii($d)
  163. result = dd in toLowerAscii(uname()) or dd in toLowerAscii(release()) or ("operating system: " & dd) in toLowerAscii(hostnamectl())
  164. template detectOs*(d: untyped): bool =
  165. ## Distro/OS detection. For convenience the
  166. ## required ``Distribution.`` qualifier is added to the
  167. ## enum value.
  168. detectOsImpl(Distribution.d)
  169. when not defined(nimble):
  170. var foreignDeps: seq[string] = @[]
  171. proc foreignCmd*(cmd: string; requiresSudo=false) =
  172. ## Registers a foreign command to the intern list of commands
  173. ## that can be queried later.
  174. let c = (if requiresSudo: "sudo " else: "") & cmd
  175. when defined(nimble):
  176. nimscriptapi.foreignDeps.add(c)
  177. else:
  178. foreignDeps.add(c)
  179. proc foreignDepInstallCmd*(foreignPackageName: string): (string, bool) =
  180. ## Returns the distro's native command line to install 'foreignPackageName'
  181. ## and whether it requires root/admin rights.
  182. let p = foreignPackageName
  183. when defined(windows):
  184. result = ("Chocolatey install " & p, false)
  185. elif defined(bsd):
  186. result = ("ports install " & p, true)
  187. elif defined(linux):
  188. if detectOs(Ubuntu) or detectOs(Elementary) or detectOs(Debian) or
  189. detectOs(KNOPPIX) or detectOs(SteamOS):
  190. result = ("apt-get install " & p, true)
  191. elif detectOs(Gentoo):
  192. result = ("emerge install " & p, true)
  193. elif detectOs(Fedora):
  194. result = ("yum install " & p, true)
  195. elif detectOs(RedHat):
  196. result = ("rpm install " & p, true)
  197. elif detectOs(OpenSUSE):
  198. result = ("yast -i " & p, true)
  199. elif detectOs(Slackware):
  200. result = ("installpkg " & p, true)
  201. elif detectOs(OpenMandriva):
  202. result = ("urpmi " & p, true)
  203. elif detectOs(ZenWalk):
  204. result = ("netpkg install " & p, true)
  205. elif detectOs(NixOS):
  206. result = ("nix-env -i " & p, false)
  207. elif detectOs(Solaris):
  208. result = ("pkg install " & p, true)
  209. elif detectOs(PCLinuxOS):
  210. result = ("rpm -ivh " & p, true)
  211. elif detectOs(ArchLinux):
  212. result = ("pacman -S " & p, true)
  213. else:
  214. result = ("<your package manager here> install " & p, true)
  215. elif defined(haiku):
  216. result = ("pkgman install " & p, true)
  217. else:
  218. result = ("brew install " & p, false)
  219. proc foreignDep*(foreignPackageName: string) =
  220. ## Registers 'foreignPackageName' to the internal list of foreign deps.
  221. ## It is your job to ensure the package name
  222. let (installCmd, sudo) = foreignDepInstallCmd(foreignPackageName)
  223. foreignCmd installCmd, sudo
  224. proc echoForeignDeps*() =
  225. ## Writes the list of registered foreign deps to stdout.
  226. for d in foreignDeps:
  227. echo d
  228. when false:
  229. foreignDep("libblas-dev")
  230. foreignDep "libfoo"
  231. echoForeignDeps()