Factor out filesystem functionality into MonadFile

This commit is contained in:
Ryan Trinkle 2018-11-16 15:16:17 -05:00
parent 02e057c5c0
commit 2884c4f918
4 changed files with 56 additions and 25 deletions

View file

@ -90,7 +90,7 @@ import Nix.Utils
import Nix.Value
import Nix.XML
import System.FilePath
import System.Posix.Files
import System.Posix.Files (isRegularFile, isDirectory, isSymbolicLink)
import Text.Regex.TDFA
-- | Evaluate a nix expression in the default context
@ -965,7 +965,7 @@ readDir_ pathThunk = do
path <- absolutePathFromValue =<< pathThunk
items <- listDirectory path
itemsWithTypes <- forM items $ \item -> do
s <- Nix.Effects.getSymbolicLinkStatus $ path </> item
s <- getSymbolicLinkStatus $ path </> item
let t = if
| isRegularFile s -> FileTypeRegular
| isDirectory s -> FileTypeDirectory

View file

@ -6,7 +6,6 @@ import Nix.Frames
import Nix.Render
import Nix.Value
import System.Exit
import System.Posix.Files
import System.Process
import System.Directory
@ -30,9 +29,6 @@ class (MonadFile m, MonadStore m) => MonadEffects m where
getCurrentSystemOS :: m Text
getCurrentSystemArch :: m Text
listDirectory :: FilePath -> m [FilePath]
getSymbolicLinkStatus :: FilePath -> m FileStatus
derivationStrict :: NValue m -> m (NValue m)
nixInstantiateExpr :: String -> m (NValue m)

View file

