Skip to content

Commit 44e7b97

Browse files
authored
to-directory-tree: Do not support setting file metadata on Windows (#2507)
1 parent 85146e5 commit 44e7b97

File tree

3 files changed

+59
-3
lines changed

3 files changed

+59
-3
lines changed

dhall/src/Dhall/DirectoryTree.hs

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import Control.Exception (Exception)
2323
import Control.Monad (unless, when)
2424
import Data.Either.Validation (Validation (..))
2525
import Data.Functor.Identity (Identity (..))
26-
import Data.Maybe (fromMaybe)
26+
import Data.Maybe (fromMaybe, isJust)
2727
import Data.Sequence (Seq)
2828
import Data.Text (Text)
2929
import Data.Void (Void)
@@ -50,6 +50,7 @@ import qualified Dhall.Marshal.Decode as Decode
5050
import qualified Dhall.Pretty
5151
import qualified Dhall.TypeCheck as TypeCheck
5252
import qualified Dhall.Util as Util
53+
import qualified Prettyprinter as Pretty
5354
import qualified Prettyprinter.Render.String as Pretty
5455
import qualified System.Directory as Directory
5556
import qualified System.FilePath as FilePath
@@ -274,6 +275,8 @@ getGroup (GroupName name) = Posix.groupID <$> Posix.getGroupEntryForName name
274275
processFilesystemEntry :: Bool -> FilePath -> FilesystemEntry -> IO ()
275276
processFilesystemEntry 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'
283286
processFilesystemEntry _ 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 ()
293298
processFilesystemEntryList 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.
297321
applyMetadata :: Entry a -> FilePath -> IO ()
298322
applyMetadata entry fp = do
@@ -378,6 +402,8 @@ hasFileMode mode x = (mode `Posix.intersectFileModes` x) == x
378402
newtype FilesystemError =
379403
FilesystemError { unexpectedExpression :: Expr Void Void }
380404

405+
instance Exception FilesystemError
406+
381407
instance 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"

dhall/src/Dhall/DirectoryTree/Types.hs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ module Dhall.DirectoryTree.Types
2323

2424
, setFileMode
2525
, prettyFileMode
26+
27+
, isMetadataSupported
2628
) where
2729

2830
import Data.Functor.Identity (Identity (..))
@@ -239,3 +241,11 @@ prettyFileMode mode = userPP <> groupPP <> otherPP
239241
isBitSet c mask = if mask `Posix.intersectFileModes` mode /= Posix.nullFileMode
240242
then [c]
241243
else "-"
244+
245+
-- | Is setting metadata supported on this platform or not.
246+
isMetadataSupported :: Bool
247+
#ifdef mingw32_HOST_OS
248+
isMetadataSupported = False
249+
#else
250+
isMetadataSupported = True
251+
#endif

dhall/tests/Dhall/Test/DirectoryTree.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ tests = testGroup "to-directory-tree"
2828
, fixpointedSimple
2929
#ifndef mingw32_HOST_OS
3030
, fixpointedPermissions
31-
#endif
3231
, fixpointedUserGroup
32+
#endif
3333
]
3434
]
3535

0 commit comments

Comments
 (0)