dhall-1.42.0: A configuration language guaranteed to terminate

Safe Haskell | Safe-Inferred
Language | Haskell2010

Dhall.DirectoryTree

Contents

- Filesystem
- Low-level types and functions

Description

Implementation of the `dhall to-directory-tree` subcommand

Synopsis

- toDirectoryTree :: Bool -> FilePath -> Expr Void Void -> IO ()
- newtype FilesystemError = FilesystemError {
  - unexpectedExpression :: Expr Void Void
  }
- data FilesystemEntry
  - = DirectoryEntry (Entry (Seq FilesystemEntry))
  - | FileEntry (Entry Text)
- type DirectoryEntry = Entry (Seq FilesystemEntry)
- type FileEntry = Entry Text
- data Entry a = Entry {
  - entryName :: String
  - entryContent :: a
  - entryUser :: Maybe User
  - entryGroup :: Maybe Group
  - entryMode :: Maybe (Mode Maybe)
  }
- data User
  - = UserId UserID
  - | UserName String
- data Group
  - = GroupId GroupID
  - | GroupName String
- data Mode f = Mode {
  - modeUser :: f (Access f)
  - modeGroup :: f (Access f)
  - modeOther :: f (Access f)
  }
- data Access f = Access {
  - accessExecute :: f Bool
  - accessRead :: f Bool
  - accessWrite :: f Bool
  }
- setFileMode :: FilePath -> FileMode -> IO ()
- prettyFileMode :: FileMode -> String
- isMetadataSupported :: Bool
- decodeDirectoryTree :: Expr s Void -> IO (Seq FilesystemEntry)
- directoryTreeType :: Expector (Expr Src Void)

# Filesystem

toDirectoryTree #

Arguments

:: Bool | Whether to allow path separators in file names or not
-> FilePath |
-> Expr Void Void |
-> IO () |

Attempt to transform a Dhall record into a directory tree where:

- Records are translated into directories
- `Map`s are also translated into directories
- `Text` values or fields are translated into files
- `Optional` values are omitted if `None`
- There is a more advanced way to construct directory trees using a fixpoint encoding. See the documentation below on that.

For example, the following Dhall record:

    { dir = { `hello.txt` = "Hello\n" }
    , `goodbye.txt`= Some "Goodbye\n"
    , `missing.txt` = None Text
    }

... should translate to this directory tree:

    $ tree result
    result
    ├── dir
    │   └── hello.txt
    └── goodbye.txt

    $ cat result/dir/hello.txt
    Hello

    $ cat result/goodbye.txt
    Goodbye

Use this in conjunction with the Prelude's support for rendering JSON/YAML in "pure Dhall" so that you can generate files containing JSON. For example:

    let JSON =
          https://prelude.dhall-lang.org/v12.0.0/JSON/package.dhall sha256:843783d29e60b558c2de431ce1206ce34bdfde375fcf06de8ec5bf77092fdef7

    in  { `example.json` =
            JSON.render (JSON.array [ JSON.number 1.0, JSON.bool True ])
        , `example.yaml` =
            JSON.renderYAML
              (JSON.object (toMap { foo = JSON.string "Hello", bar = JSON.null }))
        }

... which would generate:

    $ cat result/example.json
    [ 1.0, true ]

    $ cat result/example.yaml
    ! "bar": null
    ! "foo": "Hello"

Advanced construction of directory trees

In addition to the ways described above using "simple" Dhall values to construct the directory tree there is one based on a fixpoint encoding. It works by passing a value of the following type to the interpreter:

    let User = < UserId : Natural | UserName : Text >

    let Group = < GroupId : Natural | GroupName : Text >

    let Access =
          { execute : Optional Bool
          , read : Optional Bool
          , write : Optional Bool
          }

    let Mode =
          { user : Optional Access
          , group : Optional Access
          , other : Optional Access
          }

    let Entry =
          \(content : Type) ->
            { name : Text
            , content : content
            , user : Optional User
            , group : Optional Group
            , mode : Optional Mode
            }

    in  forall (tree : Type) ->
        forall  ( make
                : { directory : Entry (List tree) -> tree
                  , file : Entry Text -> tree
                  }
                ) ->
          List tree

The fact that the metadata for filesystem entries is modeled after the POSIX permission model comes with the unfortunate downside that it might not apply to other systems: There, changes to the metadata (user, group, permissions) might be a no-op and no warning will be issued. This is a leaking abstraction of the unix-compat package used internally.