@ -36,7 +36,6 @@ import Control.Monad.Ref
import Control.Monad.State.Strict
import Control.Monad.Trans.Reader (ReaderT(..))
import Control.Monad.Trans.State.Strict (StateT(..))
import qualified Data.ByteString as BS
import Data.Coerce
import Data.Fix
import Data.HashMap.Lazy (HashMap)
@ -73,7 +72,6 @@ import Nix.Value
#ifdef MIN_VERSION_haskeline
import System.Console.Haskeline.MonadException hiding (catch)
#endif
import System.Directory
import System.Environment
import System.Exit (ExitCode (ExitSuccess))
import System.FilePath
@ -486,11 +484,7 @@ instance MonadRef m => MonadRef (Lazy m) where
instance MonadAtomicRef m => MonadAtomicRef (Lazy m) where
atomicModifyRef r = lift . atomicModifyRef r
instance (MonadFile m, Monad m) => MonadFile (Lazy m) where
readFile = lift . Nix.Render.readFile
instance MonadFile IO where
readFile = BS.readFile
instance (MonadFile m, Monad m) => MonadFile (Lazy m)
instance MonadCatch m => MonadCatch (Lazy m) where
catch (Lazy (ReaderT m)) f = Lazy $ ReaderT $ \e ->
@ -514,12 +508,12 @@ instance (MonadFix m, MonadCatch m, MonadFile m, MonadStore m, MonadVar m,
MonadIO m, Alternative m, MonadPlus m, Typeable m)
=> MonadEffects (Lazy m) where
makeAbsolutePath origPath = do
origPathExpanded <- liftIO $ expandHomePath origPath
origPathExpanded <- expandHomePath origPath
absPath <- if isAbsolute origPathExpanded then pure origPathExpanded else do
cwd <- do
mres <- lookupVar @_ @(NThunk (Lazy m)) "__cur_file"
case mres of
Nothing -> liftIO getCurrentDirectory
Nothing -> getCurrentDirectory
Just v -> force v $ \case
NVPath s -> return $ takeDirectory s
v -> throwError $ ErrorCall $ "when resolving relative path,"
@ -527,10 +521,10 @@ instance (MonadFix m, MonadCatch m, MonadFile m, MonadStore m, MonadVar m,
++ " but is not a path; it is: "
++ show v
pure $ cwd <///> origPathExpanded
liftIO $ removeDotDotIndirections <$> canonicalizePath absPath
removeDotDotIndirections <$> canonicalizePath absPath
-- Given a path, determine the nix file to load
pathToDefaultNix = liftIO . pathToDefaultNixFile
pathToDefaultNix = pathToDefaultNixFile
findEnvPath = findEnvPathM
findPath = findPathM
@ -568,9 +562,6 @@ instance (MonadFix m, MonadCatch m, MonadFile m, MonadStore m, MonadVar m,
"i386" -> "i686"
arch -> arch
listDirectory = liftIO . System.Directory.listDirectory
getSymbolicLinkStatus = liftIO . System.Posix.Files.getSymbolicLinkStatus
derivationStrict = fromValue @(ValueSet (Lazy m)) >=> \s -> do
nn <- maybe (pure False) fromNix (M.lookup "__ignoreNulls" s)
s' <- M.fromList <$> mapMaybeM (handleEntry nn) (M.toList s)
@ -677,12 +668,12 @@ removeDotDotIndirections = intercalate "/" . go [] . splitOn "/"
go (_:s) ("..":rest) = go s rest
go s (this:rest) = go (this:s) rest
expandHomePath :: FilePath -> IO FilePath
expandHomePath :: MonadFile m => FilePath -> m FilePath
expandHomePath ('~' : xs) = flip (++) xs <$> getHomeDirectory
expandHomePath p = return p
-- Given a path, determine the nix file to load
pathToDefaultNixFile :: FilePath -> IO FilePath
pathToDefaultNixFile :: MonadFile m => FilePath -> m FilePath
pathToDefaultNixFile p = do
isDir <- doesDirectoryExist p
pure $ if isDir then p </> "default.nix" else p
@ -740,7 +731,7 @@ findPathM l name = findPathBy path l name
path :: (MonadEffects m, MonadIO m) => FilePath -> m (Maybe FilePath)
path path = do
path <- makeAbsolutePath path
exists <- liftIO $ doesPathExist path
exists <- doesPathExist path
return $ if exists then Just path else Nothing
findEnvPathM :: forall e m. (MonadNix e m, MonadIO m)
@ -755,11 +746,11 @@ findEnvPathM name = do
nixFilePath :: (MonadEffects m, MonadIO m) => FilePath -> m (Maybe FilePath)
nixFilePath path = do
path <- makeAbsolutePath path
exists <- liftIO $ doesDirectoryExist path
exists <- doesDirectoryExist path
path' <- if exists
then makeAbsolutePath $ path </> "default.nix"
else return path
exists <- liftIO $ doesFileExist path'
exists <- doesFileExist path'
return $ if exists then Just path' else Nothing
addTracing :: (MonadNix e m, Has e Options, MonadIO m,

View file

@ -1,4 +1,5 @@
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DefaultSignatures #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE OverloadedStrings #-}
@ -9,17 +10,60 @@
module Nix.Render where
import Prelude hiding (readFile)
import Control.Monad.Trans
import Data.ByteString (ByteString)
import qualified Data.ByteString as BS
import Data.List.NonEmpty (NonEmpty((:|)))
import qualified Data.Set as Set
import Data.Void
import Nix.Expr.Types.Annotated
import qualified System.Posix.Files as S
import qualified System.Directory as S
import Text.Megaparsec.Error
import Text.Megaparsec.Pos (SourcePos(..))
import Text.PrettyPrint.ANSI.Leijen
class Monad m => MonadFile m where
readFile :: FilePath -> m ByteString
default readFile :: (MonadTrans t, MonadFile m', m ~ t m') => FilePath -> m ByteString
readFile = lift . readFile
listDirectory :: FilePath -> m [FilePath]
default listDirectory :: (MonadTrans t, MonadFile m', m ~ t m') => FilePath -> m [FilePath]
listDirectory = lift . listDirectory
getCurrentDirectory :: m FilePath
default getCurrentDirectory :: (MonadTrans t, MonadFile m', m ~ t m') => m FilePath
getCurrentDirectory = lift getCurrentDirectory
canonicalizePath :: FilePath -> m FilePath
default canonicalizePath :: (MonadTrans t, MonadFile m', m ~ t m') => FilePath -> m FilePath
canonicalizePath = lift . canonicalizePath
getHomeDirectory :: m FilePath
default getHomeDirectory :: (MonadTrans t, MonadFile m', m ~ t m') => m FilePath
getHomeDirectory = lift getHomeDirectory
doesPathExist :: FilePath -> m Bool
default doesPathExist :: (MonadTrans t, MonadFile m', m ~ t m') => FilePath -> m Bool
doesPathExist = lift . doesPathExist
doesFileExist :: FilePath -> m Bool
default doesFileExist :: (MonadTrans t, MonadFile m', m ~ t m') => FilePath -> m Bool
doesFileExist = lift . doesFileExist
doesDirectoryExist :: FilePath -> m Bool
default doesDirectoryExist :: (MonadTrans t, MonadFile m', m ~ t m') => FilePath -> m Bool
doesDirectoryExist = lift . doesDirectoryExist
getSymbolicLinkStatus :: FilePath -> m S.FileStatus
default getSymbolicLinkStatus :: (MonadTrans t, MonadFile m', m ~ t m') => FilePath -> m S.FileStatus
getSymbolicLinkStatus = lift . getSymbolicLinkStatus
instance MonadFile IO where
readFile = BS.readFile
listDirectory = S.listDirectory
getCurrentDirectory = S.getCurrentDirectory
canonicalizePath = S.canonicalizePath
getHomeDirectory = S.getHomeDirectory
doesPathExist = S.doesPathExist
doesFileExist = S.doesFileExist
doesDirectoryExist = S.doesDirectoryExist
getSymbolicLinkStatus = S.getSymbolicLinkStatus
posAndMsg :: SourcePos -> Doc -> ParseError t Void
posAndMsg beg msg =