Skip to content

Commit d712f3a

Browse files
committed
Added some Haddocks
Also fixed a minor bug in `Dhall.DirectoryTree.hasMode`.
1 parent 720c948 commit d712f3a

File tree

1 file changed

+48
-12
lines changed

1 file changed

+48
-12
lines changed

dhall/src/Dhall/DirectoryTree.hs

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,8 @@ toDirectoryTree allowSeparators path expression = case expression of
190190

191191
Lam _ _ (Lam _ (functionBindingVariable -> make) body)
192192
| isFixpointedDirectoryTree expression
193-
-> applyFilesystemEntryList allowSeparators path $ extractFilesystemEntryList make body
193+
-> processFilesystemEntryList allowSeparators path $
194+
extractFilesystemEntryList make body
194195

195196
_ ->
196197
die
@@ -217,6 +218,7 @@ toDirectoryTree allowSeparators path expression = case expression of
217218
where
218219
unexpectedExpression = expression
219220

221+
-- | Check if an expression is a valid fixpoint directory-tree.
220222
isFixpointedDirectoryTree :: Expr Void Void -> Bool
221223
isFixpointedDirectoryTree expr = isRight $ TypeCheck.typeOf $ Annot expr $
222224
[TH.dhall|
@@ -254,11 +256,13 @@ isFixpointedDirectoryTree expr = isRight $ TypeCheck.typeOf $ Annot expr $
254256
List r
255257
|]
256258

259+
-- | A filesystem entry.
257260
data FilesystemEntry
258261
= DirectoryEntry (Entry (Seq FilesystemEntry))
259262
| FileEntry (Entry Text)
260263
deriving Show
261264

