@@ -23,7 +23,7 @@ import Control.Exception (Exception)
2323import Control.Monad (unless , when )
2424import Data.Either.Validation (Validation (.. ))
2525import Data.Functor.Identity (Identity (.. ))
26- import Data.Maybe (fromMaybe )
26+ import Data.Maybe (fromMaybe , isJust )
2727import Data.Sequence (Seq )
2828import Data.Text (Text )
2929import Data.Void (Void )
@@ -50,6 +50,7 @@ import qualified Dhall.Marshal.Decode as Decode
5050import qualified Dhall.Pretty
5151import qualified Dhall.TypeCheck as TypeCheck
5252import qualified Dhall.Util as Util
53+ import qualified Prettyprinter as Pretty
5354import qualified Prettyprinter.Render.String as Pretty
5455import qualified System.Directory as Directory
5556import qualified System.FilePath as FilePath
@@ -274,6 +275,8 @@ getGroup (GroupName name) = Posix.groupID <$> Posix.getGroupEntryForName name
274275processFilesystemEntry :: Bool -> FilePath -> FilesystemEntry -> IO ()
275276processFilesystemEntry allowSeparators path (DirectoryEntry entry) = do
276277 let path' = path </> entryName entry
278+ when (hasMetadata entry && not isMetadataSupported) $
279+ Exception. throwIO $ MetadataUnsupportedError path'
277280 Directory. createDirectoryIfMissing allowSeparators path'
278281 processFilesystemEntryList allowSeparators path' $ entryContent entry
279282 -- It is important that we write the metadata after we wrote the content of
@@ -282,6 +285,8 @@ processFilesystemEntry allowSeparators path (DirectoryEntry entry) = do
282285 applyMetadata entry path'
283286processFilesystemEntry _ path (FileEntry entry) = do
284287 let path' = path </> entryName entry
288+ when (hasMetadata entry && not isMetadataSupported) $
289+ Exception. throwIO $ MetadataUnsupportedError path'
285290 Text.IO. writeFile path' $ entryContent entry
286291 -- It is important that we write the metadata after we wrote the content of
287292 -- the file as we might lock ourself out by changing ownership or
@@ -293,6 +298,25 @@ processFilesystemEntryList :: Bool -> FilePath -> Seq FilesystemEntry -> IO ()
293298processFilesystemEntryList allowSeparators path = Foldable. traverse_
294299 (processFilesystemEntry allowSeparators path)
295300
301+ -- | Does this entry have some metadata set?
302+ hasMetadata :: Entry a -> Bool
303+ hasMetadata entry
304+ = isJust (entryUser entry)
305+ || isJust (entryGroup entry)
306+ || maybe False hasMode (entryMode entry)
307+ where
308+ hasMode :: Mode Maybe -> Bool
309+ hasMode mode
310+ = maybe False hasAccess (modeUser mode)
311+ || maybe False hasAccess (modeGroup mode)
312+ || maybe False hasAccess (modeOther mode)
313+
314+ hasAccess :: Access Maybe -> Bool
315+ hasAccess access
316+ = isJust (accessExecute access)
317+ || isJust (accessRead access)
318+ || isJust (accessWrite access)
319+
296320-- | Set the metadata of an object referenced by a path.
297321applyMetadata :: Entry a -> FilePath -> IO ()
298322applyMetadata entry fp = do
@@ -378,6 +402,8 @@ hasFileMode mode x = (mode `Posix.intersectFileModes` x) == x
378402newtype FilesystemError =
379403 FilesystemError { unexpectedExpression :: Expr Void Void }
380404
405+ instance Exception FilesystemError
406+
381407instance Show FilesystemError where
382408 show FilesystemError {.. } =
383409 Pretty. renderString (Dhall.Pretty. layout message)
@@ -436,4 +462,24 @@ instance Show FilesystemError where
436462 \ \n \
437463 \... which is not an expression that can be translated to a directory tree. \n "
438464
439- instance Exception FilesystemError
465+ {- | This error indicates that you want to set some metadata for a file or
466+ directory, but that operation is not supported on your platform.
467+ -}
468+ newtype MetadataUnsupportedError =
469+ MetadataUnsupportedError { metadataForPath :: FilePath }
470+
471+ instance Exception MetadataUnsupportedError
472+
473+ instance Show MetadataUnsupportedError where
474+ show MetadataUnsupportedError {.. } =
475+ Pretty. renderString (Dhall.Pretty. layout message)
476+ where
477+ message =
478+ Util. _ERROR <> " : Setting metadata is not supported on this platform. \n \
479+ \ \n \
480+ \Explanation: Your Dhall expression indicates that you intend to set some metadata \n \
481+ \like ownership or permissions for the following file or directory: \n \
482+ \ \n \
483+ \" <> Pretty. pretty metadataForPath <> " \n \
484+ \ \n \
485+ \... which is not supported on your platform. \n "
0 commit comments