hpack 0.34.7 → 0.35.0
raw patch · 11 files changed
+547/−143 lines, 11 filesdep ~Cabaldep ~basePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: Cabal, base
API changes (from Hackage documentation)
- Hpack.Config: instance GHC.Generics.Generic Hpack.Config.BuildType
+ Hpack.Config: Language :: String -> Language
+ Hpack.Config: [sectionLanguage] :: Section a -> Maybe Language
+ Hpack.Config: instance Data.Aeson.Config.FromValue.FromValue Hpack.Config.Language
+ Hpack.Config: instance Data.String.IsString Hpack.Config.Language
+ Hpack.Config: instance GHC.Classes.Eq Hpack.Config.Language
+ Hpack.Config: instance GHC.Show.Show Hpack.Config.Language
+ Hpack.Config: newtype Language
+ Hpack.Yaml: Alias :: a -> Alias (deprecated :: Bool) (alias :: Symbol) a
+ Hpack.Yaml: newtype Alias (deprecated :: Bool) (alias :: Symbol) a
+ Hpack.Yaml: unAlias :: Alias deprecated alias a -> a
- Hpack.Config: Section :: a -> [FilePath] -> Dependencies -> [String] -> [String] -> [String] -> [GhcOption] -> [GhcProfOption] -> [GhcjsOption] -> [CppOption] -> [CcOption] -> [Path] -> [CxxOption] -> [Path] -> [Path] -> [FilePath] -> [FilePath] -> [FilePath] -> [FilePath] -> [FilePath] -> [FilePath] -> [LdOption] -> Maybe Bool -> [Conditional (Section a)] -> Map BuildTool DependencyVersion -> SystemBuildTools -> [Verbatim] -> Section a
+ Hpack.Config: Section :: a -> [FilePath] -> Dependencies -> [String] -> [String] -> [String] -> Maybe Language -> [GhcOption] -> [GhcProfOption] -> [GhcjsOption] -> [CppOption] -> [CcOption] -> [Path] -> [CxxOption] -> [Path] -> [Path] -> [FilePath] -> [FilePath] -> [FilePath] -> [FilePath] -> [FilePath] -> [FilePath] -> [LdOption] -> Maybe Bool -> [Conditional (Section a)] -> Map BuildTool DependencyVersion -> SystemBuildTools -> [Verbatim] -> Section a
- Hpack.Yaml: type Result a = Either String (a, [String])
+ Hpack.Yaml: type Result a = Either String (a, [String], [(String, String)])
Files
- CHANGELOG.md +6/−0
- hpack.cabal +2/−2
- src/Data/Aeson/Config/FromValue.hs +52/−6
- src/Data/Aeson/Config/Parser.hs +17/−7
- src/Hpack/Config.hs +51/−27
- src/Hpack/Render.hs +10/−10
- test/Data/Aeson/Config/FromValueSpec.hs +161/−6
- test/EndToEndSpec.hs +232/−70
- test/Hpack/ConfigSpec.hs +12/−1
- test/Hpack/RenderSpec.hs +3/−13
- test/Hpack/Syntax/DependenciesSpec.hs +1/−1
CHANGELOG.md view
@@ -1,3 +1,9 @@+## Changes in 0.35.0+ - Add support for `language` (thanks @mpilgrem)+ - Accept Cabal names for fields where Hpack and Cabal use different+ terminology, but still warn (e.g. accept `hs-source-dirs` as an alias for+ `source-dirs`)+ ## Changes in 0.34.7 - Support `Cabal-3.6.*` - Make sure that verbatim `import` fields are rendered at the beginning of
hpack.cabal view
@@ -1,11 +1,11 @@ cabal-version: 1.12 --- This file has been generated from package.yaml by hpack version 0.34.6.+-- This file has been generated from package.yaml by hpack version 0.34.7. -- -- see: https://github.com/sol/hpack name: hpack-version: 0.34.7+version: 0.35.0 synopsis: A modern format for Haskell packages description: See README at <https://github.com/sol/hpack#readme> category: Development
src/Data/Aeson/Config/FromValue.hs view
@@ -6,8 +6,11 @@ {-# LANGUAGE TypeOperators #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE RecordWildCards #-}- {-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE DeriveFunctor #-} module Data.Aeson.Config.FromValue ( FromValue(..) , Parser@@ -38,17 +41,24 @@ , Value(..) , Object , Array++, Alias(..)+, unAlias ) where import Imports +import Data.Monoid (Last(..)) import GHC.Generics+import GHC.TypeLits+import Data.Proxy import Data.Map.Lazy (Map) import qualified Data.Map.Lazy as Map import qualified Data.Vector as V import Data.Aeson.Config.Key (Key) import qualified Data.Aeson.Config.Key as Key+import Data.Aeson.Config.KeyMap (member) import qualified Data.Aeson.Config.KeyMap as KeyMap import Data.Aeson.Types (FromJSON(..))@@ -56,7 +66,7 @@ import Data.Aeson.Config.Util import Data.Aeson.Config.Parser -type Result a = Either String (a, [String])+type Result a = Either String (a, [String], [(String, String)]) decodeValue :: FromValue a => Value -> Result a decodeValue = runParser fromValue@@ -137,13 +147,49 @@ instance (GenericDecode a, GenericDecode b) => GenericDecode (a :*: b) where genericDecode opts o = (:*:) <$> genericDecode opts o <*> genericDecode opts o -instance (Selector sel, FromValue a) => GenericDecode (S1 sel (Rec0 a)) where+type RecordField sel a = S1 sel (Rec0 a)++instance (Selector sel, FromValue a) => GenericDecode (RecordField sel a) where genericDecode = accessFieldWith (.:) -instance {-# OVERLAPPING #-} (Selector sel, FromValue a) => GenericDecode (S1 sel (Rec0 (Maybe a))) where+instance {-# OVERLAPPING #-} (Selector sel, FromValue a) => GenericDecode (RecordField sel (Maybe a)) where genericDecode = accessFieldWith (.:?) -accessFieldWith :: forall sel a p. Selector sel => (Object -> Key -> Parser a) -> Options -> Value -> Parser (S1 sel (Rec0 a) p)+instance {-# OVERLAPPING #-} (Selector sel, FromValue a) => GenericDecode (RecordField sel (Last a)) where+ genericDecode = accessFieldWith (\ value key -> Last <$> (value .:? key))++instance {-# OVERLAPPING #-} (Selector sel, FromValue a, KnownBool deprecated, KnownSymbol alias) => GenericDecode (RecordField sel (Alias deprecated alias (Maybe a))) where+ genericDecode = accessFieldWith (\ value key -> aliasAccess (.:?) value (Alias key))++instance {-# OVERLAPPING #-} (Selector sel, FromValue a, KnownBool deprecated, KnownSymbol alias) => GenericDecode (RecordField sel (Alias deprecated alias (Last a))) where+ genericDecode = accessFieldWith (\ value key -> fmap Last <$> aliasAccess (.:?) value (Alias key))++aliasAccess :: forall deprecated alias a. (KnownBool deprecated, KnownSymbol alias) => (Object -> Key -> Parser a) -> Object -> (Alias deprecated alias Key) -> Parser (Alias deprecated alias a)+aliasAccess op value (Alias key)+ | alias `member` value && not (key `member` value) = Alias <$> value `op` alias <* deprecated+ | otherwise = Alias <$> value `op` key+ where+ deprecated = case boolVal (Proxy @deprecated) of+ False -> return ()+ True -> markDeprecated alias key+ alias = Key.fromString (symbolVal $ Proxy @alias)++accessFieldWith :: forall sel a p. Selector sel => (Object -> Key -> Parser a) -> Options -> Value -> Parser (RecordField sel a p) accessFieldWith op Options{..} v = M1 . K1 <$> withObject (`op` Key.fromString label) v where- label = optionsRecordSelectorModifier $ selName (undefined :: S1 sel (Rec0 a) p)+ label = optionsRecordSelectorModifier $ selName (undefined :: RecordField sel a p)++newtype Alias (deprecated :: Bool) (alias :: Symbol) a = Alias a+ deriving (Show, Eq, Semigroup, Monoid, Functor)++unAlias :: Alias deprecated alias a -> a+unAlias (Alias a) = a++class KnownBool (a :: Bool) where+ boolVal :: Proxy a -> Bool++instance KnownBool 'True where+ boolVal _ = True++instance KnownBool 'False where+ boolVal _ = False
src/Data/Aeson/Config/Parser.hs view
@@ -28,6 +28,8 @@ , fromAesonPath , formatPath++, markDeprecated ) where import Imports@@ -56,6 +58,9 @@ type JSONPath = [JSONPathElement] +data Path = Consumed JSONPath | Deprecated JSONPath JSONPath+ deriving (Eq, Ord, Show)+ fromAesonPath :: Aeson.JSONPath -> JSONPath fromAesonPath = reverse . map fromAesonPathElement @@ -64,16 +69,16 @@ Aeson.Key k -> Key (Key.toText k) Aeson.Index n -> Index n -newtype Parser a = Parser {unParser :: WriterT (Set JSONPath) Aeson.Parser a}+newtype Parser a = Parser {unParser :: WriterT (Set Path) Aeson.Parser a} deriving (Functor, Applicative, Alternative, Monad, Fail.MonadFail) liftParser :: Aeson.Parser a -> Parser a liftParser = Parser . lift -runParser :: (Value -> Parser a) -> Value -> Either String (a, [String])+runParser :: (Value -> Parser a) -> Value -> Either String (a, [String], [(String, String)]) runParser p v = case iparse (runWriterT . unParser <$> p) v of IError path err -> Left ("Error while parsing " ++ formatPath (fromAesonPath path) ++ " - " ++ err)- ISuccess (a, consumed) -> Right (a, map formatPath (determineUnconsumed consumed v))+ ISuccess (a, paths) -> Right (a, map formatPath (determineUnconsumed paths v), [(formatPath name, formatPath substitute) | Deprecated name substitute <- Set.toList paths]) formatPath :: JSONPath -> String formatPath = go "$" . reverse@@ -84,12 +89,12 @@ Index n : xs -> go (acc ++ "[" ++ show n ++ "]") xs Key key : xs -> go (acc ++ "." ++ T.unpack key) xs -determineUnconsumed :: Set JSONPath -> Value -> [JSONPath]-determineUnconsumed ((<> Set.singleton []) -> consumed) = Set.toList . execWriter . go []+determineUnconsumed :: Set Path -> Value -> [JSONPath]+determineUnconsumed ((<> Set.singleton (Consumed [])) -> consumed) = Set.toList . execWriter . go [] where go :: JSONPath -> Value -> Writer (Set JSONPath) () go path value- | path `notMember` consumed = tell (Set.singleton path)+ | Consumed path `notMember` consumed = tell (Set.singleton path) | otherwise = case value of Number _ -> return () String _ -> return ()@@ -110,7 +115,12 @@ markConsumed :: JSONPathElement -> Parser () markConsumed e = do path <- getPath- Parser $ tell (Set.singleton $ e : path)+ Parser $ tell (Set.singleton . Consumed $ e : path)++markDeprecated :: Key -> Key -> Parser ()+markDeprecated (Key.toText -> name) (Key.toText -> substitute) = do+ path <- getPath+ Parser $ tell (Set.singleton $ Deprecated (Key name : path) (Key substitute : path)) getPath :: Parser JSONPath getPath = liftParser $ Aeson.parserCatchError empty $ \ path _ -> return (fromAesonPath path)
src/Hpack/Config.hs view
@@ -13,6 +13,7 @@ {-# LANGUAGE ViewPatterns #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE DataKinds #-} module Hpack.Config ( -- | /__NOTE:__/ This module is exposed to allow integration of Hpack into -- other tools. It is not meant for general use by end users. The following@@ -59,6 +60,7 @@ , Cond(..) , Flag(..) , SourceRepository(..)+, Language(..) , BuildType(..) , GhcProfOption , GhcjsOption@@ -88,6 +90,7 @@ import qualified Data.Map.Lazy as Map import qualified Data.Aeson.Config.KeyMap as KeyMap import Data.Maybe+import Data.Monoid (Last(..)) import Data.Ord import qualified Data.Text as T import Data.Text.Encoding (decodeUtf8)@@ -185,7 +188,7 @@ deps xs = [(name, info) | (name, info) <- (Map.toList . unDependencies . sectionDependencies) xs] section :: a -> Section a-section a = Section a [] mempty [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] Nothing [] mempty mempty []+section a = Section a [] mempty [] [] [] Nothing [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] [] Nothing [] mempty mempty [] packageConfig :: FilePath packageConfig = "package.yaml"@@ -222,18 +225,18 @@ } data ExecutableSection = ExecutableSection {- executableSectionMain :: Maybe FilePath+ executableSectionMain :: Alias 'True "main-is" (Last FilePath) , executableSectionOtherModules :: Maybe (List Module) , executableSectionGeneratedOtherModules :: Maybe (List Module) } deriving (Eq, Show, Generic, FromValue) instance Monoid ExecutableSection where- mempty = ExecutableSection Nothing Nothing Nothing+ mempty = ExecutableSection mempty Nothing Nothing mappend = (<>) instance Semigroup ExecutableSection where a <> b = ExecutableSection {- executableSectionMain = executableSectionMain b <|> executableSectionMain a+ executableSectionMain = executableSectionMain a <> executableSectionMain b , executableSectionOtherModules = executableSectionOtherModules a <> executableSectionOtherModules b , executableSectionGeneratedOtherModules = executableSectionGeneratedOtherModules a <> executableSectionGeneratedOtherModules b }@@ -266,11 +269,12 @@ _ -> typeMismatch (formatOrList ["String", "Object"]) v data CommonOptions cSources cxxSources jsSources a = CommonOptions {- commonOptionsSourceDirs :: Maybe (List FilePath)-, commonOptionsDependencies :: Maybe Dependencies-, commonOptionsPkgConfigDependencies :: Maybe (List String)+ commonOptionsSourceDirs :: Alias 'True "hs-source-dirs" (Maybe (List FilePath))+, commonOptionsDependencies :: Alias 'True "build-depends" (Maybe Dependencies)+, commonOptionsPkgConfigDependencies :: Alias 'False "pkgconfig-depends" (Maybe (List String)) , commonOptionsDefaultExtensions :: Maybe (List String) , commonOptionsOtherExtensions :: Maybe (List String)+, commonOptionsLanguage :: Alias 'True "default-language" (Last (Maybe Language)) , commonOptionsGhcOptions :: Maybe (List GhcOption) , commonOptionsGhcProfOptions :: Maybe (List GhcProfOption) , commonOptionsGhcjsOptions :: Maybe (List GhcjsOption)@@ -287,9 +291,9 @@ , commonOptionsIncludeDirs :: Maybe (List FilePath) , commonOptionsInstallIncludes :: Maybe (List FilePath) , commonOptionsLdOptions :: Maybe (List LdOption)-, commonOptionsBuildable :: Maybe Bool+, commonOptionsBuildable :: Last Bool , commonOptionsWhen :: Maybe (List (ConditionalSection cSources cxxSources jsSources a))-, commonOptionsBuildTools :: Maybe BuildTools+, commonOptionsBuildTools :: Alias 'True "build-tool-depends" (Maybe BuildTools) , commonOptionsSystemBuildTools :: Maybe SystemBuildTools , commonOptionsVerbatim :: Maybe (List Verbatim) } deriving (Functor, Generic)@@ -299,11 +303,12 @@ instance (Semigroup cSources, Semigroup cxxSources, Semigroup jsSources, Monoid cSources, Monoid cxxSources, Monoid jsSources) => Monoid (CommonOptions cSources cxxSources jsSources a) where mempty = CommonOptions {- commonOptionsSourceDirs = Nothing- , commonOptionsDependencies = Nothing- , commonOptionsPkgConfigDependencies = Nothing+ commonOptionsSourceDirs = Alias Nothing+ , commonOptionsDependencies = Alias Nothing+ , commonOptionsPkgConfigDependencies = Alias Nothing , commonOptionsDefaultExtensions = Nothing , commonOptionsOtherExtensions = Nothing+ , commonOptionsLanguage = mempty , commonOptionsGhcOptions = Nothing , commonOptionsGhcProfOptions = Nothing , commonOptionsGhcjsOptions = Nothing@@ -320,9 +325,9 @@ , commonOptionsIncludeDirs = Nothing , commonOptionsInstallIncludes = Nothing , commonOptionsLdOptions = Nothing- , commonOptionsBuildable = Nothing+ , commonOptionsBuildable = mempty , commonOptionsWhen = Nothing- , commonOptionsBuildTools = Nothing+ , commonOptionsBuildTools = Alias Nothing , commonOptionsSystemBuildTools = Nothing , commonOptionsVerbatim = Nothing }@@ -335,6 +340,7 @@ , commonOptionsPkgConfigDependencies = commonOptionsPkgConfigDependencies a <> commonOptionsPkgConfigDependencies b , commonOptionsDefaultExtensions = commonOptionsDefaultExtensions a <> commonOptionsDefaultExtensions b , commonOptionsOtherExtensions = commonOptionsOtherExtensions a <> commonOptionsOtherExtensions b+ , commonOptionsLanguage = commonOptionsLanguage a <> commonOptionsLanguage b , commonOptionsGhcOptions = commonOptionsGhcOptions a <> commonOptionsGhcOptions b , commonOptionsGhcProfOptions = commonOptionsGhcProfOptions a <> commonOptionsGhcProfOptions b , commonOptionsGhcjsOptions = commonOptionsGhcjsOptions a <> commonOptionsGhcjsOptions b@@ -351,7 +357,7 @@ , commonOptionsIncludeDirs = commonOptionsIncludeDirs a <> commonOptionsIncludeDirs b , commonOptionsInstallIncludes = commonOptionsInstallIncludes a <> commonOptionsInstallIncludes b , commonOptionsLdOptions = commonOptionsLdOptions a <> commonOptionsLdOptions b- , commonOptionsBuildable = commonOptionsBuildable b <|> commonOptionsBuildable a+ , commonOptionsBuildable = commonOptionsBuildable a <> commonOptionsBuildable b , commonOptionsWhen = commonOptionsWhen a <> commonOptionsWhen b , commonOptionsBuildTools = commonOptionsBuildTools a <> commonOptionsBuildTools b , commonOptionsSystemBuildTools = commonOptionsSystemBuildTools b <> commonOptionsSystemBuildTools a@@ -501,12 +507,21 @@ instance FromValue Empty where fromValue _ = return Empty +newtype Language = Language String+ deriving (Eq, Show)++instance IsString Language where+ fromString = Language++instance FromValue Language where+ fromValue = fmap Language . fromValue+ data BuildType = Simple | Configure | Make | Custom- deriving (Eq, Show, Generic, Enum, Bounded)+ deriving (Eq, Show, Enum, Bounded) instance FromValue BuildType where fromValue = withText $ \ (T.unpack -> t) -> do@@ -877,16 +892,18 @@ decodeValue :: FromValue a => ProgramName -> FilePath -> Value -> Warnings (Errors IO) a decodeValue (ProgramName programName) file value = do- (r, unknown) <- lift . ExceptT . return $ first (prefix ++) (Config.decodeValue value)+ (r, unknown, deprecated) <- lift . ExceptT . return $ first (prefix ++) (Config.decodeValue value) case r of UnsupportedSpecVersion v -> do lift $ throwE ("The file " ++ file ++ " requires version " ++ showVersion v ++ " of the Hpack package specification, however this version of " ++ programName ++ " only supports versions up to " ++ showVersion Hpack.version ++ ". Upgrading to the latest version of " ++ programName ++ " may resolve this issue.") SupportedSpecVersion a -> do tell (map formatUnknownField unknown)+ tell (map formatDeprecatedField deprecated) return a where prefix = file ++ ": " formatUnknownField name = prefix ++ "Ignoring unrecognized field " ++ name+ formatDeprecatedField (name, substitute) = prefix <> name <> " is deprecated, use " <> substitute <> " instead" data CheckSpecVersion a = SupportedSpecVersion a | UnsupportedSpecVersion Version @@ -968,6 +985,7 @@ , sectionPkgConfigDependencies :: [String] , sectionDefaultExtensions :: [String] , sectionOtherExtensions :: [String]+, sectionLanguage :: Maybe Language , sectionGhcOptions :: [GhcOption] , sectionGhcProfOptions :: [GhcProfOption] , sectionGhcjsOptions :: [GhcjsOption]@@ -1034,8 +1052,13 @@ toPackage :: ProgramName -> FilePath -> FilePath -> ConfigWithDefaults -> Warnings (Errors IO) (Package, String) toPackage programName userDataDir dir = expandDefaultsInConfig programName userDataDir dir- >=> traverseConfig (expandForeignSources dir)+ >=> setDefaultLanguage "Haskell2010"+ >>> traverseConfig (expandForeignSources dir) >=> toPackage_ dir+ where+ setDefaultLanguage language config = first setLanguage config+ where+ setLanguage = (mempty { commonOptionsLanguage = Alias . Last $ Just (Just language) } <>) expandDefaultsInConfig :: ProgramName@@ -1396,7 +1419,7 @@ } getMentionedExecutableModules :: ExecutableSection -> [Module]-getMentionedExecutableModules (ExecutableSection main otherModules generatedModules)=+getMentionedExecutableModules (ExecutableSection (Alias (Last main)) otherModules generatedModules)= maybe id (:) (toModule . Path.fromFilePath <$> main) $ fromMaybeList (otherModules <> generatedModules) toExecutable :: FilePath -> String -> Section ExecutableSection -> IO (Section Executable)@@ -1406,7 +1429,7 @@ where fromExecutableSection :: [Module] -> [Module] -> ExecutableSection -> Executable fromExecutableSection pathsModule inferableModules ExecutableSection{..} =- (Executable executableSectionMain (otherModules ++ generatedModules) generatedModules)+ (Executable (getLast $ unAlias executableSectionMain) (otherModules ++ generatedModules) generatedModules) where otherModules = maybe (inferableModules ++ pathsModule) fromList executableSectionOtherModules generatedModules = maybe [] fromList executableSectionGeneratedOtherModules@@ -1419,9 +1442,9 @@ where go exec@ExecutableSection{..} = let- (mainSrcFile, ghcOptions) = maybe (Nothing, []) (first Just . parseMain) executableSectionMain+ (mainSrcFile, ghcOptions) = maybe (Nothing, []) (first Just . parseMain) (getLast $ unAlias executableSectionMain) in- (ghcOptions, exec{executableSectionMain = mainSrcFile})+ (ghcOptions, exec{executableSectionMain = Alias $ Last mainSrcFile}) flatten :: Section ([GhcOption], ExecutableSection) -> Section ExecutableSection flatten sect@Section{sectionData = (ghcOptions, exec), ..} = sect{@@ -1434,14 +1457,15 @@ toSection packageName_ executableNames = go where go (Product CommonOptions{..} a) = do- (systemBuildTools, buildTools) <- maybe (return mempty) toBuildTools commonOptionsBuildTools+ (systemBuildTools, buildTools) <- maybe (return mempty) toBuildTools (unAlias commonOptionsBuildTools) conditionals <- mapM toConditional (fromMaybeList commonOptionsWhen) return Section { sectionData = a- , sectionSourceDirs = nub $ fromMaybeList commonOptionsSourceDirs+ , sectionSourceDirs = nub $ fromMaybeList (unAlias commonOptionsSourceDirs) , sectionDefaultExtensions = fromMaybeList commonOptionsDefaultExtensions , sectionOtherExtensions = fromMaybeList commonOptionsOtherExtensions+ , sectionLanguage = join . getLast $ unAlias commonOptionsLanguage , sectionGhcOptions = fromMaybeList commonOptionsGhcOptions , sectionGhcProfOptions = fromMaybeList commonOptionsGhcProfOptions , sectionGhcjsOptions = fromMaybeList commonOptionsGhcjsOptions@@ -1458,9 +1482,9 @@ , sectionIncludeDirs = fromMaybeList commonOptionsIncludeDirs , sectionInstallIncludes = fromMaybeList commonOptionsInstallIncludes , sectionLdOptions = fromMaybeList commonOptionsLdOptions- , sectionBuildable = commonOptionsBuildable- , sectionDependencies = fromMaybe mempty commonOptionsDependencies- , sectionPkgConfigDependencies = fromMaybeList commonOptionsPkgConfigDependencies+ , sectionBuildable = getLast commonOptionsBuildable+ , sectionDependencies = fromMaybe mempty (unAlias commonOptionsDependencies)+ , sectionPkgConfigDependencies = fromMaybeList (unAlias commonOptionsPkgConfigDependencies) , sectionConditionals = conditionals , sectionBuildTools = buildTools , sectionSystemBuildTools = systemBuildTools <> fromMaybe mempty commonOptionsSystemBuildTools
src/Hpack/Render.hs view
@@ -186,7 +186,7 @@ (renderExecutableSection [Field "type" "exitcode-stdio-1.0"] sect) renderExecutableSection :: [Element] -> Section Executable -> [Element]-renderExecutableSection extraFields = renderSection renderExecutableFields extraFields [defaultLanguage]+renderExecutableSection extraFields = renderSection renderExecutableFields extraFields renderExecutableFields :: Executable -> [Element] renderExecutableFields Executable{..} = mainIs ++ [otherModules, generatedModules]@@ -203,7 +203,7 @@ renderLibrary sect = Stanza "library" $ renderLibrarySection sect renderLibrarySection :: Section Library -> [Element]-renderLibrarySection = renderSection renderLibraryFields [] [defaultLanguage]+renderLibrarySection = renderSection renderLibraryFields [] renderLibraryFields :: Library -> [Element] renderLibraryFields Library{..} =@@ -222,8 +222,8 @@ renderVisibility :: String -> Element renderVisibility = Field "visibility" . Literal -renderSection :: (a -> [Element]) -> [Element] -> [Element] -> Section a -> [Element]-renderSection renderSectionData extraFieldsStart extraFieldsEnd Section{..} = addVerbatim sectionVerbatim $+renderSection :: (a -> [Element]) -> [Element] -> Section a -> [Element]+renderSection renderSectionData extraFieldsStart Section{..} = addVerbatim sectionVerbatim $ extraFieldsStart ++ renderSectionData sectionData ++ [ renderDirectories "hs-source-dirs" sectionSourceDirs@@ -250,8 +250,8 @@ ++ renderBuildTools sectionBuildTools sectionSystemBuildTools ++ renderDependencies "build-depends" sectionDependencies ++ maybe [] (return . renderBuildable) sectionBuildable+ ++ maybe [] (return . renderLanguage) sectionLanguage ++ map (renderConditional renderSectionData) sectionConditionals- ++ extraFieldsEnd addVerbatim :: [Verbatim] -> [Element] -> [Element] addVerbatim verbatim fields = filterVerbatim verbatim fields ++ renderVerbatim verbatim@@ -285,9 +285,9 @@ renderConditional :: (a -> [Element]) -> Conditional (Section a) -> Element renderConditional renderSectionData (Conditional condition sect mElse) = case mElse of Nothing -> if_- Just else_ -> Group if_ (Stanza "else" $ renderSection renderSectionData [] [] else_)+ Just else_ -> Group if_ (Stanza "else" $ renderSection renderSectionData [] else_) where- if_ = Stanza ("if " ++ renderCond condition) (renderSection renderSectionData [] [] sect)+ if_ = Stanza ("if " ++ renderCond condition) (renderSection renderSectionData [] sect) renderCond :: Cond -> String renderCond = \ case@@ -295,9 +295,6 @@ CondBool True -> "true" CondBool False -> "false" -defaultLanguage :: Element-defaultLanguage = Field "default-language" "Haskell2010"- renderDirectories :: String -> [String] -> Element renderDirectories name = Field name . LineSeparatedList . replaceDots where@@ -375,6 +372,9 @@ renderSystemBuildTool :: (String, VersionConstraint) -> String renderSystemBuildTool (name, constraint) = name ++ renderVersionConstraint constraint++renderLanguage :: Language -> Element+renderLanguage (Language lang) = Field "default-language" (Literal lang) renderGhcOptions :: [GhcOption] -> Element renderGhcOptions = Field "ghc-options" . WordList
test/Data/Aeson/Config/FromValueSpec.hs view
@@ -3,12 +3,14 @@ {-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE DataKinds #-} module Data.Aeson.Config.FromValueSpec where import Helper import GHC.Generics import qualified Data.Map.Lazy as Map+import Data.Monoid (Last(..)) import Data.Aeson.Config.FromValue @@ -16,7 +18,7 @@ shouldDecodeTo value expected = decodeValue value `shouldBe` expected shouldDecodeTo_ :: (HasCallStack, Eq a, Show a, FromValue a) => Value -> a -> Expectation-shouldDecodeTo_ value expected = decodeValue value `shouldBe` Right (expected, [])+shouldDecodeTo_ value expected = decodeValue value `shouldBe` Right (expected, [], []) data Person = Person { personName :: String@@ -34,6 +36,30 @@ , jobSalary :: Int } deriving (Eq, Show, Generic, FromValue) +data FlatMaybe = FlatMaybe {+ flatMaybeValue :: Maybe String+} deriving (Eq, Show, Generic, FromValue)++data AliasMaybe = AliasMaybe {+ aliasMaybeValue :: Alias 'False "some-alias" (Maybe String)+} deriving (Eq, Show, Generic, FromValue)++data NestedMaybe = NestedMaybe {+ nestedMaybeValue :: Maybe (Maybe String)+} deriving (Eq, Show, Generic, FromValue)++data AliasNestedMaybe = AliasNestedMaybe {+ aliasNestedMaybeValue :: Alias 'False "some-alias" (Maybe (Maybe String))+} deriving (Eq, Show, Generic, FromValue)++data FlatLast = FlatLast {+ flatLastValue :: Last String+} deriving (Eq, Show, Generic, FromValue)++data AliasLast = AliasLast {+ aliasLastValue :: Alias 'False "some-alias" (Last String)+} deriving (Eq, Show, Generic, FromValue)+ spec :: Spec spec = do describe "fromValue" $ do@@ -52,7 +78,7 @@ name: "Joe" age: 23 foo: bar- |] `shouldDecodeTo` Right (Person "Joe" 23 Nothing, ["$.foo"])+ |] `shouldDecodeTo` Right (Person "Joe" 23 Nothing, ["$.foo"], []) it "captures nested unrecognized fields" $ do [yaml|@@ -63,7 +89,7 @@ zip: "123456" foo: bar: 23- |] `shouldDecodeTo` Right (Person "Joe" 23 (Just (Address "somewhere" "123456")), ["$.address.foo"])+ |] `shouldDecodeTo` Right (Person "Joe" 23 (Just (Address "somewhere" "123456")), ["$.address.foo"], []) it "ignores fields that start with an underscore" $ do [yaml|@@ -87,6 +113,135 @@ age: "23" |] `shouldDecodeTo` left "Error while parsing $.age - parsing Int failed, expected Number, but encountered String" + context "when parsing a field of type (Maybe a)" $ do+ it "accepts a value" $ do+ [yaml|+ value: some value+ |] `shouldDecodeTo_` FlatMaybe (Just "some value")++ it "allows the field to be omitted" $ do+ [yaml|+ {}+ |] `shouldDecodeTo_` FlatMaybe Nothing++ it "rejects null" $ do+ [yaml|+ value: null+ |] `shouldDecodeTo` (Left "Error while parsing $.value - expected String, but encountered Null" :: Result FlatMaybe)++ context "when parsing a field of type (Maybe (Maybe a))" $ do+ it "accepts a value" $ do+ [yaml|+ value: some value+ |] `shouldDecodeTo_` NestedMaybe (Just $ Just "some value")++ it "allows the field to be omitted" $ do+ [yaml|+ {}+ |] `shouldDecodeTo_` NestedMaybe Nothing++ it "accepts null" $ do+ [yaml|+ value: null+ |] `shouldDecodeTo_` NestedMaybe (Just Nothing)++ context "when parsing a field of type (Alias (Maybe a))" $ do+ it "accepts a value" $ do+ [yaml|+ value: some value+ |] `shouldDecodeTo_` AliasMaybe (Alias $ Just "some value")++ it "allows the field to be accessed by its alias" $ do+ [yaml|+ some-alias: some alias value+ |] `shouldDecodeTo_` AliasMaybe (Alias $ Just "some alias value")++ it "gives the primary name precedence" $ do+ [yaml|+ value: some value+ some-alias: some alias value+ |] `shouldDecodeTo` Right (AliasMaybe (Alias $ Just "some value"), ["$.some-alias"], [])++ it "allows the field to be omitted" $ do+ [yaml|+ {}+ |] `shouldDecodeTo_` AliasMaybe (Alias Nothing)++ it "rejects null" $ do+ [yaml|+ value: null+ |] `shouldDecodeTo` (Left "Error while parsing $.value - expected String, but encountered Null" :: Result AliasMaybe)++ context "when parsing a field of type (Alias (Maybe (Maybe a)))" $ do+ it "accepts a value" $ do+ [yaml|+ value: some value+ |] `shouldDecodeTo_` AliasNestedMaybe (Alias . Just $ Just "some value")++ it "allows the field to be accessed by its alias" $ do+ [yaml|+ some-alias: some value+ |] `shouldDecodeTo_` AliasNestedMaybe (Alias . Just $ Just "some value")++ it "gives the primary name precedence" $ do+ [yaml|+ value: some value+ some-alias: some alias value+ |] `shouldDecodeTo` Right (AliasNestedMaybe (Alias . Just $ Just "some value"), ["$.some-alias"], [])++ it "allows the field to be omitted" $ do+ [yaml|+ {}+ |] `shouldDecodeTo_` AliasNestedMaybe (Alias Nothing)++ it "accepts null" $ do+ [yaml|+ value: null+ |] `shouldDecodeTo_` AliasNestedMaybe (Alias $ Just Nothing)++ context "when parsing a field of type (Last a)" $ do+ it "accepts a value" $ do+ [yaml|+ value: some value+ |] `shouldDecodeTo_` FlatLast (Last $ Just "some value")++ it "allows the field to be omitted" $ do+ [yaml|+ {}+ |] `shouldDecodeTo_` FlatLast (Last Nothing)++ it "rejects null" $ do+ [yaml|+ value: null+ |] `shouldDecodeTo` (Left "Error while parsing $.value - expected String, but encountered Null" :: Result FlatLast)++ context "when parsing a field of type (Alias (Last a))" $ do+ it "accepts a value" $ do+ [yaml|+ value: some value+ |] `shouldDecodeTo_` AliasLast (Alias . Last $ Just "some value")++ it "allows the field to be accessed by its alias" $ do+ [yaml|+ some-alias: some value+ |] `shouldDecodeTo_` AliasLast (Alias . Last $ Just "some value")++ it "gives the primary name precedence" $ do+ [yaml|+ value: some value+ some-alias: some alias value+ |] `shouldDecodeTo` Right (AliasLast (Alias . Last $ Just "some value"), ["$.some-alias"], [])++ it "allows the field to be omitted" $ do+ [yaml|+ {}+ |] `shouldDecodeTo_` AliasLast (Alias $ Last Nothing)++ it "rejects null" $ do+ [yaml|+ value: null+ |] `shouldDecodeTo` (Left "Error while parsing $.value - expected String, but encountered Null" :: Result AliasLast)+ context "with (,)" $ do it "captures unrecognized fields" $ do [yaml|@@ -95,7 +250,7 @@ role: engineer salary: 100000 foo: bar- |] `shouldDecodeTo` Right ((Person "Joe" 23 Nothing, Job "engineer" 100000), ["$.foo"])+ |] `shouldDecodeTo` Right ((Person "Joe" 23 Nothing, Job "engineer" 100000), ["$.foo"], []) context "with []" $ do it "captures unrecognized fields" $ do@@ -111,7 +266,7 @@ - name: "Marry" age: 25 bar: 42- |] `shouldDecodeTo` Right (expected, ["$[1].bar", "$[0].address.foo"])+ |] `shouldDecodeTo` Right (expected, ["$[1].bar", "$[0].address.foo"], []) context "with Map" $ do it "captures unrecognized fields" $ do@@ -120,4 +275,4 @@ region: somewhere zip: '123456' foo: bar- |] `shouldDecodeTo` Right (Map.fromList [("Joe", Address "somewhere" "123456")], ["$.Joe.foo"])+ |] `shouldDecodeTo` Right (Map.fromList [("Joe", Address "somewhere" "123456")], ["$.Joe.foo"], [])
test/EndToEndSpec.hs view
@@ -11,7 +11,7 @@ import Helper import Test.HUnit -import System.Directory (canonicalizePath, createDirectory)+import System.Directory (canonicalizePath) import Data.Maybe import Data.List import Data.String.Interpolate@@ -35,10 +35,15 @@ _foo: bar: 23 library: {}- |] `shouldRenderTo` library [i|- other-modules:- Paths_foo+ |] `shouldRenderTo` library_ [i| |]+ it "warns on duplicate fields" $ do+ [i|+ name: foo+ name: foo+ |] `shouldWarn` [+ "package.yaml: Duplicate field $.name"+ ] describe "tested-with" $ do it "accepts a string" $ do@@ -62,14 +67,6 @@ , GHC == 7.4.2 |] - it "warns on duplicate fields" $ do- [i|- name: foo- name: foo- |] `shouldWarn` [- "package.yaml: Duplicate field $.name"- ]- describe "handling of Paths_ module" $ do it "adds Paths_ to other-modules" $ do [i|@@ -77,6 +74,7 @@ |] `shouldRenderTo` library [i| other-modules: Paths_foo+ default-language: Haskell2010 |] context "when cabal-version is >= 2" $ do@@ -90,6 +88,7 @@ Paths_foo autogen-modules: Paths_foo+ default-language: Haskell2010 |]) { packageCabalVersion = "2.0" } context "when Paths_ module is listed explicitly under generated-other-modules" $ do@@ -104,6 +103,7 @@ Paths_foo autogen-modules: Paths_foo+ default-language: Haskell2010 |]) { packageCabalVersion = "2.0" } context "when Paths_ module is listed explicitly under generated-exposed-modules" $ do@@ -118,6 +118,7 @@ Paths_foo autogen-modules: Paths_foo+ default-language: Haskell2010 |]) { packageCabalVersion = "2.0" } context "when Paths_ is mentioned in a conditional that is always false" $ do@@ -128,9 +129,10 @@ - condition: false other-modules: Paths_foo |] `shouldRenderTo` library [i|+ default-language: Haskell2010 |] - context "with RebindableSyntax and OverloadedStrings or OverloadedStrings" $ do+ context "when Paths_ is used with RebindableSyntax and (OverloadedStrings or OverloadedLists)" $ do it "infers cabal-version 2.2" $ do [i| default-extensions: [RebindableSyntax, OverloadedStrings]@@ -143,6 +145,7 @@ Paths_foo autogen-modules: Paths_foo+ default-language: Haskell2010 |]) {packageCabalVersion = "2.2"} context "when Paths_ is mentioned in a conditional that is always false" $ do@@ -157,6 +160,7 @@ default-extensions: RebindableSyntax OverloadedStrings+ default-language: Haskell2010 |]) describe "spec-version" $ do@@ -342,13 +346,36 @@ github: sol/hpack-template path: defaults.yaml ref: "2017"- |] `shouldRenderTo` library [i|+ |] `shouldRenderTo` library_ [i| exposed-modules: Foo- other-modules:- Paths_foo |] + it "accepts executable defaults" $ do+ writeFile "defaults/sol/hpack-template/2017/.hpack/defaults.yaml" [i|+ main: Foo.hs+ |]++ [i|+ executable:+ defaults: sol/hpack-template@2017+ |] `shouldRenderTo` executable_ "foo" [i|+ main-is: Foo.hs+ |]++ it "gives `main` from executable section precedence" $ do+ writeFile "defaults/sol/hpack-template/2017/.hpack/defaults.yaml" [i|+ main: Foo.hs+ |]++ [i|+ executable:+ main: Bar.hs+ defaults: sol/hpack-template@2017+ |] `shouldRenderTo` executable_ "foo" [i|+ main-is: Bar.hs+ |]+ it "accepts a list of defaults" $ do writeFile "defaults/foo/bar/v1/.hpack/defaults.yaml" "default-extensions: RecordWildCards" writeFile "defaults/foo/bar/v2/.hpack/defaults.yaml" "default-extensions: DeriveFunctor"@@ -439,9 +466,7 @@ defaults: local: defaults/foo.yaml library: {}- |] `shouldRenderTo` library [i|- other-modules:- Paths_foo+ |] `shouldRenderTo` library_ [i| default-extensions: RecordWildCards DeriveFunctor@@ -629,6 +654,19 @@ packageCabalVersion = "1.12" } + it "accepts build-tool-depends as an alias" $ do+ [i|+ executable:+ build-tool-depends:+ hspec-discover: 0.1.0+ |] `shouldRenderTo` (executable_ "foo" [i|+ build-tool-depends:+ hspec-discover:hspec-discover ==0.1.0+ |]) {+ packageCabalVersion = "1.12"+ , packageWarnings = ["package.yaml: $.executable.build-tool-depends is deprecated, use $.executable.build-tools instead"]+ }+ context "when the name of a build tool matches an executable from the same package" $ do it "adds it to build-tools" $ do [i|@@ -734,6 +772,17 @@ base |] + it "accepts build-depends as an alias" $ do+ [i|+ executable:+ build-depends: base+ |] `shouldRenderTo` (executable_ "foo" [i|+ build-depends:+ base+ |]) {+ packageWarnings = ["package.yaml: $.executable.build-depends is deprecated, use $.executable.dependencies instead"]+ }+ it "accepts dependencies with subcomponents" $ do [i| executable:@@ -794,6 +843,18 @@ , weston |] + it "accepts pkgconfig-depends as an alias" $ do+ [i|+ pkgconfig-depends:+ - QtWebKit+ - weston+ executable: {}+ |] `shouldRenderTo` executable_ "foo" [i|+ pkgconfig-depends:+ QtWebKit+ , weston+ |]+ describe "include-dirs" $ do it "accepts include-dirs" $ do [i|@@ -867,9 +928,12 @@ when: condition: True cxx-options: -Wall- |] `shouldRenderTo` (executable_ "foo" [i|+ |] `shouldRenderTo` (executable "foo" [i|+ other-modules:+ Paths_foo autogen-modules: Paths_foo+ default-language: Haskell2010 if true if true if true@@ -891,6 +955,63 @@ cxxbits/bar.cc |]) {packageCabalVersion = "2.2"} + describe "language" $ do+ it "accepts language" $ do+ [i|+ language: GHC2021+ executable: {}+ |] `shouldRenderTo` executable "foo" [i|+ other-modules:+ Paths_foo+ default-language: GHC2021+ |]++ it "omits language if it is null" $ do+ [i|+ language: null+ executable: {}+ |] `shouldRenderTo` executable "foo" [i|+ other-modules:+ Paths_foo+ |]++ it "accepts default-language as an alias" $ do+ [i|+ default-language: GHC2021+ executable: {}+ |] `shouldRenderTo` (executable "foo" [i|+ other-modules:+ Paths_foo+ default-language: GHC2021+ |]) {+ packageWarnings = ["package.yaml: $.default-language is deprecated, use $.language instead"]+ }++ it "gives section-level language precedence" $ do+ [i|+ language: Haskell2010+ executable:+ language: GHC2021+ |] `shouldRenderTo` executable "foo" [i|+ other-modules:+ Paths_foo+ default-language: GHC2021+ |]++ it "accepts language from defaults" $ do+ writeFile "defaults/sol/hpack-template/2017/.hpack/defaults.yaml" [i|+ language: GHC2021+ |]++ [i|+ defaults: sol/hpack-template@2017+ library: {}+ |] `shouldRenderTo` library [i|+ other-modules:+ Paths_foo+ default-language: GHC2021+ |]+ describe "extra-lib-dirs" $ do it "accepts extra-lib-dirs" $ do [i|@@ -1054,6 +1175,7 @@ Foo other-modules: Foo+ default-language: Haskell2010 |] context "with mixins" $ do@@ -1073,6 +1195,7 @@ foo mixins: foo (Blah as Etc)+ default-language: Haskell2010 |]) {packageCabalVersion = "2.0"} describe "internal-libraries" $ do@@ -1137,6 +1260,7 @@ Foo other-modules: Paths_foo+ default-language: Haskell2010 |] it "ignores duplicate modules" $ do@@ -1152,6 +1276,7 @@ Foo other-modules: Paths_foo+ default-language: Haskell2010 |] context "with exposed-modules" $ do@@ -1170,6 +1295,7 @@ other-modules: Bar Paths_foo+ default-language: Haskell2010 |] context "with other-modules" $ do@@ -1187,6 +1313,7 @@ Foo other-modules: Bar+ default-language: Haskell2010 |] context "with both exposed-modules and other-modules" $ do@@ -1205,6 +1332,7 @@ Foo other-modules: Bar+ default-language: Haskell2010 |] context "with neither exposed-modules nor other-modules" $ do@@ -1222,6 +1350,7 @@ Foo other-modules: Paths_foo+ default-language: Haskell2010 |] context "with a conditional" $ do@@ -1236,15 +1365,17 @@ exposed-modules: - Foo - Paths_foo- |] `shouldRenderTo` library [i|- hs-source-dirs:- src- if os(windows)+ |] `shouldRenderTo` package [i|+ library+ hs-source-dirs:+ src exposed-modules:- Foo- Paths_foo- exposed-modules:- Bar+ Bar+ default-language: Haskell2010+ if os(windows)+ exposed-modules:+ Foo+ Paths_foo |] context "with a source-dir inside the conditional" $ do@@ -1255,14 +1386,16 @@ when: condition: os(windows) source-dirs: windows- |] `shouldRenderTo` library [i|- other-modules:- Paths_foo- if os(windows)+ |] `shouldRenderTo` package [i|+ library other-modules:- Foo- hs-source-dirs:- windows+ Paths_foo+ default-language: Haskell2010+ if os(windows)+ other-modules:+ Foo+ hs-source-dirs:+ windows |] it "does not infer outer modules" $ do@@ -1278,17 +1411,19 @@ else: source-dirs: unix/ - |] `shouldRenderTo` library [i|- exposed-modules:- Foo- other-modules:- Paths_foo- if os(windows)- hs-source-dirs:- windows/- else- hs-source-dirs:- unix/+ |] `shouldRenderTo` package [i|+ library+ exposed-modules:+ Foo+ other-modules:+ Paths_foo+ default-language: Haskell2010+ if os(windows)+ hs-source-dirs:+ windows/+ else+ hs-source-dirs:+ unix/ |] context "with generated modules" $ do@@ -1307,6 +1442,7 @@ Paths_foo Foo Bar+ default-language: Haskell2010 |]) {packageCabalVersion = "2.0"} it "does not infer any mentioned generated modules" $ do@@ -1329,6 +1465,7 @@ Paths_foo Exposed Other+ default-language: Haskell2010 |]) {packageCabalVersion = "2.0"} it "does not infer any generated modules mentioned inside conditionals" $ do@@ -1341,21 +1478,23 @@ condition: os(windows) generated-exposed-modules: Exposed generated-other-modules: Other- |] `shouldRenderTo` (library [i|- other-modules:- Paths_foo- autogen-modules:- Paths_foo- hs-source-dirs:- src- if os(windows)- exposed-modules:- Exposed+ |] `shouldRenderTo` (package [i|+ library other-modules:- Other+ Paths_foo autogen-modules:- Other- Exposed+ Paths_foo+ hs-source-dirs:+ src+ default-language: Haskell2010+ if os(windows)+ exposed-modules:+ Exposed+ other-modules:+ Other+ autogen-modules:+ Other+ Exposed |]) {packageCabalVersion = "2.0"} context "with an executable" $ do@@ -1374,6 +1513,7 @@ other-modules: Foo Paths_foo+ default-language: Haskell2010 |] it "allows to specify other-modules" $ do@@ -1391,6 +1531,7 @@ src other-modules: Baz+ default-language: Haskell2010 |] it "does not infer any mentioned generated modules" $ do@@ -1411,6 +1552,7 @@ autogen-modules: Paths_foo Foo+ default-language: Haskell2010 |]) {packageCabalVersion = "2.0"} context "with a conditional" $ do@@ -1430,6 +1572,7 @@ Paths_foo hs-source-dirs: src+ default-language: Haskell2010 if os(windows) other-modules: Foo@@ -1451,6 +1594,7 @@ Paths_foo hs-source-dirs: src+ default-language: Haskell2010 if os(windows) other-modules: Bar@@ -1459,6 +1603,16 @@ |] describe "executables" $ do+ it "accepts main-is as an alias for main" $ do+ [i|+ executable:+ main-is: Foo.hs+ |] `shouldRenderTo` (executable_ "foo" [i|+ main-is: Foo.hs+ |]) {+ packageWarnings = ["package.yaml: $.executable.main-is is deprecated, use $.executable.main instead"]+ }+ it "accepts arbitrary entry points as main" $ do touch "src/Foo.hs" touch "src/Bar.hs"@@ -1475,6 +1629,7 @@ other-modules: Bar Paths_foo+ default-language: Haskell2010 |] context "with a conditional" $ do@@ -1487,8 +1642,11 @@ when: condition: os(windows) main: Foo.hs- |] `shouldRenderTo` executable_ "foo" [i|+ |] `shouldRenderTo` executable "foo" [i| ghc-options: -Wall+ other-modules:+ Paths_foo+ default-language: Haskell2010 if os(windows) main-is: Foo.hs |]@@ -1500,7 +1658,10 @@ when: condition: os(windows) main: Foo- |] `shouldRenderTo` executable_ "foo" [i|+ |] `shouldRenderTo` executable "foo" [i|+ other-modules:+ Paths_foo+ default-language: Haskell2010 if os(windows) main-is: Foo.hs ghc-options: -main-is Foo@@ -1513,7 +1674,10 @@ condition: os(windows) dependencies: Win32 executable: {}- |] `shouldRenderTo` executable_ "foo" [i|+ |] `shouldRenderTo` executable "foo" [i|+ other-modules:+ Paths_foo+ default-language: Haskell2010 if os(windows) build-depends: Win32@@ -1547,7 +1711,10 @@ else: dependencies: unix executable: {}- |] `shouldRenderTo` executable_ "foo" [i|+ |] `shouldRenderTo` executable "foo" [i|+ other-modules:+ Paths_foo+ default-language: Haskell2010 if os(windows) build-depends: Win32@@ -1768,11 +1935,8 @@ shouldRenderTo :: HasCallStack => String -> Package -> Expectation shouldRenderTo input p = do writeFile packageConfig ("name: foo\n" ++ unindent input)- let currentDirectory = ".working-directory"- createDirectory currentDirectory- withCurrentDirectory currentDirectory $ do- (warnings, output) <- run ".." (".." </> packageConfig) expected- RenderResult warnings (dropEmptyLines output) `shouldBe` RenderResult (packageWarnings p) expected+ (warnings, output) <- run "" packageConfig expected+ RenderResult warnings (dropEmptyLines output) `shouldBe` RenderResult (packageWarnings p) expected where expected = dropEmptyLines (renderPackage p) dropEmptyLines = unlines . filter (not . null) . lines@@ -1813,7 +1977,6 @@ content = [i| library #{indentBy 2 $ unindent l}- default-language: Haskell2010 |] internalLibrary :: String -> String -> Package@@ -1842,7 +2005,6 @@ content = [i| executable #{name} #{indentBy 2 $ unindent e}- default-language: Haskell2010 |] package :: String -> Package
test/Hpack/ConfigSpec.hs view
@@ -28,12 +28,14 @@ import Hpack.Syntax.Dependencies import Hpack.Syntax.DependencyVersion import Hpack.Syntax.BuildTools-import Hpack.Config hiding (package)+import Hpack.Config hiding (section, package) import qualified Hpack.Config as Config import Data.Aeson.Config.Types import Data.Aeson.Config.FromValue +section :: a -> Section a+section a = (Config.section a) {sectionLanguage = Just $ Language "Haskell2010"} instance Exts.IsList (Maybe (List a)) where type Item (Maybe (List a)) = a@@ -418,6 +420,15 @@ withPackageConfig_ [i| library: source-dirs:+ - foo+ - bar+ |]+ (packageLibrary >>> (`shouldBe` Just (section library) {sectionSourceDirs = ["foo", "bar"]}))++ it "accepts hs-source-dirs as an alias for source-dirs" $ do+ withPackageConfig_ [i|+ library:+ hs-source-dirs: - foo - bar |]
test/Hpack/RenderSpec.hs view
@@ -14,7 +14,9 @@ library = Library Nothing Nothing [] [] [] [] [] executable :: Section Executable-executable = section (Executable (Just "Main.hs") [] [])+executable = (section $ Executable (Just "Main.hs") [] []) {+ sectionLanguage = Just $ Language "Haskell2010"+} renderEmptySection :: Empty -> [Element] renderEmptySection Empty = []@@ -117,19 +119,7 @@ , "" , "library" , " buildable: False"- , " default-language: Haskell2010" ]-- context "when rendering library section" $ do- it "renders library section" $ do- renderPackage_ package {packageLibrary = Just $ section library} `shouldBe` unlines [- "name: foo"- , "version: 0.0.0"- , "build-type: Simple"- , ""- , "library"- , " default-language: Haskell2010"- ] context "when given list of existing fields" $ do it "retains field order" $ do
test/Hpack/Syntax/DependenciesSpec.hs view
@@ -212,7 +212,7 @@ outer-name: name: inner-name path: somewhere- |] `shouldDecodeTo` Right (Dependencies [("outer-name", defaultInfo { dependencyInfoVersion = DependencyVersion source AnyVersion })], ["$.outer-name.name"])+ |] `shouldDecodeTo` Right (Dependencies [("outer-name", defaultInfo { dependencyInfoVersion = DependencyVersion source AnyVersion })], ["$.outer-name.name"], []) it "defaults to any version" $ do [yaml|