diff options
Diffstat (limited to 'lib/pure/distros.nim')
-rw-r--r-- | lib/pure/distros.nim | 147 |
1 files changed, 91 insertions, 56 deletions
diff --git a/lib/pure/distros.nim b/lib/pure/distros.nim index 0adba5b1e..9e71d4ce0 100644 --- a/lib/pure/distros.nim +++ b/lib/pure/distros.nim @@ -9,33 +9,35 @@ ## This module implements the basics for Linux distribution ("distro") ## detection and the OS's native package manager. Its primary purpose is to -## produce output for Nimble packages like:: +## produce output for Nimble packages, like: ## -## To complete the installation, run: +## To complete the installation, run: ## -## sudo apt-get libblas-dev -## sudo apt-get libvoodoo +## sudo apt-get install libblas-dev +## sudo apt-get install libvoodoo ## ## The above output could be the result of a code snippet like: ## -## .. code-block:: nim -## +## ```nim ## if detectOs(Ubuntu): ## foreignDep "lbiblas-dev" ## foreignDep "libvoodoo" +## ``` ## +## See `packaging <packaging.html>`_ for hints on distributing Nim using OS packages. -from strutils import contains, toLowerAscii +from std/strutils import contains, toLowerAscii when not defined(nimscript): - from osproc import execProcess + from std/osproc import execProcess + from std/envvars import existsEnv type Distribution* {.pure.} = enum ## the list of known distributions - Windows ## some version of Windows - Posix ## some Posix system - MacOSX ## some version of OSX - Linux ## some version of Linux + Windows ## some version of Windows + Posix ## some POSIX system + MacOSX ## some version of OSX + Linux ## some version of Linux Ubuntu Debian Gentoo @@ -49,6 +51,7 @@ type CentOS Deepin ArchLinux + Artix Antergos PCLinuxOS Mageia @@ -105,7 +108,7 @@ type Clonezilla SteamOS Absolute - NixOS + NixOS ## NixOS or a Nix build environment AUSTRUMI Arya Porteus @@ -120,67 +123,98 @@ type ExTiX Rockstor GoboLinux + Void BSD FreeBSD + NetBSD OpenBSD DragonFlyBSD + Haiku + const LacksDevPackages* = {Distribution.Gentoo, Distribution.Slackware, - Distribution.ArchLinux} + Distribution.ArchLinux, Distribution.Artix, Distribution.Antergos, + Distribution.BlackArch, Distribution.ArchBang} -var unameRes, releaseRes: string ## we cache the result of the 'uname -a' - ## execution for faster platform detections. +# we cache the result of the 'cmdRelease' +# execution for faster platform detections. +var unameRes, osReleaseIDRes, releaseRes, hostnamectlRes: string -template unameRelease(cmd, cache): untyped = +template cmdRelease(cmd, cache): untyped = if cache.len == 0: cache = (when defined(nimscript): gorge(cmd) else: execProcess(cmd)) cache -template uname(): untyped = unameRelease("uname -a", unameRes) -template release(): untyped = unameRelease("lsb_release -a", releaseRes) +template uname(): untyped = cmdRelease("uname -a", unameRes) +template osReleaseID(): untyped = cmdRelease("cat /etc/os-release | grep ^ID=", osReleaseIDRes) +template release(): untyped = cmdRelease("lsb_release -d", releaseRes) +template hostnamectl(): untyped = cmdRelease("hostnamectl", hostnamectlRes) + +proc detectOsWithAllCmd(d: Distribution): bool = + let dd = toLowerAscii($d) + result = dd in toLowerAscii(osReleaseID()) or dd in toLowerAscii(release()) or + dd in toLowerAscii(uname()) or ("operating system: " & dd) in + toLowerAscii(hostnamectl()) proc detectOsImpl(d: Distribution): bool = case d - of Distribution.Windows: ## some version of Windows - result = defined(windows) + of Distribution.Windows: result = defined(windows) of Distribution.Posix: result = defined(posix) of Distribution.MacOSX: result = defined(macosx) of Distribution.Linux: result = defined(linux) - of Distribution.Ubuntu, Distribution.Gentoo, Distribution.FreeBSD, - Distribution.OpenBSD: - result = ("-" & $d & " ") in uname() - of Distribution.RedHat: - result = "Red Hat" in uname() of Distribution.BSD: result = defined(bsd) - of Distribution.ArchLinux: - result = "arch" in toLowerAscii(uname()) - of Distribution.OpenSUSE: - result = "suse" in toLowerAscii(uname()) or "suse" in toLowerAscii(release()) - of Distribution.GoboLinux: - result = "-Gobo " in uname() - of Distribution.OpenMandriva: - result = "mandriva" in toLowerAscii(uname()) - of Distribution.Solaris: - let uname = toLowerAscii(uname()) - result = ("sun" in uname) or ("solaris" in uname) else: - let dd = toLowerAscii($d) - result = dd in toLowerAscii(uname()) or dd in toLowerAscii(release()) + when defined(bsd): + case d + of Distribution.FreeBSD, Distribution.NetBSD, Distribution.OpenBSD: + result = $d in uname() + else: + result = false + elif defined(linux): + case d + of Distribution.Gentoo: + result = ("-" & $d & " ") in uname() + of Distribution.Elementary, Distribution.Ubuntu, Distribution.Debian, + Distribution.Fedora, Distribution.OpenMandriva, Distribution.CentOS, + Distribution.Alpine, Distribution.Mageia, Distribution.Zorin, Distribution.Void: + result = toLowerAscii($d) in osReleaseID() + of Distribution.RedHat: + result = "rhel" in osReleaseID() + of Distribution.ArchLinux: + result = "arch" in osReleaseID() + of Distribution.Artix: + result = "artix" in osReleaseID() + of Distribution.NixOS: + # Check if this is a Nix build or NixOS environment + result = existsEnv("NIX_BUILD_TOP") or existsEnv("__NIXOS_SET_ENVIRONMENT_DONE") + of Distribution.OpenSUSE: + result = "suse" in toLowerAscii(uname()) or "suse" in toLowerAscii(release()) + of Distribution.GoboLinux: + result = "-Gobo " in uname() + of Distribution.Solaris: + let uname = toLowerAscii(uname()) + result = ("sun" in uname) or ("solaris" in uname) + of Distribution.Haiku: + result = defined(haiku) + else: + result = detectOsWithAllCmd(d) + else: + result = false template detectOs*(d: untyped): bool = - ## Distro/OS detection. For convenience the - ## required ``Distribution.`` qualifier is added to the + ## Distro/OS detection. For convenience, the + ## required `Distribution.` qualifier is added to the ## enum value. detectOsImpl(Distribution.d) when not defined(nimble): - var foreignDeps: seq[string] = @[] + var foreignDeps*: seq[string] = @[] ## Registered foreign deps. -proc foreignCmd*(cmd: string; requiresSudo=false) = - ## Registers a foreign command to the intern list of commands +proc foreignCmd*(cmd: string; requiresSudo = false) = + ## Registers a foreign command to the internal list of commands ## that can be queried later. let c = (if requiresSudo: "sudo " else: "") & cmd when defined(nimble): @@ -189,11 +223,11 @@ proc foreignCmd*(cmd: string; requiresSudo=false) = foreignDeps.add(c) proc foreignDepInstallCmd*(foreignPackageName: string): (string, bool) = - ## Returns the distro's native command line to install 'foreignPackageName' + ## Returns the distro's native command to install `foreignPackageName` ## and whether it requires root/admin rights. let p = foreignPackageName when defined(windows): - result = ("Chocolatey install " & p, false) + result = ("choco install " & p, false) elif defined(bsd): result = ("ports install " & p, true) elif defined(linux): @@ -216,29 +250,30 @@ proc foreignDepInstallCmd*(foreignPackageName: string): (string, bool) = result = ("netpkg install " & p, true) elif detectOs(NixOS): result = ("nix-env -i " & p, false) - elif detectOs(Solaris): + elif detectOs(Solaris) or detectOs(FreeBSD): result = ("pkg install " & p, true) + elif detectOs(NetBSD) or detectOs(OpenBSD): + result = ("pkg_add " & p, true) elif detectOs(PCLinuxOS): result = ("rpm -ivh " & p, true) - elif detectOs(ArchLinux): + elif detectOs(ArchLinux) or detectOs(Manjaro) or detectOs(Artix): result = ("pacman -S " & p, true) + elif detectOs(Void): + result = ("xbps-install " & p, true) else: result = ("<your package manager here> install " & p, true) + elif defined(haiku): + result = ("pkgman install " & p, true) else: result = ("brew install " & p, false) proc foreignDep*(foreignPackageName: string) = - ## Registers 'foreignPackageName' to the internal list of foreign deps. - ## It is your job to ensure the package name + ## Registers `foreignPackageName` to the internal list of foreign deps. + ## It is your job to ensure that the package name is correct. let (installCmd, sudo) = foreignDepInstallCmd(foreignPackageName) - foreignCmd installCmd, sudo + foreignCmd(installCmd, sudo) proc echoForeignDeps*() = ## Writes the list of registered foreign deps to stdout. for d in foreignDeps: echo d - -when false: - foreignDep("libblas-dev") - foreignDep "libfoo" - echoForeignDeps() |