{-# LANGUAGE CPP #-}

module Cachix.Client.NixVersion
  ( assertNixVersion,
    parseNixVersion,
  )
where

import Data.Text as T
import Data.Versions
import Protolude
import System.Process (readProcessWithExitCode)

assertNixVersion :: IO (Either Text ())
assertNixVersion :: IO (Either Text ())
assertNixVersion = do
  (ExitCode
exitcode, String
out, String
err) <- String -> [String] -> String -> IO (ExitCode, String, String)
readProcessWithExitCode String
"nix-env" [String
"--version"] String
forall a. Monoid a => a
mempty
  Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (String
err String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"") (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ String -> IO ()
forall a (m :: * -> *). (Print a, MonadIO m) => a -> m ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"nix-env stderr: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
err
  Either Text () -> IO (Either Text ())
forall (m :: * -> *) a. Monad m => a -> m a
return (Either Text () -> IO (Either Text ()))
-> Either Text () -> IO (Either Text ())
forall a b. (a -> b) -> a -> b
$ case ExitCode
exitcode of
    ExitFailure Int
i -> Text -> Either Text ()
forall a b. a -> Either a b
Left (Text -> Either Text ()) -> Text -> Either Text ()
forall a b. (a -> b) -> a -> b
$ Text
"'nix-env --version' exited with " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Int -> Text
forall a b. (Show a, ConvertText String b) => a -> b
show Int
i
    ExitCode
ExitSuccess -> Text -> Either Text ()
parseNixVersion (Text -> Either Text ()) -> Text -> Either Text ()
forall a b. (a -> b) -> a -> b
$ String -> Text
forall a b. ConvertText a b => a -> b
toS String
out

parseNixVersion :: Text -> Either Text ()
parseNixVersion :: Text -> Either Text ()
parseNixVersion Text
output =
  let verStr :: Text
verStr = Int -> Text -> Text
T.drop Int
14 (Text -> Text) -> Text -> Text
forall a b. (a -> b) -> a -> b
$ Text -> Text
T.strip Text
output
      err :: Text
err = Text
"Couldn't parse 'nix-env --version' output: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
output
   in case Text -> Either ParsingError Versioning
versioning Text
verStr of
        Left ParsingError
_ -> Text -> Either Text ()
forall a b. a -> Either a b
Left Text
err
        Right Versioning
ver
          | Text
verStr Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
"" -> Text -> Either Text ()
forall a b. a -> Either a b
Left Text
err
          | Versioning
ver Versioning -> Versioning -> Bool
forall a. Ord a => a -> a -> Bool
< SemVer -> Versioning
Ideal SemVer
minimalVersion -> Text -> Either Text ()
forall a b. a -> Either a b
Left Text
"Nix 2.0.2 or lower is not supported. Please upgrade: https://nixos.org/nix/"
          | Bool
otherwise -> () -> Either Text ()
forall a b. b -> Either a b
Right ()

minimalVersion :: SemVer
minimalVersion :: SemVer
minimalVersion =
  Word -> Word -> Word -> [VChunk] -> Maybe Text -> SemVer
SemVer Word
2 Word
0 Word
1 []

#if MIN_VERSION_versions(0,5,0)
    Maybe Text
forall a. Maybe a
Nothing
#else
    []
#endif