yaml 0.11.5.0 → 0.11.6.0
raw patch · 6 files changed
+286/−70 lines, 6 filesdep +optparse-applicativedep −semigroupsPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies added: optparse-applicative
Dependencies removed: semigroups
API changes (from Hackage documentation)
+ Data.Yaml.Parser: instance Control.Monad.Fail.MonadFail Data.Yaml.Parser.YamlParser
- Data.Yaml: (.!=) :: () => Parser (Maybe a) -> a -> Parser a
+ Data.Yaml: (.!=) :: Parser (Maybe a) -> a -> Parser a
- Data.Yaml: parseEither :: () => (a -> Parser b) -> a -> Either String b
+ Data.Yaml: parseEither :: (a -> Parser b) -> a -> Either String b
- Data.Yaml: parseMaybe :: () => (a -> Parser b) -> a -> Maybe b
+ Data.Yaml: parseMaybe :: (a -> Parser b) -> a -> Maybe b
- Data.Yaml: parseMonad :: Monad m => (a -> Parser b) -> a -> m b
+ Data.Yaml: parseMonad :: MonadFail m => (a -> Parser b) -> a -> m b
- Data.Yaml: withArray :: () => String -> (Array -> Parser a) -> Value -> Parser a
+ Data.Yaml: withArray :: String -> (Array -> Parser a) -> Value -> Parser a
- Data.Yaml: withBool :: () => String -> (Bool -> Parser a) -> Value -> Parser a
+ Data.Yaml: withBool :: String -> (Bool -> Parser a) -> Value -> Parser a
- Data.Yaml: withObject :: () => String -> (Object -> Parser a) -> Value -> Parser a
+ Data.Yaml: withObject :: String -> (Object -> Parser a) -> Value -> Parser a
- Data.Yaml: withScientific :: () => String -> (Scientific -> Parser a) -> Value -> Parser a
+ Data.Yaml: withScientific :: String -> (Scientific -> Parser a) -> Value -> Parser a
- Data.Yaml: withText :: () => String -> (Text -> Parser a) -> Value -> Parser a
+ Data.Yaml: withText :: String -> (Text -> Parser a) -> Value -> Parser a
- Data.Yaml.TH: (.!=) :: () => Parser (Maybe a) -> a -> Parser a
+ Data.Yaml.TH: (.!=) :: Parser (Maybe a) -> a -> Parser a
Files
- ChangeLog.md +6/−0
- README.md +10/−2
- exe/Common.hs +68/−0
- exe/json2yaml.hs +101/−17
- exe/yaml2json.hs +79/−23
- yaml.cabal +22/−28
ChangeLog.md view
@@ -1,5 +1,11 @@ # ChangeLog for yaml +## 0.11.6.0++* `yaml2json`: add `--help` and `--version` options [#197](https://github.com/snoyberg/yaml/pull/197)+* `json2yaml`: add `--help` and `--version` options [#198](https://github.com/snoyberg/yaml/pull/198)+* Add the `-o` options to both `yaml2json` and `json2yaml` [#200](https://github.com/snoyberg/yaml/pull/200)+ ## 0.11.5.0 * New functions capable of parsing YAML streams containing multiple documents into a list of results:
README.md view
@@ -1,7 +1,7 @@ ## yaml -[](https://travis-ci.org/snoyberg/yaml)-[](https://ci.appveyor.com/project/snoyberg/yaml/branch/master)+[](https://github.com/snoyberg/yaml/actions/workflows/tests.yml)+[](https://ci.appveyor.com/project/snoyberg/yaml/branch/master) Provides support for parsing and emitting Yaml documents. @@ -16,3 +16,11 @@ * `Data.Yaml.Include` supports adding `!include` directives to your YAML files. * `Data.Yaml.Builder` and `Data.Yaml.Parser` allow more fine-grained control of parsing an rendering, as opposed to just using the aeson typeclass and datatype system for parsing and rendering. * `Data.Yaml.Aeson` is currently a re-export of `Data.Yaml` to explicitly choose to use the aeson-compatible API.++### Executables++Converters `json2yaml` and `yaml2json` can be built by disabling flag `no-exe`, e.g., one of:+```+cabal install yaml -f-no-exe+stack install yaml --flag yaml:-no-exe+```
+ exe/Common.hs view
@@ -0,0 +1,68 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE LambdaCase #-}++-- | Code shared between @yaml2json@ and @json2yaml@.++module Common where++import Data.List ( intercalate )+#if !MIN_VERSION_base(4,11,0)+import Data.Semigroup ( Semigroup(..) )+#endif+import Data.Version ( Version(versionBranch) )++import Options.Applicative ( Parser, help, hidden, infoOption, long, short )++import qualified Paths_yaml as Paths++-- * Version info and option+---------------------------------------------------------------------------++-- | Homepage for @yaml2json@ and @json2yaml@.++homepage :: String+homepage = "https://github.com/snoyberg/yaml/"++-- | Version in @x.y.z@ format.++version :: String+version = intercalate "." $ map show $ versionBranch Paths.version++-- | The version header including given program name and 'homepage'.++versionText :: String -> String+versionText self = unwords+ [ self+ , "version"+ , version+ , homepage -- concat [ "<", homepage, ">" ]+ ]++-- | Option @--numeric-version@.++numericVersionOption :: Parser (a -> a)+numericVersionOption =+ infoOption version+ $ long "numeric-version"+ <> hidden+ <> help "Show just version number."++-- | Option @--version@.++versionOption :: String -> Parser (a -> a)+versionOption self =+ infoOption (versionText self)+ $ long "version"+ <> short 'V'+ <> hidden+ <> help "Show version info."++-- * Misc+---------------------------------------------------------------------------++-- | @Just@ unless argument is @"-"@ (denoting @stdin@ or @stdout@).++dashToNothing :: FilePath -> Maybe FilePath+dashToNothing = \case+ "-" -> Nothing+ file -> Just file
exe/json2yaml.hs view
@@ -1,22 +1,106 @@-import qualified Data.Aeson as J-import qualified Data.ByteString as S+{-# LANGUAGE CPP #-}+{-# LANGUAGE NamedFieldPuns #-}++import qualified Data.Aeson as J+import qualified Data.ByteString as S import qualified Data.ByteString.Lazy as L-import System.Environment (getArgs)+import qualified Data.Yaml as Y+#if !MIN_VERSION_base(4,11,0)+import Data.Semigroup ( Semigroup(..) )+#endif -import qualified Data.Yaml as Y+import Options.Applicative+ ( Parser, (<|>)+ , action, execParser, footerDoc, headerDoc, help, helper, hidden, info+ , long, metavar, short, strArgument, strOption, value+ )+import Options.Applicative.Help.Pretty+ ( vcat, text ) +import System.Exit ( die )++import Common ( dashToNothing, versionText, versionOption, numericVersionOption )++data Options = Options+ { optInput :: Maybe FilePath+ -- ^ 'Nothing' means @stdin@.+ , optOutput :: Maybe FilePath+ -- ^ 'Nothing' means @stdout@.+ }++-- | Name of the executable.++self :: String+self = "json2yaml"++-- | Parse options; handle parse errors, @--help@, @--version@.++options :: IO Options+options =+ execParser $+ info (helper <*> versionOption self <*> numericVersionOption <*> programOptions)+ $ headerDoc hdoc+ <> footerDoc fdoc++ where+ hdoc = Just $ vcat $ map text+ [ versionText self+ , "Convert JSON to YAML."+ ]+ fdoc = Just $ text $ concat+ [ "The old call pattern '"+ , self+ , " IN OUT' is also accepted, but deprecated."+ ]++ programOptions :: Parser Options+ programOptions = Options <$> oInput <*> oOutput++ oInput :: Parser (Maybe FilePath)+ oInput = dashToNothing <$> do+ strArgument+ $ metavar "IN"+ <> value "-"+ <> action "file"+ <> help "The input file containing the JSON document; use '-' for stdin (default)."++ oOutput :: Parser (Maybe FilePath)+ oOutput = dashToNothing <$> do+ oOutputExplicit <|> oOutputImplicit++ oOutputExplicit :: Parser FilePath+ oOutputExplicit =+ strOption+ $ long "output"+ <> short 'o'+ <> metavar "OUT"+ <> action "file"+ -- <> help "The file to hold the produced YAML document; use '-' for stdout (default)."++ oOutputImplicit :: Parser FilePath+ oOutputImplicit =+ strArgument+ $ metavar "OUT"+ <> value "-"+ <> action "file"+ <> hidden+ <> help "The file to hold the produced YAML document; use '-' for stdout (default)."++-- | Exit with 'self'-stamped error message.++abort :: String -> IO a+abort msg = die $ concat [ self, ": ", msg ]+ main :: IO () main = do- args <- getArgs- (input, output) <- case args ++ replicate (2 - length args) "-" of- [i, o] -> return (i, o)- _ -> fail "Usage: json2yaml [in] [out]"- mval <- fmap J.decode $- case input of- "-" -> L.getContents- _ -> L.readFile input- case mval of- Nothing -> error "Invalid input JSON"- Just val -> case output of- "-" -> S.putStr $ Y.encode (val :: Y.Value)- _ -> Y.encodeFile output val+ Options{ optInput, optOutput } <- options++ -- Read JSON.+ mval <- J.decode <$> maybe L.getContents L.readFile optInput++ -- Write YAML.+ case mval of+ Nothing -> abort "Invalid input JSON"+ Just val -> case optOutput of+ Nothing -> S.putStr $ Y.encode (val :: Y.Value)+ Just f -> Y.encodeFile f val
exe/yaml2json.hs view
@@ -1,31 +1,87 @@-import Prelude hiding (putStr, getContents)+{-# LANGUAGE CPP #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE NamedFieldPuns #-} -import Data.Aeson (encode, Value)-import Data.ByteString (getContents)-import Data.ByteString.Lazy (putStr)-import System.Environment (getArgs)-import System.Exit-import System.IO (stderr, hPutStrLn)+import Data.Aeson (encode, Value)+import qualified Data.ByteString as S (getContents)+import qualified Data.ByteString.Lazy as L (putStr, writeFile)+#if !MIN_VERSION_base(4,11,0)+import Data.Semigroup (Semigroup(..))+#endif+import Data.Yaml (decodeFileEither, decodeEither')+import System.Exit (die) -import Data.Yaml (decodeFileEither, decodeEither')+import Options.Applicative+ ( Parser+ , action, execParser, headerDoc, help, helper, info+ , long, metavar, short, strArgument, strOption, value+ )+import Options.Applicative.Help.Pretty+ ( vcat, text ) -helpMessage :: IO ()-helpMessage = putStrLn "Usage: yaml2json FILE\n\nuse '-' as FILE to indicate stdin" >> exitFailure+import Common+ ( versionText, versionOption, numericVersionOption, dashToNothing ) -showJSON :: Show a => Either a Value -> IO b-showJSON ejson =- case ejson of- Left err -> hPutStrLn stderr (show err) >> exitFailure- Right res -> putStr (encode (res :: Value)) >> exitSuccess+data Options = Options+ { optInput :: Maybe FilePath+ -- ^ 'Nothing' means @stdin@.+ , optOutput :: Maybe FilePath+ -- ^ 'Nothing' means @stdout@.+ } +-- | Name of the executable.++self :: String+self = "yaml2json"++-- | Parse options; handle parse errors, @--help@, @--version@.++options :: IO Options+options =+ execParser $+ info (helper <*> versionOption self <*> numericVersionOption <*> programOptions)+ (headerDoc hdoc)++ where+ hdoc = Just $ vcat $ map text+ [ versionText self+ , "Convert YAML to JSON."+ ]++ programOptions = Options <$> oInput <*> oOutput++ oInput :: Parser (Maybe FilePath)+ oInput = dashToNothing <$> do+ strArgument+ $ metavar "IN"+ <> value "-"+ <> action "file"+ <> help "The input file containing the YAML document; use '-' for stdin (default)."++ oOutput :: Parser (Maybe FilePath)+ oOutput = dashToNothing <$> do+ strOption+ $ long "output"+ <> short 'o'+ <> value "-"+ <> metavar "OUT"+ <> action "file"+ <> help "The file to hold the produced JSON document; use '-' for stdout (default)."++ main :: IO () main = do- args <- getArgs- case args of- -- strict getContents will read in all of stdin at once- (["-h"]) -> helpMessage- (["--help"]) -> helpMessage- (["-"]) -> getContents >>= showJSON . decodeEither'- ([f]) -> decodeFileEither f >>= showJSON- _ -> helpMessage+ Options{ optInput, optOutput } <- options + -- Input YAML.+ result <- case optInput of+ -- strict getContents will read in all of stdin at once+ Nothing -> decodeEither' <$> S.getContents+ Just f -> decodeFileEither f++ -- Output JSON.+ case result of+ Left err -> die $ show err+ Right val -> do+ let json = encode (val :: Value)+ maybe L.putStr L.writeFile optOutput json
yaml.cabal view
@@ -1,13 +1,11 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.33.0.+-- This file has been generated from package.yaml by hpack version 0.34.4. -- -- see: https://github.com/sol/hpack------ hash: 55c85c8d4d3074a558a82e30a2592ecff9db2e6f1571547c73d26ba44bfc1c20 name: yaml-version: 0.11.5.0+version: 0.11.6.0 synopsis: Support for parsing and rendering YAML documents. description: README and API documentation are available at <https://www.stackage.org/package/yaml> category: Data@@ -62,8 +60,9 @@ Paths_yaml hs-source-dirs: src- other-extensions: LambdaCase- ghc-options: -Wall+ other-extensions:+ LambdaCase+ ghc-options: -Wall -Wcompat build-depends: aeson >=0.11 , attoparsec >=0.11.3.0@@ -73,7 +72,7 @@ , containers , directory , filepath- , libyaml >=0.1 && <0.2+ , libyaml ==0.1.* , mtl , resourcet >=0.3 && <1.3 , scientific >=0.3@@ -82,9 +81,6 @@ , transformers >=0.1 , unordered-containers , vector- if !impl(ghc >= 8.0)- build-depends:- semigroups default-language: Haskell2010 executable examples@@ -95,7 +91,7 @@ Paths_yaml hs-source-dirs: examples- ghc-options: -Wall+ ghc-options: -Wall -Wcompat build-depends: aeson >=0.11 , attoparsec >=0.11.3.0@@ -105,7 +101,7 @@ , containers , directory , filepath- , libyaml >=0.1 && <0.2+ , libyaml ==0.1.* , mtl , resourcet >=0.3 && <1.3 , scientific >=0.3@@ -114,9 +110,6 @@ , transformers >=0.1 , unordered-containers , vector- if !impl(ghc >= 8.0)- build-depends:- semigroups if flag(no-examples) buildable: False else@@ -128,9 +121,11 @@ executable json2yaml main-is: json2yaml.hs other-modules:+ Common Paths_yaml hs-source-dirs: exe+ ghc-options: -Wall -Wcompat build-depends: aeson >=0.11 , attoparsec >=0.11.3.0@@ -140,8 +135,9 @@ , containers , directory , filepath- , libyaml >=0.1 && <0.2+ , libyaml ==0.1.* , mtl+ , optparse-applicative , resourcet >=0.3 && <1.3 , scientific >=0.3 , template-haskell@@ -150,9 +146,6 @@ , unordered-containers , vector , yaml- if !impl(ghc >= 8.0)- build-depends:- semigroups if flag(no-exe) buildable: False default-language: Haskell2010@@ -160,9 +153,15 @@ executable yaml2json main-is: yaml2json.hs other-modules:+ Common Paths_yaml hs-source-dirs: exe+ other-extensions:+ CPP+ LambdaCase+ NamedFieldPuns+ ghc-options: -Wall -Wcompat build-depends: aeson >=0.11 , attoparsec >=0.11.3.0@@ -172,8 +171,9 @@ , containers , directory , filepath- , libyaml >=0.1 && <0.2+ , libyaml ==0.1.* , mtl+ , optparse-applicative , resourcet >=0.3 && <1.3 , scientific >=0.3 , template-haskell@@ -182,9 +182,6 @@ , unordered-containers , vector , yaml- if !impl(ghc >= 8.0)- build-depends:- semigroups if flag(no-exe) buildable: False default-language: Haskell2010@@ -199,7 +196,7 @@ Paths_yaml hs-source-dirs: test- ghc-options: -Wall "-with-rtsopts=-K1K"+ ghc-options: -Wall -Wcompat -with-rtsopts=-K1K cpp-options: -DTEST build-depends: HUnit@@ -213,7 +210,7 @@ , directory , filepath , hspec >=1.3- , libyaml >=0.1 && <0.2+ , libyaml ==0.1.* , mockery , mtl , raw-strings-qq@@ -226,7 +223,4 @@ , unordered-containers , vector , yaml- if !impl(ghc >= 8.0)- build-depends:- semigroups default-language: Haskell2010