dhall-yaml 1.1.0 → 1.2.0
raw patch · 10 files changed
+123/−53 lines, 10 filesdep ~dhalldep ~dhall-jsondep ~tasty-expected-failurePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: dhall, dhall-json, tasty-expected-failure
API changes (from Hackage documentation)
+ Dhall.Yaml: [noEdit] :: Options -> Bool
- Dhall.Yaml: Options :: Bool -> (Value -> Value) -> Bool -> Bool -> Conversion -> Maybe FilePath -> Maybe FilePath -> Options
+ Dhall.Yaml: Options :: Bool -> (Value -> Value) -> Bool -> Bool -> Conversion -> Maybe FilePath -> Maybe FilePath -> Bool -> Options
Files
- CHANGELOG.md +15/−0
- dhall-yaml.cabal +12/−11
- src/Dhall/Yaml.hs +23/−21
- tasty/Main.hs +35/−12
- tasty/data/boolean-quotes.dhall +7/−0
- tasty/data/boolean-quotes.yaml +6/−0
- tasty/data/mergify.dhall +8/−8
- tasty/data/normal-aeson.dhall +8/−0
- tasty/data/normal-aeson.yaml +8/−0
- tasty/data/normal.yaml +1/−1
CHANGELOG.md view
@@ -1,3 +1,18 @@+1.2.0++* BREAKING CHANGE: [Add `--generated-comment` flag for `dhall-to-yaml{-ng}`](https://github.com/dhall-lang/dhall-haskell/pull/1840)+ * You can now optionally add a comment header to the YAML output+ indicating that the file is generated and should not be hand-edited+ * This is a breaking change because this adds a new `noEdit` field to the+ options type+ * In practice this breakage won't affect most users+* [Produce output compatible with YAML 1.1](https://github.com/dhall-lang/dhall-haskell/pull/1788)+ * Special strings like `on` are now quoted in order to avoid being+ misinterpreted as boolean values by YAML 1.1 implementations+* [Show JSON/YAML path on error reporting](https://github.com/dhall-lang/dhall-haskell/pull/1799)+ * Error messages will now include the path to the error in the diagnostic+ output+ 1.1.0 * BREAKING CHANGE: [Add `yaml-to-dhall` support for inferring the schema](https://github.com/dhall-lang/dhall-haskell/pull/1773)
dhall-yaml.cabal view
@@ -1,5 +1,5 @@ Name: dhall-yaml-Version: 1.1.0+Version: 1.2.0 Cabal-Version: >=1.10 Build-Type: Simple Tested-With: GHC == 8.2.2, GHC == 8.4.3, GHC == 8.6.1@@ -35,10 +35,10 @@ HsYAML >= 0.2 && < 0.3 , HsYAML-aeson >= 0.2 && < 0.3 , base >= 4.8.0.0 && < 5 ,- aeson >= 1.0.0.0 && < 1.5 ,+ aeson >= 1.0.0.0 && < 1.6 , bytestring < 0.11,- dhall >= 1.31.0 && < 1.33,- dhall-json >= 1.6.0 && < 1.7 ,+ dhall >= 1.31.0 && < 1.34,+ dhall-json >= 1.6.0 && < 1.8 , optparse-applicative >= 0.14.0.0 && < 0.16, text >= 0.11.1.0 && < 1.3 , vector@@ -88,14 +88,15 @@ Hs-Source-Dirs: tasty Main-Is: Main.hs Build-Depends:- base ,- bytestring ,- dhall ,- dhall-json ,- dhall-yaml ,- tasty < 1.3,- tasty-expected-failure < 0.12,+ base ,+ bytestring ,+ dhall ,+ dhall-json ,+ dhall-yaml ,+ tasty < 1.4,+ tasty-expected-failure < 0.12, text , tasty-hunit >= 0.2+ GHC-Options: -Wall Default-Language: Haskell2010
src/Dhall/Yaml.hs view
@@ -9,22 +9,22 @@ , dhallToYaml ) where -import Data.ByteString (ByteString)-import Data.Text (Text)-import Dhall.JSON (SpecialDoubleMode(..), codeToValue)-import Dhall.JSON.Yaml (Options(..))+import Data.ByteString (ByteString) import Data.ByteString.Lazy (toStrict)+import Data.Text (Text)+import Dhall.JSON (SpecialDoubleMode (..), codeToValue)+import Dhall.JSON.Yaml (Options (..)) import qualified Data.Aeson import qualified Data.ByteString-import qualified Data.Char as Char-import qualified Data.Text as Text+import qualified Data.Char as Char+import qualified Data.Text as Text import qualified Data.Vector-import qualified Data.YAML as Y+import qualified Data.YAML as Y import qualified Data.YAML.Aeson-import qualified Data.YAML.Event as YE+import qualified Data.YAML.Event as YE import qualified Data.YAML.Schema as YS-import qualified Data.YAML.Token as YT+import qualified Data.YAML.Token as YT import qualified Dhall import qualified Dhall.JSON.Yaml @@ -37,13 +37,18 @@ -> Text -- ^ Input text. -> IO ByteString dhallToYaml Options{..} mFilePath code = do- + let explaining = if explain then Dhall.detailed else id json <- omission <$> explaining (codeToValue conversion UseYAMLEncoding mFilePath code) - return $ jsonToYaml json documents quoted+ let header =+ if noEdit+ then Dhall.JSON.Yaml.generatedCodeNotice+ else mempty + return $ header <> jsonToYaml json documents quoted+ -- | Transform json representation into yaml jsonToYaml :: Data.Aeson.Value@@ -54,9 +59,8 @@ case (documents, json) of (True, Data.Aeson.Array elems) -> Data.ByteString.intercalate "\n---\n"- $ fmap (Data.ByteString.Lazy.toStrict. (Data.YAML.Aeson.encodeValue' schemaEncoder YT.UTF8). (:[]))- $ Data.Vector.toList elems- _ -> Data.ByteString.Lazy.toStrict (Data.YAML.Aeson.encodeValue' schemaEncoder YT.UTF8 [json])+ $ (Data.ByteString.Lazy.toStrict . encoder . (:[])) <$> Data.Vector.toList elems+ _ -> Data.ByteString.Lazy.toStrict (encoder [json]) where style (Y.SStr s) | "\n" `Text.isInfixOf` s =@@ -64,15 +68,13 @@ | quoted || Text.all isNumberOrDateRelated s || isBoolString = Right (YE.untagged, YE.SingleQuoted, s) where- isBoolString- | Text.length s > 5 = False- | otherwise =- case Text.toLower s of- "true" -> True- "false" -> True- _ -> False+ -- For backwards compatibility with YAML 1.1, we need to add the following to the set of boolean values:+ -- https://yaml.org/type/bool.html+ isBoolString = Text.length s <= 5 &&+ Text.toLower s `elem` ["y", "yes", "n", "no", "true", "false", "on", "off"] isNumberOrDateRelated c = Char.isDigit c || c == '.' || c == 'e' || c == '-' style s = YS.schemaEncoderScalar Y.coreSchemaEncoder s schemaEncoder = YS.setScalarStyle style Y.coreSchemaEncoder+ encoder = Data.YAML.Aeson.encodeValue' schemaEncoder YT.UTF8
tasty/Main.hs view
@@ -1,21 +1,22 @@-{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedLists #-}+{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-} module Main where -import Data.Monoid ((<>))-import Dhall.JSON.Yaml (Options(..))-import Test.Tasty (TestTree)+import Data.Monoid ((<>))+import Dhall.JSON.Yaml (Options (..))+import Test.Tasty (TestTree) import qualified Data.ByteString import qualified Data.Text.IO import qualified Dhall.Core import qualified Dhall.JSON.Yaml import qualified Dhall.Yaml-import qualified Dhall.YamlToDhall as YamlToDhall+import qualified Dhall.YamlToDhall as YamlToDhall import qualified GHC.IO.Encoding import qualified Test.Tasty+import qualified Test.Tasty.ExpectedFailure as Tasty.ExpectedFailure import qualified Test.Tasty.HUnit main :: IO ()@@ -24,35 +25,57 @@ Test.Tasty.defaultMain testTree +data TestScope+ = SkipAesonYaml String -- ^ To skip aeson-yaml tests. "String" is to let us know why are we skipping it+ | SkipHsYAML String -- ^ As above, but for HsYAML+ | TestBoth -- ^ Tests both integrations+ testTree :: TestTree testTree = Test.Tasty.testGroup "dhall-yaml" [ testDhallToYaml Dhall.JSON.Yaml.defaultOptions- "./tasty/data/normal"+ "./tasty/data/normal" $+ SkipAesonYaml "aeson-yaml uses yaml 1.2 so it doesn't quotes yaml 1.1 boolean strings" , testDhallToYaml Dhall.JSON.Yaml.defaultOptions+ "./tasty/data/normal-aeson" $+ SkipHsYAML "HsYAML integration let us quotes boolean strings for backwards compatibility with yaml 1.1"+ , testDhallToYaml+ Dhall.JSON.Yaml.defaultOptions "./tasty/data/special"+ TestBoth , testDhallToYaml Dhall.JSON.Yaml.defaultOptions "./tasty/data/emptyList"+ TestBoth , testDhallToYaml Dhall.JSON.Yaml.defaultOptions "./tasty/data/emptyMap"+ TestBoth , testDhallToYaml (Dhall.JSON.Yaml.defaultOptions { quoted = True }) "./tasty/data/quoted"+ TestBoth+ , testDhallToYaml+ Dhall.JSON.Yaml.defaultOptions+ "./tasty/data/boolean-quotes" $+ SkipAesonYaml "this test is just for HsYAML integration" , testYamlToDhall "./tasty/data/mergify" ] -testDhallToYaml :: Options -> String -> TestTree-testDhallToYaml options prefix =- Test.Tasty.testGroup prefix- [ testCase Dhall.Yaml.dhallToYaml "HsYAML"- , testCase Dhall.JSON.Yaml.dhallToYaml "aeson-yaml"- ]+testDhallToYaml :: Options -> String -> TestScope -> TestTree+testDhallToYaml options prefix testScope =+ Test.Tasty.testGroup prefix (+ case testScope of+ SkipAesonYaml _ -> [hsYamlTest, Tasty.ExpectedFailure.expectFail hsAesonYamlTest]+ SkipHsYAML _ -> [hsAesonYamlTest, Tasty.ExpectedFailure.expectFail hsYamlTest]+ _ -> [hsYamlTest, hsAesonYamlTest]+ ) where+ hsYamlTest = testCase Dhall.Yaml.dhallToYaml "HsYAML"+ hsAesonYamlTest = testCase Dhall.JSON.Yaml.dhallToYaml "aeson-yaml" testCase dhallToYaml s = Test.Tasty.HUnit.testCase s $ do let inputFile = prefix <> ".dhall" let outputFile = prefix <> ".yaml"
+ tasty/data/boolean-quotes.dhall view
@@ -0,0 +1,7 @@+{ y_quoted = "y"+, yes_quoted = "yes"+, n_quoted = "n"+, no_quoted = "no"+, on_quoted = "on"+, off_quoted = "off"+}
+ tasty/data/boolean-quotes.yaml view
@@ -0,0 +1,6 @@+n_quoted: 'n'+no_quoted: 'no'+off_quoted: 'off'+on_quoted: 'on'+y_quoted: 'y'+yes_quoted: 'yes'
tasty/data/mergify.dhall view
@@ -3,7 +3,7 @@ { backport = None { branches : List Text } , delete_head_branch = None {} , label = None { remove : List Text }- , merge = Some { method = "squash", strict = "smart" }+ , `merge` = Some { method = "squash", strict = "smart" } } , conditions = [ "status-success=continuous-integration/appveyor/pr"@@ -16,7 +16,7 @@ { backport = None { branches : List Text } , delete_head_branch = Some {=} , label = None { remove : List Text }- , merge = None { method : Text, strict : Text }+ , `merge` = None { method : Text, strict : Text } } , conditions = [ "merged" ] , name = "Delete head branch after merge"@@ -25,7 +25,7 @@ { backport = Some { branches = [ "1.0.x" ] } , delete_head_branch = None {} , label = Some { remove = [ "backport-1.0" ] }- , merge = None { method : Text, strict : Text }+ , `merge` = None { method : Text, strict : Text } } , conditions = [ "merged", "label=backport-1.0" ] , name = "backport patches to 1.0.x branch"@@ -34,7 +34,7 @@ { backport = Some { branches = [ "1.1.x" ] } , delete_head_branch = None {} , label = Some { remove = [ "backport-1.1" ] }- , merge = None { method : Text, strict : Text }+ , `merge` = None { method : Text, strict : Text } } , conditions = [ "merged", "label=backport-1.1" ] , name = "backport patches to 1.1.x branch"@@ -43,7 +43,7 @@ { backport = Some { branches = [ "1.2.x" ] } , delete_head_branch = None {} , label = Some { remove = [ "backport-1.2" ] }- , merge = None { method : Text, strict : Text }+ , `merge` = None { method : Text, strict : Text } } , conditions = [ "merged", "label=backport-1.2" ] , name = "backport patches to 1.2.x branch"@@ -52,7 +52,7 @@ { backport = Some { branches = [ "1.3.x" ] } , delete_head_branch = None {} , label = Some { remove = [ "backport-1.3" ] }- , merge = None { method : Text, strict : Text }+ , `merge` = None { method : Text, strict : Text } } , conditions = [ "merged", "label=backport-1.3" ] , name = "backport patches to 1.3.x branch"@@ -61,7 +61,7 @@ { backport = Some { branches = [ "1.4.x" ] } , delete_head_branch = None {} , label = Some { remove = [ "backport-1.4" ] }- , merge = None { method : Text, strict : Text }+ , `merge` = None { method : Text, strict : Text } } , conditions = [ "merged", "label=backport-1.4" ] , name = "backport patches to 1.4.x branch"@@ -70,7 +70,7 @@ { backport = Some { branches = [ "1.5.x" ] } , delete_head_branch = None {} , label = Some { remove = [ "backport-1.5" ] }- , merge = None { method : Text, strict : Text }+ , `merge` = None { method : Text, strict : Text } } , conditions = [ "merged", "label=backport" ] , name = "backport patches to 1.5.x branch"
+ tasty/data/normal-aeson.dhall view
@@ -0,0 +1,8 @@+{ string_value = "2000-01-01"+, text = ./yaml.txt as Text+, int_value = 1+, bool_value = True+, bool_string = "true"+, yes = "y"+, hello_world = "hello world"+}
+ tasty/data/normal-aeson.yaml view
@@ -0,0 +1,8 @@+bool_string: 'true'+bool_value: true+hello_world: hello world+int_value: 1+string_value: '2000-01-01'+text: |+ Plain text+yes: y
tasty/data/normal.yaml view
@@ -5,4 +5,4 @@ string_value: '2000-01-01' text: | Plain text-yes: y+'yes': 'y'