summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorArnaud Moura <arnaudmoura@gmail.com>2020-04-22 07:49:42 +0200
committerGitHub <noreply@github.com>2020-04-22 07:49:42 +0200
commitdc40fb805f82bad83d5892e1c5734942a2ceade7 (patch)
tree5b32e3e241d0939e6b86a7adfb5464fb1525aa6c
parent9604a5a97af45fa601d8d38827eb1462642e2c16 (diff)
downloadNim-dc40fb805f82bad83d5892e1c5734942a2ceade7.tar.gz
Fix OS detection in a docker container (#13172)
* Support detection in docker container.
* Get only ID information in os-release.
* Add test to distros module.
* Fix Linux OS detection in Windows.
* Fix OS detection for FreeBSD and OpenBSD.
-rw-r--r--lib/pure/distros.nim78
-rw-r--r--tests/distros/tdistros_detect.nim21
2 files changed, 67 insertions, 32 deletions
diff --git a/lib/pure/distros.nim b/lib/pure/distros.nim
index a8f0946e1..ae2248b40 100644
--- a/lib/pure/distros.nim
+++ b/lib/pure/distros.nim
@@ -136,18 +136,24 @@ const
   LacksDevPackages* = {Distribution.Gentoo, Distribution.Slackware,
     Distribution.ArchLinux}
 
-# we cache the result of the 'uname -a'
+# we cache the result of the 'cmdRelease'
 # execution for faster platform detections.
-var unameRes, releaseRes, hostnamectlRes: string
+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 -d", releaseRes)
-template hostnamectl(): untyped = unameRelease("hostnamectl", hostnamectlRes)
+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
@@ -156,34 +162,42 @@ proc detectOsImpl(d: Distribution): bool =
   of Distribution.Posix: result = defined(posix)
   of Distribution.MacOSX: result = defined(macosx)
   of Distribution.Linux: result = defined(linux)
-  of Distribution.Ubuntu:
-    result = "Ubuntu" in release() or ("-" & $d & " ") in uname()
-  of 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.NixOS:
-    result = existsEnv("NIX_BUILD_TOP") or existsEnv("__NIXOS_SET_ENVIRONMENT_DONE")
-    # Check if this is a Nix build or NixOS environment
-  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)
-  of Distribution.Haiku:
-    result = defined(haiku)
   else:
-    let dd = toLowerAscii($d)
-    result = dd in toLowerAscii(uname()) or dd in toLowerAscii(release()) or
-              ("operating system: " & dd) in toLowerAscii(hostnamectl())
+    when defined(bsd):
+      case d
+      of Distribution.FreeBSD, 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:
+        result = toLowerAscii($d) in osReleaseID()
+      of Distribution.RedHat:
+        result = "rhel" in osReleaseID()
+      of Distribution.ArchLinux:
+        result = "arch" in osReleaseID()
+      of Distribution.NixOS:
+        result = existsEnv("NIX_BUILD_TOP") or existsEnv("__NIXOS_SET_ENVIRONMENT_DONE")
+        # Check if this is a Nix build or NixOS environment
+      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
diff --git a/tests/distros/tdistros_detect.nim b/tests/distros/tdistros_detect.nim
new file mode 100644
index 000000000..793a9edd3
--- /dev/null
+++ b/tests/distros/tdistros_detect.nim
@@ -0,0 +1,21 @@
+import distros
+
+discard """
+  exitcode: 0
+  output: ""
+"""
+
+when defined(windows):
+    doAssert detectOs(Windows) == true
+    doAssert detectOs(Ubuntu) == false
+    doAssert detectOs(MacOSX) == false
+
+when defined(linux):
+    doAssert detectOs(Ubuntu) == true
+    doAssert detectOs(Windows) == false
+    doAssert detectOs(MacOSX) == false
+
+when defined(macosx):
+    doAssert detectOs(MacOSX) == true
+    doAssert detectOs(Windows) == false
+    doAssert detectOs(Ubuntu) == false
\ No newline at end of file