{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}
module System.Which (which, staticWhich, staticWhichNix) where
import qualified Shelly as Sh
import qualified Data.Text as T
import Language.Haskell.TH (Exp, Q, reportError, runIO)
import Data.Monoid ((<>))
import Data.List (isPrefixOf)
which :: FilePath -> IO (Maybe FilePath)
which f = fmap (fmap (T.unpack . Sh.toTextIgnore)) $ Sh.shelly $ Sh.which $ Sh.fromText $ T.pack f
staticWhichImpl :: (FilePath -> Maybe String) -> FilePath -> Q Exp
staticWhichImpl test f = do
mf' <- runIO $ which f
case mf' of
Nothing -> compileError $ "Could not find executable for " <> show f
Just f' -> case test f' of
Just err -> compileError err
Nothing -> [| f' |]
where
compileError msg' = do
let msg = "staticWhich: " <> msg'
reportError msg
[| error msg |]
staticWhich :: FilePath -> Q Exp
staticWhich = staticWhichImpl (const Nothing)
staticWhichNix :: FilePath -> Q Exp
staticWhichNix = staticWhichImpl $ \x ->
if "/nix/store/" `isPrefixOf` x
then Nothing
else Just $ "Executable was found in " <> x <> " which is not in /nix/store."