1{-# LANGUAGE RankNTypes #-}
2module Data.Yaml.Include (decodeFile, decodeFileEither) where
4import Control.Exception (throwIO)
5import Control.Monad (when)
6import Control.Monad.IO.Class (liftIO)
7import Control.Monad.Trans.Resource (MonadResource)
8import Data.Aeson (FromJSON)
10import qualified Data.Conduit.List as CL
11import Data.Text (unpack)
12import Data.Text.Encoding (decodeUtf8)
13import System.Directory
16import Data.Yaml.Internal (ParseException(..), decodeHelper_, decodeHelper)
17import Text.Libyaml hiding (decodeFile)
18import qualified Text.Libyaml as Y
26 go :: MonadResource m => [FilePath] -> FilePath -> Producer m Event
28 cfp <- liftIO $ canonicalizePath fp
29 when (cfp `elem` seen) $ do
30 liftIO $ throwIO CyclicIncludes
31 Y.decodeFile cfp $= do
32 awaitForever $ \event -> case event of
33 EventScalar f (UriTag "!include") _ _ -> do
34 let includeFile = takeDirectory cfp </> unpack (decodeUtf8 f)
35 go (cfp : seen) includeFile $= CL.filter (`notElem` irrelevantEvents)
38 irrelevantEvents = [EventStreamStart, EventDocumentStart, EventDocumentEnd, EventStreamEnd]
40-- | Like `Data.Yaml.decodeFile` but with support for relative and absolute
43-- The syntax for includes follows the form:
45-- > somekey: !include ./somefile.yaml
50decodeFile fp = decodeHelper (eventsFromFile fp) >>= either throwIO (return . either (const Nothing) id)
52-- | Like `Data.Yaml.decodeFileEither` but with support for relative and
55-- The syntax for includes follows the form:
57-- > somekey: !include ./somefile.yaml
61 -> IO (Either ParseException a)
62decodeFileEither = decodeHelper_ . eventsFromFile
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list