on master help sign in
Merge pull request #104 from liskin/directory-canonicalizePath-exception

Workaround for exception-throwing canonicalizePath in old directory

commit02b2d5d8b70183035f756f96b66859d17b46ea92 authorMichael Snoyman <michael@snoyman.com> dateWed 25 Jan 2017, 13:17 (10 years ago) parent953e79d8ee41a0
4 files changed+39−7
ChangeLog.md+4 Data/Yaml/Include.hs+19−1 test/Data/Yaml/IncludeSpec.hs+15−5 yaml.cabal+1−1
ChangeLog.md+4
@@ -1,3 +1,7 @@
1+## 0.8.21.2
2+
3+* Fix wrong file not found exception in `Data.Yaml.Include` with pre-1.2.3.0 `directory` [#104](https://github.com/snoyberg/yaml/pull/104)
4+
15## 0.8.21.1
26
37* Add missing test files [#102](https://github.com/snoyberg/yaml/pull/102)
Data/Yaml/Include.hs+19−1
@@ -1,6 +1,13 @@
1+{-# LANGUAGE CPP #-}
12{-# LANGUAGE RankNTypes #-}
23module Data.Yaml.Include (decodeFile, decodeFileEither) where
34
5+#if !MIN_VERSION_directory(1, 2, 3)
6+import Control.Exception (handleJust)
7+import Control.Monad (guard)
8+import System.IO.Error (ioeGetFileName, ioeGetLocation, isDoesNotExistError)
9+#endif
10+
411import Control.Exception (throwIO)
512import Control.Monad (when)
613import Control.Monad.IO.Class (liftIO)
@@ -25,7 +32,7 @@ eventsFromFile = go []
2532 where
2633 go :: MonadResource m => [FilePath] -> FilePath -> Producer m Event
2734 go seen fp = do
28− cfp <- liftIO $ canonicalizePath fp
35+ cfp <- liftIO $ handleNotFound $ canonicalizePath fp
2936 when (cfp `elem` seen) $ do
3037 liftIO $ throwIO CyclicIncludes
3138 Y.decodeFile cfp $= do
@@ -37,6 +44,17 @@ eventsFromFile = go []
3744
3845 irrelevantEvents = [EventStreamStart, EventDocumentStart, EventDocumentEnd, EventStreamEnd]
3946
47+#if !MIN_VERSION_directory(1, 2, 3)
48+ handleNotFound = handleJust
49+ (\e -> do
50+ guard (isDoesNotExistError e)
51+ guard (ioeGetLocation e == "canonicalizePath")
52+ ioeGetFileName e)
53+ (throwIO . YamlException . ("Yaml file not found: " ++))
54+#else
55+ handleNotFound = id
56+#endif
57+
4058-- | Like `Data.Yaml.decodeFile` but with support for relative and absolute
4159-- includes.
4260--
test/Data/Yaml/IncludeSpec.hs+15−5
@@ -2,12 +2,12 @@
22module Data.Yaml.IncludeSpec (main, spec) where
33
44import Test.Hspec
5−import Data.Either.Compat
5+import Data.List (isPrefixOf)
66import Data.Aeson
77import Data.Aeson.QQ
8−import Data.Yaml (ParseException)
9−
8+import Data.Yaml (ParseException(InvalidYaml))
109import Data.Yaml.Include
10+import Text.Libyaml (YamlException(YamlException))
1111
1212main :: IO ()
1313main = hspec spec
@@ -38,7 +38,17 @@ spec = do
3838 it "aborts on cyclic includes" $ do
3939 (decodeFile "test/resources/loop/foo.yaml" :: IO (Maybe Value)) `shouldThrow` anyException
4040
41+ context "when file does not exist" $ do
42+ it "throws Left (InvalidYaml (Just (YamlException \"Yaml file not found: ...\")))" $ do
43+ (decodeFile "./does_not_exist.yaml" :: IO (Maybe Value)) `shouldThrow` isYamlFileNotFoundException
44+
4145 describe "decodeFileEither" $ do
4246 context "when file does not exist" $ do
43− it "returns Left" $ do
44− (decodeFileEither "./does_not_exist.yaml" :: IO (Either ParseException Value)) >>= (`shouldSatisfy` isLeft)
47+ it "returns Left (InvalidYaml (Just (YamlException \"Yaml file not found: ...\")))" $ do
48+ (decodeFileEither "./does_not_exist.yaml" :: IO (Either ParseException Value)) >>=
49+ (`shouldSatisfy` either isYamlFileNotFoundException (const False))
50+
51+isYamlFileNotFoundException :: ParseException -> Bool
52+isYamlFileNotFoundException (InvalidYaml (Just (YamlException msg)))
53+ | "Yaml file not found: " `isPrefixOf` msg = True
54+isYamlFileNotFoundException _ = False
yaml.cabal+1−1
@@ -1,5 +1,5 @@
11name: yaml
2−version: 0.8.21.1
2+version: 0.8.21.2
33license: BSD3
44license-file: LICENSE
55author: Michael Snoyman <michael@snoyman.com>, Anton Ageev <antage@gmail.com>,Kirill Simonov