265+
-- | Extract a `FilesystemEntry` from an expression.
262266
extractFilesystemEntry :: Text -> Expr Void Void -> FilesystemEntry
263267
extractFilesystemEntry make (App (Field (Var (V make' 0)) (fieldSelectionLabel -> label)) entry)
264268
| make' == make
@@ -267,9 +271,11 @@ extractFilesystemEntry make (App (Field (Var (V make' 0)) (fieldSelectionLabel -
267271
, label == "file" = FileEntry $ extractEntry extractText entry
268272
extractFilesystemEntry _ expr = Exception.throw (FilesystemError expr)
269273

274+
-- | Extract a list of `FilesystemEntry`s from an expression.
270275
extractFilesystemEntryList :: Text -> Expr Void Void -> Seq FilesystemEntry
271276
extractFilesystemEntryList make = extractList (extractFilesystemEntry make)
272277

278+
-- | A generic filesystem entry parameterized over the content.
273279
data Entry a = Entry
274280
{ entryName :: String
275281
, entryContent :: a
@@ -279,6 +285,7 @@ data Entry a = Entry
279285
}
280286
deriving Show
281287

288+
-- | Extract an `Entry` from an expression.
282289
extractEntry :: (Expr Void Void -> a) -> Expr Void Void -> Entry a
283290
extractEntry extractContent (RecordLit (Map.toList ->
284291
[ ("content", recordFieldValue -> contentExpr)
@@ -295,6 +302,7 @@ extractEntry extractContent (RecordLit (Map.toList ->
295302
}
296303
extractEntry _ expr = Exception.throw (FilesystemError expr)
297304

305+
-- | A user identified either by id or name.
298306
data User
299307
= UserId UserID
300308
| UserName String
@@ -307,15 +315,18 @@ pattern UserP label v <- App (Field (Union (Map.toList ->
307315
(fieldSelectionLabel -> label))
308316
v
309317

318+
-- | Extract a `User` from an expression.
310319
extractUser :: Expr Void Void -> User
311320
extractUser (UserP "UserId" (NaturalLit n)) = UserId $ Posix.CUid (fromIntegral n)
312321
extractUser (UserP "UserName" (TextLit (Chunks [] text))) = UserName $ Text.unpack text
313322
extractUser expr = Exception.throw (FilesystemError expr)
314323

324+
-- | Resolve a `User` to a numerical id.
315325
getUser :: User -> IO UserID
316326
getUser (UserId uid) = return uid
317327
getUser (UserName name) = Posix.userID <$> Posix.getUserEntryForName name
318328

329+
-- | A group identified either by id or name.
319330
data Group
320331
= GroupId GroupID
321332
| GroupName String
@@ -328,15 +339,20 @@ pattern GroupP label v <- App (Field (Union (Map.toList ->
328339
(fieldSelectionLabel -> label))
329340
v
330341

342+
-- | Extract a `Group` from an expression.
331343
extractGroup :: Expr Void Void -> Group
332344
extractGroup (GroupP "GroupId" (NaturalLit n)) = GroupId $ Posix.CGid (fromIntegral n)
333345
extractGroup (GroupP "GroupName" (TextLit (Chunks [] text))) = GroupName $ Text.unpack text
334346
extractGroup expr = Exception.throw (FilesystemError expr)
335347

348+
-- | Resolve a `Group` to a numerical id.
336349
getGroup :: Group -> IO GroupID
337350
getGroup (GroupId gid) = return gid
338351
getGroup (GroupName name) = Posix.groupID <$> Posix.getGroupEntryForName name
339352

353+
-- | A filesystem mode. See chmod(1).
354+
-- The parameter is meant to be instantiated by either `Identity` or `Maybe`
355+
-- depending on the completeness of the information.
340356
data Mode f = Mode
341357
{ modeUser :: f (Access f)
342358
, modeGroup :: f (Access f)
@@ -348,6 +364,7 @@ deriving instance Eq (Mode Maybe)
348364
deriving instance Show (Mode Identity)
349365
deriving instance Show (Mode Maybe)
350366

367+
-- | Extract a `Mode` from an expression.
351368
extractMode :: Expr Void Void -> Mode Maybe
352369
extractMode (RecordLit (Map.toList ->
353370
[ ("group", recordFieldValue -> groupExpr)
@@ -360,6 +377,7 @@ extractMode (RecordLit (Map.toList ->
360377
}
361378
extractMode expr = Exception.throw (FilesystemError expr)
362379

380+
-- | The permissions for a subject (user/group/other).
363381
data Access f = Access
364382
{ accessExecute :: f Bool
365383
, accessRead :: f Bool
@@ -371,6 +389,7 @@ deriving instance Eq (Access Maybe)
371389
deriving instance Show (Access Identity)
372390
deriving instance Show (Access Maybe)
373391

392+
-- | Extract a `Access` from an expression.
374393
extractAccess :: Expr Void Void -> Access Maybe
375394
extractAccess (RecordLit (Map.toList ->
376395
[ ("execute", recordFieldValue -> executeExpr)
@@ -383,49 +402,61 @@ extractAccess (RecordLit (Map.toList ->
383402
}
384403
extractAccess expr = Exception.throw (FilesystemError expr)
385404

405+
-- | Helper function to extract a `Bool` value.
386406
extractBool :: Expr Void Void -> Bool
387407
extractBool (BoolLit b) = b
388408
extractBool expr = Exception.throw (FilesystemError expr)
389409

410+
-- | Helper function to extract a list of some values.
411+
-- The first argument is used to extract the items.
390412
extractList :: (Expr Void Void -> a) -> Expr Void Void -> Seq a
391413
extractList _ (ListLit (Just _) _) = mempty
392414
extractList f (ListLit _ xs) = fmap f xs
393415
extractList _ expr = Exception.throw (FilesystemError expr)
394416

417+
-- | Helper function to extract optional values.
418+
-- The first argument is used to extract the items.
395419
extractMaybe :: (Expr Void Void -> a) -> Expr Void Void -> Maybe a
396420
extractMaybe _ (App None _) = Nothing
397421
extractMaybe f (Some expr) = Just (f expr)
398422
extractMaybe _ expr = Exception.throw (FilesystemError expr)
399423

424+
-- | Helper function to extract a `String` value.
400425
extractString :: Expr Void Void -> String
401426
extractString = Text.unpack . extractText
402427

428+
-- | Helper function to extract a `Text` value.
403429
extractText :: Expr Void Void -> Text
404430
extractText (TextLit (Chunks [] text)) = text
405431
extractText expr = Exception.throw (FilesystemError expr)
406432

407-
applyFilesystemEntry :: Bool -> FilePath -> FilesystemEntry -> IO ()
408-
applyFilesystemEntry allowSeparators path (DirectoryEntry entry) = do
433+
-- | Process a `FilesystemEntry`. Writes the content to disk and apply the
434+
-- metadata to the newly created item.
435+
processFilesystemEntry :: Bool -> FilePath -> FilesystemEntry -> IO ()
436+
processFilesystemEntry allowSeparators path (DirectoryEntry entry) = do
409437
let path' = path </> entryName entry
410438
Directory.createDirectoryIfMissing allowSeparators path'
411-
applyFilesystemEntryList allowSeparators path' $ entryContent entry
439+
processFilesystemEntryList allowSeparators path' $ entryContent entry
412440
-- It is important that we write the metadata after we wrote the content of
413441
-- the directories/files below this directory as we might lock ourself out
414442
-- by changing ownership or permissions.
415-
unsafeApplyMetadata entry path'
416-
applyFilesystemEntry _ path (FileEntry entry) = do
443+
applyMetadata entry path'
444+
processFilesystemEntry _ path (FileEntry entry) = do
417445
let path' = path </> entryName entry
418446
Text.IO.writeFile path' $ entryContent entry
419447
-- It is important that we write the metadata after we wrote the content of
420448
-- the file as we might lock ourself out by changing ownership or
421449
-- permissions.
422-
unsafeApplyMetadata entry path'
450+
applyMetadata entry path'
423451

424-
applyFilesystemEntryList :: Bool -> FilePath -> Seq FilesystemEntry -> IO ()
425-
applyFilesystemEntryList allowSeparators path = Foldable.traverse_ (applyFilesystemEntry allowSeparators path)
452+
-- | Process a list of `FilesystemEntry`s.
453+
processFilesystemEntryList :: Bool -> FilePath -> Seq FilesystemEntry -> IO ()
454+
processFilesystemEntryList allowSeparators path = Foldable.traverse_
455+
(processFilesystemEntry allowSeparators path)
426456

427-
unsafeApplyMetadata :: Entry a -> FilePath -> IO ()
428-
unsafeApplyMetadata entry fp = do
457+
-- | Set the metadata of an object referenced by a path.
458+
applyMetadata :: Entry a -> FilePath -> IO ()
459+
applyMetadata entry fp = do
429460
s <- Posix.getFileStatus fp
430461
let user = Posix.fileOwner s
431462
group = Posix.fileGroup s
@@ -440,6 +471,7 @@ unsafeApplyMetadata entry fp = do
440471
unless (mode' == mode) $
441472
Posix.setFileMode fp $ modeToFileMode mode'
442473

474+
-- | Calculate the new `Mode` from the current mode and the changes specified by the user.
443475
updateModeWith :: Mode Identity -> Mode Maybe -> Mode Identity
444476
updateModeWith x y = Mode
445477
{ modeUser = combine modeUser modeUser
@@ -449,6 +481,7 @@ updateModeWith x y = Mode
449481
where
450482
combine f g = maybe (f x) (Identity . updateAccessWith (runIdentity $ f x)) (g y)
451483

484+
-- | Calculate the new `Access` from the current permissions and the changes specified by the user.
452485
updateAccessWith :: Access Identity -> Access Maybe -> Access Identity
453486
updateAccessWith x y = Access
454487
{ accessExecute = combine accessExecute accessExecute
@@ -458,6 +491,7 @@ updateAccessWith x y = Access
458491
where
459492
combine f g = maybe (f x) Identity (g y)
460493

494+
-- | Convert a filesystem mode given as a bitmask (`FileMode`) to an ADT (`Mode`).
461495
fileModeToMode :: FileMode -> Mode Identity
462496
fileModeToMode mode = Mode
463497
{ modeUser = Identity $ Access
@@ -477,6 +511,7 @@ fileModeToMode mode = Mode
477511
}
478512
}
479513

514+
-- | Convert a filesystem mode given as an ADT (`Mode`) to a bitmask (`FileMode`).
480515
modeToFileMode :: Mode Identity -> FileMode
481516
modeToFileMode mode = foldr Posix.unionFileModes Posix.nullFileMode $
482517
[ Posix.ownerExecuteMode | runIdentity $ accessExecute (runIdentity $ modeUser mode) ] <>
@@ -489,8 +524,9 @@ modeToFileMode mode = foldr Posix.unionFileModes Posix.nullFileMode $
489524
[ Posix.otherReadMode | runIdentity $ accessRead (runIdentity $ modeOther mode) ] <>
490525
[ Posix.otherWriteMode | runIdentity $ accessWrite (runIdentity $ modeOther mode) ]
491526

527+
-- | Check whether the second `FileMode` is contained in the first one.
492528
hasFileMode :: FileMode -> FileMode -> Bool
493-
hasFileMode mode x = (mode `Posix.intersectFileModes` x) == Posix.nullFileMode
529+
hasFileMode mode x = (mode `Posix.intersectFileModes` x) == x
494530

495531
{- | This error indicates that you supplied an invalid Dhall expression to the
496532
`toDirectoryTree` function. The Dhall expression could not be translated

0 commit comments

Comments
 (0)