NOTE: This utility does not take care of type-checking and normalizing the provided expression. This will raise a `FilesystemError` exception or a `DhallErrors` exception upon encountering an expression that cannot be converted as-is.

newtype FilesystemError #

This error indicates that you supplied an invalid Dhall expression to the `toDirectoryTree` function. The Dhall expression could not be translated to a directory tree.

Constructors

FilesystemError |
Fields unexpectedExpression :: Expr Void Void

#### Instances

Instances details

Exception FilesystemError # |
Instance details Defined in Dhall.DirectoryTree Methods toException :: FilesystemError -> SomeException fromException :: SomeException -> Maybe FilesystemError displayException :: FilesystemError -> String
Show FilesystemError # |
Instance details Defined in Dhall.DirectoryTree Methods showsPrec :: Int -> FilesystemError -> ShowS # show :: FilesystemError -> String # showList :: [FilesystemError] -> ShowS #

# Low-level types and functions

data FilesystemEntry #

A filesystem entry.

Constructors

DirectoryEntry (Entry (Seq FilesystemEntry)) |
FileEntry (Entry Text) |

#### Instances

Instances details

Generic FilesystemEntry # |
Instance details Defined in Dhall.DirectoryTree.Types Associated Types type Rep FilesystemEntry :: Type -> Type # Methods from :: FilesystemEntry -> Rep FilesystemEntry x # to :: Rep FilesystemEntry x -> FilesystemEntry #
Show FilesystemEntry # |
Instance details Defined in Dhall.DirectoryTree.Types Methods showsPrec :: Int -> FilesystemEntry -> ShowS # show :: FilesystemEntry -> String # showList :: [FilesystemEntry] -> ShowS #
FromDhall FilesystemEntry # |
Instance details Defined in Dhall.DirectoryTree.Types Methods autoWith :: InputNormalizer -> Decoder FilesystemEntry #
Eq FilesystemEntry # |
Instance details Defined in Dhall.DirectoryTree.Types Methods (==) :: FilesystemEntry -> FilesystemEntry -> Bool # (/=) :: FilesystemEntry -> FilesystemEntry -> Bool #
Ord FilesystemEntry # |
Instance details Defined in Dhall.DirectoryTree.Types Methods compare :: FilesystemEntry -> FilesystemEntry -> Ordering # (<) :: FilesystemEntry -> FilesystemEntry -> Bool # (<=) :: FilesystemEntry -> FilesystemEntry -> Bool # (>) :: FilesystemEntry -> FilesystemEntry -> Bool # (>=) :: FilesystemEntry -> FilesystemEntry -> Bool # max :: FilesystemEntry -> FilesystemEntry -> FilesystemEntry # min :: FilesystemEntry -> FilesystemEntry -> FilesystemEntry #
type Rep FilesystemEntry # |
Instance details Defined in Dhall.DirectoryTree.Types type Rep FilesystemEntry = D1 ('MetaData "FilesystemEntry" "Dhall.DirectoryTree.Types" "dhall-1.42.0-KYLP0Bk1OLT52T5U2EOzRV" 'False) (C1 ('MetaCons "DirectoryEntry" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Entry (Seq FilesystemEntry)))) :+: C1 ('MetaCons "FileEntry" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Entry Text))))

type DirectoryEntry = Entry (Seq FilesystemEntry) #

A directory in the filesystem.

type FileEntry = Entry Text #

A file in the filesystem.

data Entry a #

A generic filesystem entry. This type holds the metadata that apply to all entries. It is parametric over the content of such an entry.

Constructors

Entry |
Fields entryName :: String entryContent :: a entryUser :: Maybe User entryGroup :: Maybe Group entryMode :: Maybe (Mode Maybe)

#### Instances

Instances details

