{-# LANGUAGE ViewPatterns #-}

module Language.JavaScript.Inline.Core.NodeVersion where

import Control.Exception
import Control.Monad
import Data.List
import Data.Version
import Language.JavaScript.Inline.Core.Exception
import Language.JavaScript.Inline.Core.Utils
import System.Process

parseNodeVersion :: String -> Version
parseNodeVersion :: String -> Version
parseNodeVersion String
s0 = [Int] -> [String] -> Version
Version [Int]
vs ([String] -> Version) -> [String] -> Version
forall a b. (a -> b) -> a -> b
$ case String
tag of
  String
"" -> []
  String
_ -> [String
tag]
  where
    vs_ts :: [String]
vs_ts = (Char -> Bool) -> String -> [String]
forall a. (a -> Bool) -> [a] -> [[a]]
split (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'-') String
s0
    vs :: [Int]
vs = (String -> Int) -> [String] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map String -> Int
forall a. Read a => String -> a
read ([String] -> [Int]) -> [String] -> [Int]
forall a b. (a -> b) -> a -> b
$ (Char -> Bool) -> String -> [String]
forall a. (a -> Bool) -> [a] -> [[a]]
split (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'.') (String -> [String]) -> String -> [String]
forall a b. (a -> b) -> a -> b
$ [String] -> String
forall a. [a] -> a
head [String]
vs_ts
    tag :: String
tag = String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
"-" ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ [String] -> [String]
forall a. [a] -> [a]
tail [String]
vs_ts

isSupportedVersion :: Version -> Bool
isSupportedVersion :: Version -> Bool
isSupportedVersion (Version -> [Int]
versionBranch -> [Int]
v) =
  ([Int]
v [Int] -> [Int] -> Bool
forall a. Ord a => a -> a -> Bool
>= [Int
12, Int
0, Int
0]) Bool -> Bool -> Bool
|| ([Int]
v [Int] -> [Int] -> Bool
forall a. Ord a => a -> a -> Bool
>= [Int
10, Int
20, Int
0] Bool -> Bool -> Bool
&& [Int]
v [Int] -> [Int] -> Bool
forall a. Ord a => a -> a -> Bool
< [Int
11])

checkNodeVersion :: FilePath -> IO ()
checkNodeVersion :: String -> IO ()
checkNodeVersion String
p = do
  Version
v <-
    String -> Version
parseNodeVersion
      (String -> Version) -> IO String -> IO Version
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> [String] -> String -> IO String
readProcess
        String
p
        [String
"--eval", String
"process.stdout.write(process.versions.node)"]
        String
""
  Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Version -> Bool
isSupportedVersion Version
v) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ NodeVersionUnsupported -> IO ()
forall e a. Exception e => e -> IO a
throwIO NodeVersionUnsupported
NodeVersionUnsupported