language-nix 2.1.0.1 → 2.2.0
raw patch · 5 files changed
+109/−136 lines, 5 filesdep +parsec-classdep −Cabaldep −base-compatdep −doctestPVP ok
version bump matches the API change (PVP)
Dependencies added: parsec-class
Dependencies removed: Cabal, base-compat, doctest
API changes (from Hackage documentation)
- Language.Nix.Binding: instance Distribution.Text.Text Language.Nix.Binding.Binding
- Language.Nix.Binding: instance GHC.Generics.Constructor Language.Nix.Binding.C1_0Binding
- Language.Nix.Binding: instance GHC.Generics.Datatype Language.Nix.Binding.D1Binding
- Language.Nix.Identifier: instance Distribution.Text.Text Language.Nix.Identifier.Identifier
- Language.Nix.Identifier: instance GHC.Generics.Constructor Language.Nix.Identifier.C1_0Identifier
- Language.Nix.Identifier: instance GHC.Generics.Datatype Language.Nix.Identifier.D1Identifier
- Language.Nix.Path: instance Distribution.Text.Text Language.Nix.Path.Path
- Language.Nix.Path: instance GHC.Generics.Constructor Language.Nix.Path.C1_0Path
- Language.Nix.Path: instance GHC.Generics.Datatype Language.Nix.Path.D1Path
+ Language.Nix.Binding: instance Test.QuickCheck.Arbitrary.CoArbitrary Language.Nix.Binding.Binding
+ Language.Nix.Binding: instance Text.Parsec.Class.HasParser Language.Nix.Binding.Binding
+ Language.Nix.Binding: instance Text.PrettyPrint.HughesPJClass.Pretty Language.Nix.Binding.Binding
+ Language.Nix.Identifier: instance Test.QuickCheck.Arbitrary.CoArbitrary Language.Nix.Identifier.Identifier
+ Language.Nix.Identifier: instance Text.Parsec.Class.HasParser Language.Nix.Identifier.Identifier
+ Language.Nix.Identifier: instance Text.PrettyPrint.HughesPJClass.Pretty Language.Nix.Identifier.Identifier
+ Language.Nix.Path: instance Test.QuickCheck.Arbitrary.CoArbitrary Language.Nix.Path.Path
+ Language.Nix.Path: instance Text.Parsec.Class.HasParser Language.Nix.Path.Path
+ Language.Nix.Path: instance Text.PrettyPrint.HughesPJClass.Pretty Language.Nix.Path.Path
- Language.Nix.Identifier: parseQuotedIdentifier :: ReadP r Identifier
+ Language.Nix.Identifier: parseQuotedIdentifier :: CharParser st tok m Identifier
- Language.Nix.Identifier: parseSimpleIdentifier :: ReadP r Identifier
+ Language.Nix.Identifier: parseSimpleIdentifier :: CharParser st tok m Identifier
Files
- language-nix.cabal +27/−54
- src/Language/Nix/Binding.hs +30/−29
- src/Language/Nix/Identifier.hs +31/−27
- src/Language/Nix/Path.hs +21/−20
- test/Main.hs +0/−6
language-nix.cabal view
@@ -1,60 +1,33 @@--- This file has been generated from package.yaml by hpack version 0.12.0.------ see: https://github.com/sol/hpack--name: language-nix-version: 2.1.0.1-synopsis: Data types and useful functions to represent and manipulate the Nix language.-description: Data types and useful functions to represent and manipulate the Nix language.-category: Distribution, Language-homepage: https://github.com/peti/language-nix#readme-bug-reports: https://github.com/peti/language-nix/issues-author: Peter Simons-maintainer: simons@cryp.to-license: BSD3-license-file: LICENSE-tested-with: GHC == 7.6.3, GHC == 7.8.4, GHC == 7.10.3, GHC == 8.0.1-build-type: Simple-cabal-version: >= 1.10+name: language-nix+version: 2.2.0+synopsis: Data types and functions to represent the Nix language+description: Data types and useful functions to represent and manipulate the Nix+ language.+license: BSD3+license-file: LICENSE+author: Peter Simons+maintainer: simons@cryp.to+tested-with: GHC == 8.2.2, GHC == 8.4.4, GHC == 8.6.5, GHC == 8.8.1+category: Distribution, Language, Nix+homepage: https://github.com/peti/language-nix#readme+bug-reports: https://github.com/peti/language-nix/issues+build-type: Simple+cabal-version: >= 1.10 source-repository head- type: git+ type: git location: https://github.com/peti/language-nix library- hs-source-dirs:- src- ghc-options: -Wall- build-depends:- base < 5- , base-compat- , Cabal- , deepseq- , lens- , pretty- , QuickCheck- exposed-modules:- Language.Nix- Language.Nix.Binding- Language.Nix.Identifier- Language.Nix.Path- other-modules:- Paths_language_nix- default-language: Haskell2010--test-suite spec- type: exitcode-stdio-1.0- main-is: Main.hs- hs-source-dirs:- test- ghc-options: -Wall- build-depends:- base < 5- , base-compat- , Cabal- , deepseq- , lens- , pretty- , QuickCheck- , doctest+ exposed-modules: Language.Nix+ Language.Nix.Binding+ Language.Nix.Identifier+ Language.Nix.Path+ other-modules: Paths_language_nix+ hs-source-dirs: src+ build-depends: base < 5, QuickCheck, deepseq, lens, parsec-class, pretty default-language: Haskell2010+ other-extensions: FlexibleContexts+ TemplateHaskell+ GeneralizedNewtypeDeriving+ DeriveGeneric
src/Language/Nix/Binding.hs view
@@ -1,5 +1,5 @@ {-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE NoImplicitPrelude #-}+{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE TemplateHaskell #-} module Language.Nix.Binding ( Binding, binding, localName, reference ) where@@ -8,14 +8,12 @@ import Control.Lens import Data.Maybe import Data.String-import Distribution.Compat.ReadP as ReadP-import Distribution.Text import GHC.Generics ( Generic ) import Language.Nix.Identifier import Language.Nix.Path-import Prelude.Compat import Test.QuickCheck-import Text.PrettyPrint as PP+import Text.Parsec.Class as P+import Text.PrettyPrint.HughesPJClass as PP -- | A 'Binding' represents an identifier that refers to some other 'Path'. --@@ -23,7 +21,7 @@ -- >>> "inherit (foo.bar) abc" :: Binding -- Bind (Identifier "abc") (Path [Identifier "foo",Identifier "bar",Identifier "abc"]) ----- prop> \b -> Just (b :: Binding) == simpleParse (display b)+-- prop> \b -> Just (b :: Binding) == parseM "Binding" (prettyShow b) declareLenses [d| data Binding = Bind { localName :: Identifier, reference :: Path } deriving (Show, Eq, Ord, Generic)@@ -38,34 +36,37 @@ instance Arbitrary Binding where arbitrary = review binding <$> arbitrary -instance Text Binding where- disp b = case (init ps, last ps) of- ([], i') -> if i == i'- then text "inherit" <+> disp i'- else disp i <+> equals <+> disp p- (p', i') -> if i == i'- then text "inherit" <+> parens (disp (path # p')) <+> disp i'- else disp i <+> equals <+> disp p+instance CoArbitrary Binding - where- (i, p) = view binding b- ps = view path p+instance Pretty Binding where+ pPrint b = case (init ps, last ps) of+ ([], i') -> if i == i'+ then text "inherit" <+> pPrint i'+ else pPrint i <+> equals <+> pPrint p+ (p', i') -> if i == i'+ then text "inherit" <+> parens (pPrint (path # p')) <+> pPrint i'+ else pPrint i <+> equals <+> pPrint p - parse = parseAssignment +++ parseInherit+ where+ (i, p) = view binding b+ ps = view path p +instance HasParser Binding where+ parser = try parseInherit <|> parseAssignment+ instance IsString Binding where- fromString s = fromMaybe (error ("invalid Nix binding: " ++ s)) (simpleParse s)+ fromString = parse "Language.Nix.Binding.Binding" -parseAssignment :: ReadP r Binding-parseAssignment = do l <- skipSpaces >> parse- _ <- skipSpaces >> ReadP.char '='- r <- skipSpaces >> parse+parseAssignment :: CharParser st tok m Binding+parseAssignment = do l <- spaces >> parser+ _ <- spaces >> P.char '='+ r <- spaces >> parser return (binding # (l,r)) -parseInherit :: ReadP r Binding-parseInherit = do _ <- skipSpaces >> ReadP.string "inherit"- p <- option [] $ between (skipSpaces >> ReadP.char '(')- (skipSpaces >> ReadP.char ')')- (skipSpaces >> view path <$> parse)- i <- skipSpaces >> parse+parseInherit :: CharParser st tok m Binding+parseInherit = do _ <- spaces >> P.string "inherit" >> lookAhead (P.space <|> P.char '(')+ p <- option [] $ try $ between (spaces >> P.char '(')+ (spaces >> P.char ')')+ (spaces >> view path <$> parser)+ i <- spaces >> parser return (binding # (i, path # (p ++ [i])))
src/Language/Nix/Identifier.hs view
@@ -1,6 +1,6 @@ {-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE TemplateHaskell #-} module Language.Nix.Identifier@@ -12,13 +12,12 @@ import Control.DeepSeq import Control.Lens import Data.Char+import Data.Either import Data.String-import Distribution.Compat.ReadP as ReadP-import Distribution.Text import GHC.Generics ( Generic )-import Prelude.Compat import Test.QuickCheck-import Text.PrettyPrint as PP+import Text.Parsec.Class as P+import Text.PrettyPrint.HughesPJClass as PP -- | Identifiers in Nix are essentially strings. They can be constructed -- (and viewed) with the 'ident' isomorphism. For the sake of convenience,@@ -29,13 +28,13 @@ -- methods of the 'Text' class can be used to parse and pretty-print an -- identifier with proper quoting: ----- >>> disp (ident # "test")+-- >>> pPrint (ident # "test") -- test--- >>> disp (ident # "foo.bar")+-- >>> pPrint (ident # "foo.bar") -- "foo.bar" ----- prop> \str -> Just (ident # str) == simpleParse (quote str)--- prop> \i -> Just (i :: Identifier) == simpleParse (display i)+-- prop> \str -> Just (ident # str) == parseM "Ident" (quote str)+-- prop> \i -> Just (i :: Identifier) == parseM "Ident" (prettyShow i) declareLenses [d| newtype Identifier = Identifier { ident :: String } deriving (Show, Eq, Ord, IsString, Generic) |]@@ -50,42 +49,47 @@ rnf (Identifier str) = rnf str instance Arbitrary Identifier where- arbitrary = Identifier <$> arbitrary+ arbitrary = Identifier <$> listOf1 arbitraryUnicodeChar shrink (Identifier i) = map Identifier (shrink i) -instance Text Identifier where- disp = view (ident . to quote . to text)- parse = parseQuotedIdentifier <++ parseSimpleIdentifier+instance CoArbitrary Identifier --- | 'ReadP' parser for simple identifiers, i.e. those that don't need--- quoting.-parseSimpleIdentifier :: ReadP r Identifier+instance Pretty Identifier where+ pPrint = view (ident . to quote . to text)++instance HasParser Identifier where+ parser = parseQuotedIdentifier <|> parseSimpleIdentifier++-- | Parsec parser for simple identifiers, i.e. those that don't need quoting.+parseSimpleIdentifier :: CharParser st tok m Identifier parseSimpleIdentifier = do c <- satisfy (\x -> x == '_' || isAlpha x)- cs <- munch (\x -> x `elem` "_'-" || isAlphaNum x)+ cs <- many (satisfy (\x -> x `elem` "_'-" || isAlphaNum x)) return (Identifier (c:cs)) -- | 'ReadP' parser for quoted identifiers, i.e. those that /do/ need -- quoting.-parseQuotedIdentifier :: ReadP r Identifier-parseQuotedIdentifier = Identifier . read . fst- <$> gather (between (ReadP.char '"') (ReadP.char '"') (many qString))+parseQuotedIdentifier :: CharParser st tok m Identifier+parseQuotedIdentifier = Identifier <$> qstring where- qString :: ReadP r String- qString = quotedPair <++ munch1 (`notElem` "\\\"")+ qstring :: CharParser st tok m String+ qstring = do txt <- between (P.char '"') (P.char '"') (many qtext)+ return (read ('"' : concat txt ++ ['"'])) - quotedPair :: ReadP r String+ qtext :: CharParser st tok m String+ qtext = quotedPair <|> many1 (P.noneOf "\\\"")++ quotedPair :: CharParser st tok m String quotedPair = do- c1 <- ReadP.char '\\'- c2 <- get+ c1 <- P.char '\\'+ c2 <- anyChar return [c1,c2] -- | Checks whether a given string needs quoting when interpreted as an -- 'Identifier'. Simple identifiers that don't need quoting match the -- regular expression @^[a-zA-Z_][a-zA-Z0-9_'-]*$@. needsQuoting :: String -> Bool-needsQuoting s = null r || not (any (null . snd) r)- where r = readP_to_S parseSimpleIdentifier s+needsQuoting = isLeft . runParser (parseSimpleIdentifier >> eof) () "" -- | Helper function to quote a given identifier string if necessary. --
src/Language/Nix/Path.hs view
@@ -1,5 +1,4 @@ {-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE TemplateHaskell #-} module Language.Nix.Path ( Path, path ) where@@ -8,16 +7,14 @@ import Control.Lens import Data.Maybe import Data.String-import Distribution.Compat.ReadP as ReadP-import Distribution.Text import GHC.Generics ( Generic ) import Language.Nix.Identifier-import Prelude.Compat import Test.QuickCheck-import Text.PrettyPrint as PP+import Text.Parsec.Class as P+import Text.PrettyPrint.HughesPJClass as PP -- $setup--- >>> import Control.Exception+-- >>> import Control.Exception as Excpt -- | Paths are non-empty lists of identifiers in Nix. --@@ -27,33 +24,33 @@ -- Any attempt to construct the empty path throws an 'error': -- -- >>> :set -XScopedTypeVariables--- >>> either (\(_::SomeException) -> "empty paths are illegal") show <$> try (evaluate (path # []))+-- >>> either (\(_::SomeException) -> "empty paths are illegal") show <$> Excpt.try (evaluate (path # [])) -- "empty paths are illegal" -- -- Paths can be pretty-printed and parsed with the 'Text' class: ----- >>> simpleParse "foo.\"foo.bar\".bar" :: Maybe Path--- Just (Path [Identifier "foo",Identifier "foo.bar",Identifier "bar"])--- >>> maybe empty disp (simpleParse "foo.\"foo\".\"bar\".bar" :: Maybe Path)+-- >>> parse "Path" "foo.\"foo.bar\".bar" :: Path+-- Path [Identifier "foo",Identifier "foo.bar",Identifier "bar"]+-- >>> pPrint (parse "Path" "foo.\"foo\".\"bar\".bar" :: Path) -- foo.foo.bar.bar ----- prop> \p -> Just (p :: Path) == simpleParse (display p)+-- prop> \p -> Just (p :: Path) == parseM "Path" (prettyShow p) -- -- Paths are instances of strings and can be implicitly converted: -- -- >>> :set -XOverloadedStrings--- >>> disp $ ("yo.bar" :: Path)+-- >>> pPrint $ ("yo.bar" :: Path) -- yo.bar--- >>> disp $ (" yo . bar " :: Path)+-- >>> pPrint $ (" yo . bar" :: Path) -- yo.bar -- -- Freaky quoted identifiers are fine throughout: ----- >>> disp $ path # ["yo","b\"ar"]+-- >>> pPrint $ path # ["yo","b\"ar"] -- yo."b\"ar"--- >>> disp ("\"5ident\"" :: Path)+-- >>> pPrint ("\"5ident\"" :: Path) -- "5ident"--- >>> disp $ path # ["5ident","foo.bar","foo\nbar"]+-- >>> pPrint $ path # ["5ident","foo.bar","foo\nbar"] -- "5ident"."foo.bar"."foo\nbar" declareLenses [d| newtype Path = Path [Identifier]@@ -63,15 +60,19 @@ instance NFData Path where rnf (Path p) = rnf p -instance Text Path where- disp p = hcat $ punctuate (PP.char '.') (map disp (p^.path))- parse = review path <$> sepBy (skipSpaces >> parse) (skipSpaces >> ReadP.char '.')+instance Pretty Path where+ pPrint p = hcat $ punctuate (PP.char '.') (map pPrint (p^.path)) +instance HasParser Path where+ parser = review path <$> (spaces >> parser) `sepBy` (spaces >> P.char '.')+ instance IsString Path where- fromString s = fromMaybe (error ("invalid Nix path: " ++ s)) (simpleParse s)+ fromString = parse "Language.Nix.Path.Path" instance Arbitrary Path where arbitrary = Path <$> listOf1 arbitrary++instance CoArbitrary Path -- | Use this isomorphism to construct a path from a list of identifiers, or to -- access that list for a given path.
− test/Main.hs
@@ -1,6 +0,0 @@-module Main ( main ) where--import Test.DocTest--main :: IO ()-main = doctest [ "-isrc", "src" ]