Generic (Entry a) # |
Instance details Defined in Dhall.DirectoryTree.Types Associated Types type Rep (Entry a) :: Type -> Type # Methods from :: Entry a -> Rep (Entry a) x # to :: Rep (Entry a) x -> Entry a #
Show a => Show (Entry a) # |
Instance details Defined in Dhall.DirectoryTree.Types Methods showsPrec :: Int -> Entry a -> ShowS # show :: Entry a -> String # showList :: [Entry a] -> ShowS #
FromDhall a => FromDhall (Entry a) # |
Instance details Defined in Dhall.DirectoryTree.Types Methods autoWith :: InputNormalizer -> Decoder (Entry a) #
Eq a => Eq (Entry a) # |
Instance details Defined in Dhall.DirectoryTree.Types Methods (==) :: Entry a -> Entry a -> Bool # (/=) :: Entry a -> Entry a -> Bool #
Ord a => Ord (Entry a) # |
Instance details Defined in Dhall.DirectoryTree.Types Methods compare :: Entry a -> Entry a -> Ordering # (<) :: Entry a -> Entry a -> Bool # (<=) :: Entry a -> Entry a -> Bool # (>) :: Entry a -> Entry a -> Bool # (>=) :: Entry a -> Entry a -> Bool # max :: Entry a -> Entry a -> Entry a # min :: Entry a -> Entry a -> Entry a #
type Rep (Entry a) # |
Instance details Defined in Dhall.DirectoryTree.Types type Rep (Entry a) = D1 ('MetaData "Entry" "Dhall.DirectoryTree.Types" "dhall-1.42.0-KYLP0Bk1OLT52T5U2EOzRV" 'False) (C1 ('MetaCons "Entry" 'PrefixI 'True) ((S1 ('MetaSel ('Just "entryName") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 String) :*: S1 ('MetaSel ('Just "entryContent") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 a)) :*: (S1 ('MetaSel ('Just "entryUser") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Maybe User)) :*: (S1 ('MetaSel ('Just "entryGroup") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Maybe Group)) :*: S1 ('MetaSel ('Just "entryMode") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Maybe (Mode Maybe)))))))

data User #

A user identified either by id or name.

Constructors

UserId UserID |
UserName String |

#### Instances

Instances details

Generic User # |
Instance details Defined in Dhall.DirectoryTree.Types Associated Types type Rep User :: Type -> Type # Methods from :: User -> Rep User x # to :: Rep User x -> User #
Show User # |
Instance details Defined in Dhall.DirectoryTree.Types Methods showsPrec :: Int -> User -> ShowS # show :: User -> String # showList :: [User] -> ShowS #
FromDhall User # |
Instance details Defined in Dhall.DirectoryTree.Types Methods autoWith :: InputNormalizer -> Decoder User #
Eq User # |
Instance details Defined in Dhall.DirectoryTree.Types Methods (==) :: User -> User -> Bool # (/=) :: User -> User -> Bool #
Ord User # |
Instance details Defined in Dhall.DirectoryTree.Types Methods compare :: User -> User -> Ordering # (<) :: User -> User -> Bool # (<=) :: User -> User -> Bool # (>) :: User -> User -> Bool # (>=) :: User -> User -> Bool # max :: User -> User -> User # min :: User -> User -> User #
type Rep User # |
Instance details Defined in Dhall.DirectoryTree.Types type Rep User = D1 ('MetaData "User" "Dhall.DirectoryTree.Types" "dhall-1.42.0-KYLP0Bk1OLT52T5U2EOzRV" 'False) (C1 ('MetaCons "UserId" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 UserID)) :+: C1 ('MetaCons "UserName" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 String)))

data Group #

A group identified either by id or name.

Constructors

GroupId GroupID |
GroupName String |

#### Instances

Instances details

Generic Group # |
Instance details Defined in Dhall.DirectoryTree.Types Associated Types type Rep Group :: Type -> Type # Methods from :: Group -> Rep Group x # to :: Rep Group x -> Group #
Show Group # |
Instance details Defined in Dhall.DirectoryTree.Types Methods showsPrec :: Int -> Group -> ShowS # show :: Group -> String # showList :: [Group] -> ShowS #
FromDhall Group # |
Instance details Defined in Dhall.DirectoryTree.Types Methods autoWith :: InputNormalizer -> Decoder Group #
Eq Group # |
Instance details Defined in Dhall.DirectoryTree.Types Methods (==) :: Group -> Group -> Bool # (/=) :: Group -> Group -> Bool #
Ord Group # |
Instance details Defined in Dhall.DirectoryTree.Types Methods compare :: Group -> Group -> Ordering # (<) :: Group -> Group -> Bool # (<=) :: Group -> Group -> Bool # (>) :: Group -> Group -> Bool # (>=) :: Group -> Group -> Bool # max :: Group -> Group -> Group # min :: Group -> Group -> Group #
type Rep Group # |
Instance details Defined in Dhall.DirectoryTree.Types type Rep Group = D1 ('MetaData "Group" "Dhall.DirectoryTree.Types" "dhall-1.42.0-KYLP0Bk1OLT52T5U2EOzRV" 'False) (C1 ('MetaCons "GroupId" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 GroupID)) :+: C1 ('MetaCons "GroupName" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 String)))

data Mode f #

A filesystem mode. See chmod(1). The parameter is meant to be instantiated by either `Identity` or `Maybe` depending on the completeness of the information: * For data read from the filesystem it will be `Identity`. * For user-supplied data it will be `Maybe` as we want to be able to set only specific bits.

Constructors

Mode |
Fields modeUser :: f (Access f) modeGroup :: f (Access f) modeOther :: f (Access f)

#### Instances

Instances details

Generic (Mode f) # |
Instance details Defined in Dhall.DirectoryTree.Types Associated Types type Rep (Mode f) :: Type -> Type # Methods from :: Mode f -> Rep (Mode f) x # to :: Rep (Mode f) x -> Mode f #
Show (Mode Identity) # |
Instance details Defined in Dhall.DirectoryTree.Types Methods showsPrec :: Int -> Mode Identity -> ShowS # show :: Mode Identity -> String # showList :: [Mode Identity] -> ShowS #
Show (Mode Maybe) # |
Instance details Defined in Dhall.DirectoryTree.Types Methods showsPrec :: Int -> Mode Maybe -> ShowS # show :: Mode Maybe -> String # showList :: [Mode Maybe] -> ShowS #
FromDhall (Mode Identity) # |
Instance details Defined in Dhall.DirectoryTree.Types Methods autoWith :: InputNormalizer -> Decoder (Mode Identity) #
FromDhall (Mode Maybe) # |
Instance details Defined in Dhall.DirectoryTree.Types Methods autoWith :: InputNormalizer -> Decoder (Mode Maybe) #
Eq (Mode Identity) # |
Instance details Defined in Dhall.DirectoryTree.Types Methods (==) :: Mode Identity -> Mode Identity -> Bool # (/=) :: Mode Identity -> Mode Identity -> Bool #
Eq (Mode Maybe) # |
Instance details Defined in Dhall.DirectoryTree.Types Methods (==) :: Mode Maybe -> Mode Maybe -> Bool # (/=) :: Mode Maybe -> Mode Maybe -> Bool #
Ord (Mode Identity) # |
Instance details Defined in Dhall.DirectoryTree.Types Methods compare :: Mode Identity -> Mode Identity -> Ordering # (<) :: Mode Identity -> Mode Identity -> Bool # (<=) :: Mode Identity -> Mode Identity -> Bool # (>) :: Mode Identity -> Mode Identity -> Bool # (>=) :: Mode Identity -> Mode Identity -> Bool # max :: Mode Identity -> Mode Identity -> Mode Identity # min :: Mode Identity -> Mode Identity -> Mode Identity #
Ord (Mode Maybe) # |
Instance details Defined in Dhall.DirectoryTree.Types Methods compare :: Mode Maybe -> Mode Maybe -> Ordering # (<) :: Mode Maybe -> Mode Maybe -> Bool # (<=) :: Mode Maybe -> Mode Maybe -> Bool # (>) :: Mode Maybe -> Mode Maybe -> Bool # (>=) :: Mode Maybe -> Mode Maybe -> Bool # max :: Mode Maybe -> Mode Maybe -> Mode Maybe # min :: Mode Maybe -> Mode Maybe -> Mode Maybe #
type Rep (Mode f) # |
Instance details Defined in Dhall.DirectoryTree.Types type Rep (Mode f) = D1 ('MetaData "Mode" "Dhall.DirectoryTree.Types" "dhall-1.42.0-KYLP0Bk1OLT52T5U2EOzRV" 'False) (C1 ('MetaCons "Mode" 'PrefixI 'True) (S1 ('MetaSel ('Just "modeUser") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f (Access f))) :*: (S1 ('MetaSel ('Just "modeGroup") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f (Access f))) :*: S1 ('MetaSel ('Just "modeOther") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f (Access f))))))

data Access f #

The permissions for a subject (usergroupother).

Constructors

Access |
Fields accessExecute :: f Bool accessRead :: f Bool accessWrite :: f Bool

#### Instances

Instances details

Generic (Access f) # |
Instance details Defined in Dhall.DirectoryTree.Types Associated Types type Rep (Access f) :: Type -> Type # Methods from :: Access f -> Rep (Access f) x # to :: Rep (Access f) x -> Access f #
Show (Access Identity) # |
Instance details Defined in Dhall.DirectoryTree.Types Methods showsPrec :: Int -> Access Identity -> ShowS # show :: Access Identity -> String # showList :: [Access Identity] -> ShowS #
Show (Access Maybe) # |
Instance details Defined in Dhall.DirectoryTree.Types Methods showsPrec :: Int -> Access Maybe -> ShowS # show :: Access Maybe -> String # showList :: [Access Maybe] -> ShowS #
FromDhall (Access Identity) # |
Instance details Defined in Dhall.DirectoryTree.Types Methods autoWith :: InputNormalizer -> Decoder (Access Identity) #
FromDhall (Access Maybe) # |
Instance details Defined in Dhall.DirectoryTree.Types Methods autoWith :: InputNormalizer -> Decoder (Access Maybe) #
Eq (Access Identity) # |
Instance details Defined in Dhall.DirectoryTree.Types Methods (==) :: Access Identity -> Access Identity -> Bool # (/=) :: Access Identity -> Access Identity -> Bool #
Eq (Access Maybe) # |
Instance details Defined in Dhall.DirectoryTree.Types Methods (==) :: Access Maybe -> Access Maybe -> Bool # (/=) :: Access Maybe -> Access Maybe -> Bool #
Ord (Access Identity) # |
Instance details Defined in Dhall.DirectoryTree.Types Methods compare :: Access Identity -> Access Identity -> Ordering # (<) :: Access Identity -> Access Identity -> Bool # (<=) :: Access Identity -> Access Identity -> Bool # (>) :: Access Identity -> Access Identity -> Bool # (>=) :: Access Identity -> Access Identity -> Bool # max :: Access Identity -> Access Identity -> Access Identity # min :: Access Identity -> Access Identity -> Access Identity #
Ord (Access Maybe) # |
Instance details Defined in Dhall.DirectoryTree.Types Methods compare :: Access Maybe -> Access Maybe -> Ordering # (<) :: Access Maybe -> Access Maybe -> Bool # (<=) :: Access Maybe -> Access Maybe -> Bool # (>) :: Access Maybe -> Access Maybe -> Bool # (>=) :: Access Maybe -> Access Maybe -> Bool # max :: Access Maybe -> Access Maybe -> Access Maybe # min :: Access Maybe -> Access Maybe -> Access Maybe #
type Rep (Access f) # |
Instance details Defined in Dhall.DirectoryTree.Types type Rep (Access f) = D1 ('MetaData "Access" "Dhall.DirectoryTree.Types" "dhall-1.42.0-KYLP0Bk1OLT52T5U2EOzRV" 'False) (C1 ('MetaCons "Access" 'PrefixI 'True) (S1 ('MetaSel ('Just "accessExecute") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Bool)) :*: (S1 ('MetaSel ('Just "accessRead") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Bool)) :*: S1 ('MetaSel ('Just "accessWrite") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (f Bool)))))

setFileMode :: FilePath -> FileMode -> IO () #

A wrapper around `setFileMode`. On Windows, it does check the resulting file mode of the file/directory and emits a warning if it doesn't match the desired file mode. On all other OS it is identical to `setFileMode` as it is assumed to work correctly.

prettyFileMode :: FileMode -> String #

Pretty-print a `FileMode`. The format is similar to the one ls(1): It is display as three blocks of three characters. The first block are the permissions of the user, the second one are the ones of the group and the third one the ones of other subjects. A `r` denotes that the file or directory is readable by the subject, a `w` denotes that it is writable and an `x` denotes that it is executable. Unset permissions are represented by `-`.

isMetadataSupported :: Bool #

Is setting metadata supported on this platform or not.

decodeDirectoryTree :: Expr s Void -> IO (Seq FilesystemEntry) #

Decode a fixpoint directory tree from a Dhall expression.

directoryTreeType :: Expector (Expr Src Void) #

The type of a fixpoint directory tree expression.