packages feed

hpack 0.10.0 → 0.11.0

raw patch · 6 files changed

+367/−69 lines, 6 filesdep +containersPVP ok

version bump matches the API change (PVP)

Dependencies added: containers

API changes (from Hackage documentation)

- Hpack.Config: Condition :: String -> Condition
- Hpack.Config: [conditionCondition] :: Condition -> String
- Hpack.Config: newtype Condition
+ Hpack.Config: Conditional :: String -> Section () -> Maybe (Section ()) -> Conditional
+ Hpack.Config: Flag :: String -> Maybe String -> Bool -> Bool -> Flag
+ Hpack.Config: [conditionalCondition] :: Conditional -> String
+ Hpack.Config: [conditionalElse] :: Conditional -> Maybe (Section ())
+ Hpack.Config: [conditionalThen] :: Conditional -> Section ()
+ Hpack.Config: [flagDefault] :: Flag -> Bool
+ Hpack.Config: [flagDescription] :: Flag -> Maybe String
+ Hpack.Config: [flagManual] :: Flag -> Bool
+ Hpack.Config: [flagName] :: Flag -> String
+ Hpack.Config: [libraryExposed] :: Library -> Maybe Bool
+ Hpack.Config: [packageFlags] :: Package -> [Flag]
+ Hpack.Config: [sectionBuildable] :: Section a -> Maybe Bool
+ Hpack.Config: [sectionIncludeDirs] :: Section a -> [FilePath]
+ Hpack.Config: [sectionInstallIncludes] :: Section a -> [FilePath]
+ Hpack.Config: [sectionLdOptions] :: Section a -> [LdOption]
+ Hpack.Config: data Conditional
+ Hpack.Config: data Flag
+ Hpack.Config: instance Data.Aeson.Types.Class.FromJSON (Hpack.Config.CaptureUnknownFields Hpack.Config.FlagSection)
+ Hpack.Config: instance Data.Aeson.Types.Class.FromJSON (Hpack.Config.CaptureUnknownFields Hpack.Config.ThenElse)
+ Hpack.Config: instance Data.Aeson.Types.Class.FromJSON Hpack.Config.ConditionalSection
+ Hpack.Config: instance Data.Aeson.Types.Class.FromJSON Hpack.Config.Empty
+ Hpack.Config: instance Data.Aeson.Types.Class.FromJSON Hpack.Config.FlagSection
+ Hpack.Config: instance Data.Aeson.Types.Class.FromJSON Hpack.Config.ThenElse
+ Hpack.Config: instance GHC.Classes.Eq Hpack.Config.Conditional
+ Hpack.Config: instance GHC.Classes.Eq Hpack.Config.ConditionalSection
+ Hpack.Config: instance GHC.Classes.Eq Hpack.Config.Empty
+ Hpack.Config: instance GHC.Classes.Eq Hpack.Config.Flag
+ Hpack.Config: instance GHC.Classes.Eq Hpack.Config.FlagSection
+ Hpack.Config: instance GHC.Classes.Eq Hpack.Config.ThenElse
+ Hpack.Config: instance GHC.Generics.Constructor Hpack.Config.C1_0FlagSection
+ Hpack.Config: instance GHC.Generics.Constructor Hpack.Config.C1_0ThenElse
+ Hpack.Config: instance GHC.Generics.Datatype Hpack.Config.D1FlagSection
+ Hpack.Config: instance GHC.Generics.Datatype Hpack.Config.D1ThenElse
+ Hpack.Config: instance GHC.Generics.Generic Hpack.Config.FlagSection
+ Hpack.Config: instance GHC.Generics.Generic Hpack.Config.ThenElse
+ Hpack.Config: instance GHC.Generics.Selector Hpack.Config.S1_0_0FlagSection
+ Hpack.Config: instance GHC.Generics.Selector Hpack.Config.S1_0_0ThenElse
+ Hpack.Config: instance GHC.Generics.Selector Hpack.Config.S1_0_10CommonOptions
+ Hpack.Config: instance GHC.Generics.Selector Hpack.Config.S1_0_11CommonOptions
+ Hpack.Config: instance GHC.Generics.Selector Hpack.Config.S1_0_1FlagSection
+ Hpack.Config: instance GHC.Generics.Selector Hpack.Config.S1_0_1ThenElse
+ Hpack.Config: instance GHC.Generics.Selector Hpack.Config.S1_0_21PackageConfig
+ Hpack.Config: instance GHC.Generics.Selector Hpack.Config.S1_0_22PackageConfig
+ Hpack.Config: instance GHC.Generics.Selector Hpack.Config.S1_0_2FlagSection
+ Hpack.Config: instance GHC.Generics.Selector Hpack.Config.S1_0_2ThenElse
+ Hpack.Config: instance GHC.Generics.Selector Hpack.Config.S1_0_3LibrarySection
+ Hpack.Config: instance GHC.Generics.Selector Hpack.Config.S1_0_8CommonOptions
+ Hpack.Config: instance GHC.Generics.Selector Hpack.Config.S1_0_9CommonOptions
+ Hpack.Config: instance GHC.Show.Show Hpack.Config.Conditional
+ Hpack.Config: instance GHC.Show.Show Hpack.Config.ConditionalSection
+ Hpack.Config: instance GHC.Show.Show Hpack.Config.Empty
+ Hpack.Config: instance GHC.Show.Show Hpack.Config.Flag
+ Hpack.Config: instance GHC.Show.Show Hpack.Config.FlagSection
+ Hpack.Config: instance GHC.Show.Show Hpack.Config.ThenElse
+ Hpack.Config: instance Hpack.Config.HasFieldNames Hpack.Config.Empty
+ Hpack.Config: instance Hpack.Config.HasFieldNames Hpack.Config.FlagSection
+ Hpack.Config: instance Hpack.Config.HasFieldNames Hpack.Config.ThenElse
- Hpack.Config: Library :: [String] -> [String] -> [String] -> Library
+ Hpack.Config: Library :: Maybe Bool -> [String] -> [String] -> [String] -> Library
- Hpack.Config: Package :: String -> String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> [String] -> [String] -> [String] -> Maybe String -> Maybe FilePath -> Maybe String -> [FilePath] -> [FilePath] -> Maybe SourceRepository -> Maybe (Section Library) -> [Section Executable] -> [Section Executable] -> [Section Executable] -> Package
+ Hpack.Config: Package :: String -> String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> [String] -> [String] -> [String] -> Maybe String -> Maybe FilePath -> Maybe String -> [Flag] -> [FilePath] -> [FilePath] -> Maybe SourceRepository -> Maybe (Section Library) -> [Section Executable] -> [Section Executable] -> [Section Executable] -> Package
- Hpack.Config: Section :: a -> [FilePath] -> [Dependency] -> [String] -> [String] -> [GhcOption] -> [GhcProfOption] -> [CppOption] -> [Section Condition] -> Section a
+ Hpack.Config: Section :: a -> [FilePath] -> [Dependency] -> [String] -> [String] -> [GhcOption] -> [GhcProfOption] -> [CppOption] -> [FilePath] -> [FilePath] -> [LdOption] -> Maybe Bool -> [Conditional] -> Section a
- Hpack.Config: [sectionConditionals] :: Section a -> [Section Condition]
+ Hpack.Config: [sectionConditionals] :: Section a -> [Conditional]

Files

hpack.cabal view
@@ -1,9 +1,9 @@--- This file has been generated from package.yaml by hpack version 0.9.1.+-- This file has been generated from package.yaml by hpack version 0.10.0. -- -- see: https://github.com/sol/hpack  name:           hpack-version:        0.10.0+version:        0.11.0 synopsis:       An alternative format for Haskell packages category:       Development homepage:       https://github.com/sol/hpack#readme@@ -30,6 +30,7 @@     , filepath     , Glob     , text+    , containers     , unordered-containers     , yaml     , aeson >= 0.8@@ -59,6 +60,7 @@     , filepath     , Glob     , text+    , containers     , unordered-containers     , yaml     , hpack@@ -81,6 +83,7 @@     , filepath     , Glob     , text+    , containers     , unordered-containers     , yaml     , hspec == 2.*
src/Hpack/Config.hs view
@@ -9,6 +9,7 @@ {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE CPP #-}+{-# LANGUAGE ScopedTypeVariables #-} module Hpack.Config (   packageConfig , readPackageConfig@@ -24,11 +25,13 @@ , Section(..) , Library(..) , Executable(..)-, Condition(..)+, Conditional(..)+, Flag(..) , SourceRepository(..) #ifdef TEST , HasFieldNames(..) , CaptureUnknownFields(..)+, Empty(..) , getModules , determineModules #endif@@ -38,8 +41,9 @@ import           Control.Monad.Compat import           Data.Aeson.Types import           Data.Data-import           Data.HashMap.Lazy (HashMap)-import qualified Data.HashMap.Lazy as Map+import           Data.Map.Lazy (Map)+import qualified Data.Map.Lazy as Map+import qualified Data.HashMap.Lazy as HashMap import           Data.List (nub, (\\), sortBy) import           Data.Maybe import           Data.Ord@@ -57,10 +61,10 @@ import           Hpack.Yaml  package :: String -> String -> Package-package name version = Package name version Nothing Nothing Nothing Nothing Nothing Nothing [] [] [] Nothing Nothing Nothing [] [] Nothing Nothing [] [] []+package name version = Package name version Nothing Nothing Nothing Nothing Nothing Nothing [] [] [] Nothing Nothing Nothing [] [] [] Nothing Nothing [] [] []  section :: a -> Section a-section a = Section a [] [] [] [] [] [] [] []+section a = Section a [] [] [] [] [] [] [] [] [] [] Nothing []  packageConfig :: FilePath packageConfig = "package.yaml"@@ -81,7 +85,7 @@ #else   camelTo #endif-  '-' . drop (length name)+  '-' . drop (length name) . dropWhile (== '_')  type FieldName = String @@ -96,6 +100,11 @@ , captureUnknownFieldsValue :: a } deriving (Eq, Show, Generic) +captureUnknownFields :: forall a. (HasFieldNames a, FromJSON a) => Value -> Parser (CaptureUnknownFields a)+captureUnknownFields v = CaptureUnknownFields unknown <$> parseJSON v+  where+    unknown = getUnknownFields v (Proxy :: Proxy a)+ instance (HasFieldNames a, FromJSON a) => FromJSON (CaptureUnknownFields (Section a)) where   parseJSON v = do     (unknownFields, sect) <- toSection <$> parseJSON v <*> parseJSON v@@ -103,17 +112,21 @@     where       unknownSectionFields = getUnknownFields v (Proxy :: Proxy (Section a)) +instance FromJSON (CaptureUnknownFields FlagSection) where+  parseJSON = captureUnknownFields+ getUnknownFields :: forall a. HasFieldNames a => Value -> Proxy a -> [FieldName] getUnknownFields v _ = case v of   Object o -> unknown     where       unknown = keys \\ fields-      keys = map T.unpack (Map.keys o)+      keys = map T.unpack (HashMap.keys o)       fields = fieldNames (Proxy :: Proxy a)   _ -> []  data LibrarySection = LibrarySection {-  librarySectionExposedModules :: Maybe (List String)+  librarySectionExposed :: Maybe Bool+, librarySectionExposedModules :: Maybe (List String) , librarySectionOtherModules :: Maybe (List String) , librarySectionReexportedModules :: Maybe (List String) } deriving (Eq, Show, Generic)@@ -141,7 +154,11 @@ , commonOptionsGhcOptions :: Maybe (List GhcOption) , commonOptionsGhcProfOptions :: Maybe (List GhcProfOption) , commonOptionsCppOptions :: Maybe (List CppOption)-, commonOptionsWhen :: Maybe (List (CaptureUnknownFields (Section Condition)))+, commonOptionsIncludeDirs :: Maybe (List FilePath)+, commonOptionsInstallIncludes :: Maybe (List FilePath)+, commonOptionsLdOptions :: Maybe (List LdOption)+, commonOptionsBuildable :: Maybe Bool+, commonOptionsWhen :: Maybe (List ConditionalSection) } deriving (Eq, Show, Generic)  instance HasFieldNames CommonOptions@@ -149,6 +166,18 @@ instance FromJSON CommonOptions where   parseJSON = genericParseJSON_ +data ConditionalSection = ThenElseConditional (CaptureUnknownFields ThenElse) | FlatConditional (CaptureUnknownFields (Section Condition))+  deriving (Eq, Show)++instance FromJSON ConditionalSection where+  parseJSON v+    | hasKey "then" v || hasKey "else" v = ThenElseConditional <$> parseJSON v+    | otherwise = FlatConditional <$> parseJSON v++hasKey :: Text -> Value -> Bool+hasKey key (Object o) = HashMap.member key o+hasKey _ _ = False+ newtype Condition = Condition {   conditionCondition :: String } deriving (Eq, Show, Generic)@@ -158,6 +187,29 @@  instance HasFieldNames Condition +data ThenElse = ThenElse {+  _thenElseCondition :: String+, _thenElseThen :: (CaptureUnknownFields (Section Empty))+, _thenElseElse :: (CaptureUnknownFields (Section Empty))+} deriving (Eq, Show, Generic)++instance FromJSON (CaptureUnknownFields ThenElse) where+  parseJSON = captureUnknownFields++instance HasFieldNames ThenElse++instance FromJSON ThenElse where+  parseJSON = genericParseJSON_++data Empty = Empty+  deriving (Eq, Show)++instance FromJSON Empty where+  parseJSON _ = return Empty++instance HasFieldNames Empty where+  fieldNames _ = []+ data PackageConfig = PackageConfig {   packageConfigName :: Maybe String , packageConfigVersion :: Maybe String@@ -173,13 +225,15 @@ , packageConfigLicense :: Maybe String , packageConfigLicenseFile :: Maybe String , packageConfigTestedWith :: Maybe String+, packageConfigFlags :: Maybe (Map String (CaptureUnknownFields FlagSection)) , packageConfigExtraSourceFiles :: Maybe (List FilePath) , packageConfigDataFiles :: Maybe (List FilePath) , packageConfigGithub :: Maybe Text+, packageConfigGit :: Maybe String , packageConfigLibrary :: Maybe (CaptureUnknownFields (Section LibrarySection))-, packageConfigExecutables :: Maybe (HashMap String (CaptureUnknownFields (Section ExecutableSection)))-, packageConfigTests :: Maybe (HashMap String (CaptureUnknownFields (Section ExecutableSection)))-, packageConfigBenchmarks :: Maybe (HashMap String (CaptureUnknownFields (Section ExecutableSection)))+, packageConfigExecutables :: Maybe (Map String (CaptureUnknownFields (Section ExecutableSection)))+, packageConfigTests :: Maybe (Map String (CaptureUnknownFields (Section ExecutableSection)))+, packageConfigBenchmarks :: Maybe (Map String (CaptureUnknownFields (Section ExecutableSection))) } deriving (Eq, Show, Generic)  instance HasFieldNames PackageConfig@@ -275,6 +329,7 @@ , packageLicense :: Maybe String , packageLicenseFile :: Maybe FilePath , packageTestedWith :: Maybe String+, packageFlags :: [Flag] , packageExtraSourceFiles :: [FilePath] , packageDataFiles :: [FilePath] , packageSourceRepository :: Maybe SourceRepository@@ -285,7 +340,8 @@ } deriving (Eq, Show)  data Library = Library {-  libraryExposedModules :: [String]+  libraryExposed :: Maybe Bool+, libraryExposedModules :: [String] , libraryOtherModules :: [String] , libraryReexportedModules :: [String] } deriving (Eq, Show)@@ -305,12 +361,43 @@ , sectionGhcOptions :: [GhcOption] , sectionGhcProfOptions :: [GhcProfOption] , sectionCppOptions :: [CppOption]-, sectionConditionals :: [Section Condition]+, sectionIncludeDirs :: [FilePath]+, sectionInstallIncludes :: [FilePath]+, sectionLdOptions :: [LdOption]+, sectionBuildable :: Maybe Bool+, sectionConditionals :: [Conditional] } deriving (Eq, Show, Functor, Foldable, Traversable) +data Conditional = Conditional {+  conditionalCondition :: String+, conditionalThen :: Section ()+, conditionalElse :: Maybe (Section ())+} deriving (Eq, Show)+ instance HasFieldNames a => HasFieldNames (Section a) where   fieldNames Proxy = fieldNames (Proxy :: Proxy a) ++ fieldNames (Proxy :: Proxy CommonOptions) +data FlagSection = FlagSection {+  _flagSectionDescription :: Maybe String+, _flagSectionManual :: Bool+, _flagSectionDefault :: Bool+} deriving (Eq, Show, Generic)++instance HasFieldNames FlagSection++instance FromJSON FlagSection where+  parseJSON = genericParseJSON_++data Flag = Flag {+  flagName :: String+, flagDescription :: Maybe String+, flagManual :: Bool+, flagDefault :: Bool+} deriving (Eq, Show)++toFlag :: (String, FlagSection) -> Flag+toFlag (name, FlagSection description manual def) = Flag name description manual def+ data SourceRepository = SourceRepository {   sourceRepositoryUrl :: String , sourceRepositorySubdir :: Maybe String@@ -355,6 +442,7 @@       , packageLicense = packageConfigLicense       , packageLicenseFile = packageConfigLicenseFile <|> (guard licenseFileExists >> Just "LICENSE")       , packageTestedWith = packageConfigTestedWith+      , packageFlags = flags       , packageExtraSourceFiles = extraSourceFiles       , packageDataFiles = dataFiles       , packageSourceRepository = sourceRepository@@ -366,6 +454,7 @@        warnings =            formatUnknownFields "package description" unknownFields+        ++ flagWarnings         ++ maybe [] (formatUnknownFields "library section") (captureUnknownFieldsFields <$> packageConfigLibrary)         ++ formatUnknownSectionFields "executable" executableSections         ++ formatUnknownSectionFields "test" testsSections@@ -384,7 +473,16 @@     benchmarkSections :: [(String, CaptureUnknownFields (Section ExecutableSection))]     benchmarkSections = toList packageConfigBenchmarks -    toList :: Maybe (HashMap String a) -> [(String, a)]+    (flagWarnings, flags) = (concatMap formatUnknownFlagFields xs, map (toFlag . fmap captureUnknownFieldsValue) xs)+      where+        xs :: [(String, CaptureUnknownFields FlagSection)]+        xs = toList packageConfigFlags++        formatUnknownFlagFields :: (String, CaptureUnknownFields a) -> [String]+        formatUnknownFlagFields (name, fields) = map f (captureUnknownFieldsFields fields)+          where f field = "Ignoring unknown field " ++ show field ++ " for flag " ++ show name++    toList :: Maybe (Map String a) -> [(String, a)]     toList = Map.toList . fromMaybe mempty      mLibrarySection :: Maybe (Section LibrarySection)@@ -406,7 +504,10 @@         f name = "Specified source-dir " ++ show name ++ " does not exist"      sourceRepository :: Maybe SourceRepository-    sourceRepository = parseGithub <$> packageConfigGithub+    sourceRepository = github <|> (`SourceRepository` Nothing) <$> packageConfigGit++    github :: Maybe SourceRepository+    github = parseGithub <$> packageConfigGithub       where         parseGithub :: Text -> SourceRepository         parseGithub input = case map T.unpack $ T.splitOn "/" input of@@ -419,14 +520,14 @@       Just Nothing -> Nothing       _ -> join packageConfigHomepage <|> fromGithub       where-        fromGithub = (++ "#readme") . sourceRepositoryUrl <$> sourceRepository+        fromGithub = (++ "#readme") . sourceRepositoryUrl <$> github      bugReports :: Maybe String     bugReports = case packageConfigBugReports of       Just Nothing -> Nothing       _ -> join packageConfigBugReports <|> fromGithub       where-        fromGithub = (++ "/issues") . sourceRepositoryUrl <$> sourceRepository+        fromGithub = (++ "/issues") . sourceRepositoryUrl <$> github  toLibrary :: FilePath -> String -> Section global -> Section LibrarySection -> IO (Section Library) toLibrary dir name globalOptions library = traverse fromLibrarySection sect@@ -442,7 +543,7 @@       modules <- concat <$> mapM (getModules dir) sourceDirs       let (exposedModules, otherModules) = determineModules name modules librarySectionExposedModules librarySectionOtherModules           reexportedModules = fromMaybeList librarySectionReexportedModules-      return (Library exposedModules otherModules reexportedModules)+      return (Library librarySectionExposed exposedModules otherModules reexportedModules)  toExecutables :: FilePath -> Section global -> [(String, Section ExecutableSection)] -> IO [Section Executable] toExecutables dir globalOptions executables = mapM toExecutable sections@@ -467,7 +568,7 @@  mergeSections :: Section global -> Section a -> Section a mergeSections globalOptions options-  = Section a sourceDirs dependencies defaultExtensions otherExtensions ghcOptions ghcProfOptions cppOptions conditionals+  = Section a sourceDirs dependencies defaultExtensions otherExtensions ghcOptions ghcProfOptions cppOptions includeDirs installIncludes ldOptions buildable conditionals   where     a = sectionData options     sourceDirs = sectionSourceDirs globalOptions ++ sectionSourceDirs options@@ -476,12 +577,16 @@     ghcOptions = sectionGhcOptions globalOptions ++ sectionGhcOptions options     ghcProfOptions = sectionGhcProfOptions globalOptions ++ sectionGhcProfOptions options     cppOptions = sectionCppOptions globalOptions ++ sectionCppOptions options+    includeDirs = sectionIncludeDirs globalOptions ++ sectionIncludeDirs options+    installIncludes = sectionInstallIncludes globalOptions ++ sectionInstallIncludes options+    ldOptions = sectionLdOptions globalOptions ++ sectionLdOptions options+    buildable = sectionBuildable options <|> sectionBuildable globalOptions     dependencies = sectionDependencies globalOptions ++ sectionDependencies options     conditionals = sectionConditionals globalOptions ++ sectionConditionals options  toSection :: a -> CommonOptions -> ([FieldName], Section a) toSection a CommonOptions{..}-  = (concat unknownFields, Section a sourceDirs dependencies defaultExtensions otherExtensions ghcOptions ghcProfOptions cppOptions conditionals)+  = (concat unknownFields, Section a sourceDirs dependencies defaultExtensions otherExtensions ghcOptions ghcProfOptions cppOptions includeDirs installIncludes ldOptions buildable conditionals)   where     sourceDirs = fromMaybeList commonOptionsSourceDirs     defaultExtensions = fromMaybeList commonOptionsDefaultExtensions@@ -489,9 +594,18 @@     ghcOptions = fromMaybeList commonOptionsGhcOptions     ghcProfOptions = fromMaybeList commonOptionsGhcProfOptions     cppOptions = fromMaybeList commonOptionsCppOptions+    includeDirs = fromMaybeList commonOptionsIncludeDirs+    installIncludes = fromMaybeList commonOptionsInstallIncludes+    ldOptions = fromMaybeList commonOptionsLdOptions+    buildable = commonOptionsBuildable     dependencies = fromMaybeList commonOptionsDependencies-    (unknownFields, conditionals) =-      unzip [(field, value) | CaptureUnknownFields field value <- fromMaybeList commonOptionsWhen]+    (unknownFields, conditionals) = unzip (map toConditional $ fromMaybeList commonOptionsWhen)++toConditional :: ConditionalSection -> ([FieldName], Conditional)+toConditional x = case x of+  ThenElseConditional (CaptureUnknownFields fields (ThenElse condition (CaptureUnknownFields fieldsThen then_) (CaptureUnknownFields fieldsElse else_))) ->+      (fields ++ fieldsThen ++ fieldsElse, Conditional condition (() <$ then_) (Just (() <$ else_)))+  FlatConditional (CaptureUnknownFields fields sect) -> (fields, Conditional (conditionCondition $ sectionData sect) (() <$ sect) Nothing)  pathsModuleFromPackageName :: String -> String pathsModuleFromPackageName name = "Paths_" ++ map f name
src/Hpack/Run.hs view
@@ -11,6 +11,7 @@ , defaultRenderSettings #ifdef TEST , renderConditional+, renderFlag , renderSourceRepository , formatDescription #endif@@ -67,6 +68,7 @@     stanzas = extraSourceFiles             : dataFiles             : sourceRepository+            ++ map renderFlag packageFlags             ++ library             ++ renderExecutables packageExecutables             ++ renderTests packageTests@@ -157,6 +159,14 @@   , Field "subdir" (maybe "" Literal sourceRepositorySubdir)   ] +renderFlag :: Flag -> Element+renderFlag Flag {..} = Stanza ("flag " ++ flagName) $ description ++ [+    Field "manual" (Literal $ show flagManual)+  , Field "default" (Literal $ show flagDefault)+  ]+  where+    description = maybe [] (return . Field "description" . Literal) flagDescription+ renderExecutables :: [Section Executable] -> [Element] renderExecutables = map renderExecutable @@ -189,13 +199,17 @@  renderLibrary :: Section Library -> Element renderLibrary sect@(sectionData -> Library{..}) = Stanza "library" $-  renderSection sect ++ [+  renderSection sect +++  maybe [] (return . renderExposed) libraryExposed ++ [     renderExposedModules libraryExposedModules   , renderOtherModules libraryOtherModules   , renderReexportedModules libraryReexportedModules   , defaultLanguage   ] +renderExposed :: Bool -> Element+renderExposed = Field "exposed" . Literal . show+ renderSection :: Section a -> [Element] renderSection Section{..} = [     renderSourceDirs sectionSourceDirs@@ -204,33 +218,36 @@   , renderGhcOptions sectionGhcOptions   , renderGhcProfOptions sectionGhcProfOptions   , renderCppOptions sectionCppOptions+  , Field "include-dirs" (LineSeparatedList sectionIncludeDirs)+  , Field "install-includes" (LineSeparatedList sectionInstallIncludes)+  , renderLdOptions sectionLdOptions   , renderDependencies sectionDependencies   ]-  ++ map renderConditional sectionConditionals+  ++ maybe [] (return . renderBuildable) sectionBuildable+  ++ concatMap renderConditional sectionConditionals -renderConditional :: Section Condition -> Element-renderConditional sect = Stanza condition (renderSection sect)+renderConditional :: Conditional -> [Element]+renderConditional (Conditional condition sect mElse) = Stanza ("if " ++ condition) (renderSection sect) : else_   where-    condition :: String-    condition = "if " ++ conditionCondition (sectionData sect)+    else_ = maybe [] (return . Stanza "else" . renderSection) mElse  defaultLanguage :: Element defaultLanguage = Field "default-language" "Haskell2010"  renderSourceDirs :: [String] -> Element-renderSourceDirs dirs = Field "hs-source-dirs" (CommaSeparatedList dirs)+renderSourceDirs = Field "hs-source-dirs" . CommaSeparatedList  renderExposedModules :: [String] -> Element-renderExposedModules modules = Field "exposed-modules" (LineSeparatedList modules)+renderExposedModules = Field "exposed-modules" . LineSeparatedList  renderOtherModules :: [String] -> Element-renderOtherModules modules = Field "other-modules" (LineSeparatedList modules)+renderOtherModules = Field "other-modules" . LineSeparatedList  renderReexportedModules :: [String] -> Element-renderReexportedModules modules = Field "reexported-modules" (LineSeparatedList modules)+renderReexportedModules = Field "reexported-modules" . LineSeparatedList  renderDependencies :: [Dependency] -> Element-renderDependencies dependencies = Field "build-depends" (CommaSeparatedList $ map dependencyName dependencies)+renderDependencies = Field "build-depends" . CommaSeparatedList . map dependencyName  renderGhcOptions :: [GhcOption] -> Element renderGhcOptions = Field "ghc-options" . WordList@@ -240,6 +257,12 @@  renderCppOptions :: [CppOption] -> Element renderCppOptions = Field "cpp-options" . WordList++renderLdOptions :: [LdOption] -> Element+renderLdOptions = Field "ld-options" . WordList++renderBuildable :: Bool -> Element+renderBuildable = Field "buildable" . Literal . show  renderDefaultExtensions :: [String] -> Element renderDefaultExtensions = Field "default-extensions" . WordList
src/Hpack/Util.hs view
@@ -5,6 +5,7 @@ , GhcOption , GhcProfOption , CppOption+, LdOption , parseMain , toModule , getFilesRecursive@@ -53,6 +54,7 @@ type GhcOption = String type GhcProfOption = String type CppOption = String+type LdOption = String  parseMain :: String -> (FilePath, [GhcOption]) parseMain main = case reverse name of
test/Hpack/ConfigSpec.hs view
@@ -17,6 +17,7 @@ import           Control.Arrow import           System.Directory (createDirectory) import           Data.Yaml+import           Data.Either.Compat  import           Hpack.Util import           Hpack.Config hiding (package)@@ -29,7 +30,7 @@ executable name main_ = Executable name main_ []  library :: Library-library = Library [] [] []+library = Library Nothing [] [] []  withPackage :: String -> IO () -> (([String], Package) -> Expectation) -> Expectation withPackage content beforeAction expectation = withTempDirectory $ \dir_ -> do@@ -52,15 +53,6 @@ withPackageWarnings_ :: String -> ([String] -> Expectation) -> Expectation withPackageWarnings_ content = withPackageWarnings content (return ()) -data Dummy = Dummy-  deriving (Eq, Show)--instance FromJSON Dummy where-  parseJSON _ = return Dummy--instance HasFieldNames Dummy where-  fieldNames _ = []- spec :: Spec spec = do   describe "parseJSON" $ do@@ -70,33 +62,101 @@               dependencies: hpack               |]         captureUnknownFieldsValue <$> decodeEither input-          `shouldBe` Right (section Dummy){sectionDependencies = ["hpack"]}+          `shouldBe` Right (section Empty){sectionDependencies = ["hpack"]} -      it "accepts conditionals" $ do+      it "accepts includes-dirs" $ do         let input = [i|-              when:-                condition: os(windows)-                dependencies: Win32+              include-dirs:+                - foo+                - bar               |]-            conditionals = [(section $ Condition "os(windows)"){sectionDependencies = ["Win32"]}]         captureUnknownFieldsValue <$> decodeEither input-          `shouldBe` Right (section Dummy){sectionConditionals = conditionals}+          `shouldBe` Right (section Empty){sectionIncludeDirs = ["foo", "bar"]} -      it "warns on unknown fields" $ do+      it "accepts install-includes" $ do         let input = [i|-              foo: 23-              when:-                - condition: os(windows)-                  bar: 23+              install-includes:+                - foo.h+                - bar.h+              |]+        captureUnknownFieldsValue <$> decodeEither input+          `shouldBe` Right (section Empty){sectionInstallIncludes = ["foo.h", "bar.h"]}++      context "when parsing conditionals" $ do+        it "accepts conditionals" $ do+          let input = [i|+                when:+                  condition: os(windows)+                  dependencies: Win32+                |]+              conditionals = [+                Conditional "os(windows)"+                (section ()){sectionDependencies = ["Win32"]}+                Nothing+                ]+          captureUnknownFieldsValue <$> decodeEither input+            `shouldBe` Right (section Empty){sectionConditionals = conditionals}++        it "warns on unknown fields" $ do+          let input = [i|+                foo: 23+                when:+                  - condition: os(windows)+                    bar: 23+                    when:+                      condition: os(windows)+                      bar2: 23+                  - condition: os(windows)+                    baz: 23+                |]+          captureUnknownFieldsFields <$> (decodeEither input :: Either String (CaptureUnknownFields (Section Empty)))+            `shouldBe` Right ["foo", "bar", "bar2", "baz"]++        context "when parsing conditionals with else-branch" $ do+          it "accepts conditionals with else-branch" $ do+            let input = [i|                   when:                     condition: os(windows)-                    bar2: 23-                - condition: os(windows)-                  baz: 23-              |]-        captureUnknownFieldsFields <$> (decodeEither input :: Either String (CaptureUnknownFields (Section Dummy)))-          `shouldBe` Right ["foo", "bar", "bar2", "baz"]+                    then:+                      dependencies: Win32+                    else:+                      dependencies: unix+                  |]+                conditionals = [+                  Conditional "os(windows)"+                  (section ()){sectionDependencies = ["Win32"]}+                  (Just (section ()){sectionDependencies = ["unix"]})+                  ]+                r :: Either String (Section Empty)+                r = captureUnknownFieldsValue <$> decodeEither input+            sectionConditionals <$> r `shouldBe` Right conditionals +          it "rejects invalid conditionals" $ do+            let input = [i|+                  when:+                    condition: os(windows)+                    then:+                      dependencies: Win32+                    else: null+                  |]++                r :: Either String (Section Empty)+                r = captureUnknownFieldsValue <$> decodeEither input+            sectionConditionals <$> r `shouldSatisfy` isLeft++          it "warns on unknown fields" $ do+            let input = [i|+                  when:+                    condition: os(windows)+                    foo: null+                    then:+                      bar: null+                    else:+                      baz: null+                  |]+            captureUnknownFieldsFields <$> (decodeEither input :: Either String (CaptureUnknownFields (Section Empty)))+              `shouldBe` Right ["foo", "bar", "baz"]+     context "when parsing a Dependency" $ do       it "accepts simple dependencies" $ do         parseEither parseJSON "hpack" `shouldBe` Right (Dependency "hpack" Nothing)@@ -334,6 +394,30 @@         |]         (packageLicenseFile >>> (`shouldBe` Just "FOO")) +    it "accepts flags" $ do+      withPackageConfig_ [i|+        flags:+          integration-tests:+            description: Run the integration test suite+            manual: yes+            default: no+        |]+        (packageFlags >>> (`shouldBe` [Flag "integration-tests" (Just "Run the integration test suite") True False]))++    it "warns on unknown fields in flag sections" $ do+      withPackageWarnings_ [i|+        flags:+          integration-tests:+            description: Run the integration test suite+            manual: yes+            default: no+            foo: 23+        |]+        (`shouldBe` [+          "Ignoring unknown field \"foo\" for flag \"integration-tests\""+        ]+        )+     it "accepts extra-source-files" $ do       withPackageConfig [i|         extra-source-files:@@ -369,6 +453,12 @@         |]         (packageSourceRepository >>> (`shouldBe` Just (SourceRepository "https://github.com/hspec/hspec" (Just "hspec-core")))) +    it "accepts arbitrary git URLs as source repository" $ do+      withPackageConfig_ [i|+        git: https://gitlab.com/gitlab-org/gitlab-ce.git+        |]+        (packageSourceRepository >>> (`shouldBe` Just (SourceRepository "https://gitlab.com/gitlab-org/gitlab-ce.git" Nothing)))+     it "accepts CPP options" $ do       withPackageConfig_ [i|         cpp-options: -DFOO@@ -393,6 +483,32 @@         }         ) +    it "accepts ld-options" $ do+      withPackageConfig_ [i|+        library:+          ld-options: -static+        |]+        (`shouldBe` package {+          packageLibrary = Just (section library) {sectionLdOptions = ["-static"]}+        }+        )++    it "accepts buildable" $ do+      withPackageConfig_ [i|+        buildable: no+        library:+          buildable: yes++        executables:+          foo:+            main: Main.hs+        |]+        (`shouldBe` package {+          packageLibrary = Just (section library) {sectionBuildable = Just True}+        , packageExecutables = [(section $ executable "foo" "Main.hs") {sectionBuildable = Just False}]+        }+        )+     context "when reading library section" $ do       it "warns on unknown fields" $ do         withPackageWarnings_ [i|@@ -441,6 +557,13 @@           library: {}           |]           (packageLibrary >>> (`shouldBe` Just (section library) {sectionSourceDirs = ["foo", "bar"]}))++      it "allows to specify exposed" $ do+        withPackageConfig_ [i|+          library:+            exposed: no+          |]+          (packageLibrary >>> (`shouldBe` Just (section library{libraryExposed = Just False})))        it "allows to specify exposed-modules" $ do         withPackageConfig [i|
test/Hpack/RunSpec.hs view
@@ -91,6 +91,18 @@         , "    bar"         ] +    it "includes buildable" $ do+      renderPackage_ 0 [] package {packageLibrary = Just (section library){sectionBuildable = Just False}} `shouldBe` unlines [+          "name: foo"+        , "version: 0.0.0"+        , "build-type: Simple"+        , "cabal-version: >= 1.10"+        , ""+        , "library"+        , "  buildable: False"+        , "  default-language: Haskell2010"+        ]+     context "when rendering library section" $ do       it "renders library section" $ do         renderPackage_ 0 [] package {packageLibrary = Just $ section library} `shouldBe` unlines [@@ -204,22 +216,43 @@           ]   describe "renderConditional" $ do     it "renders conditionals" $ do-      let conditional = (section $ Condition "os(windows)"){sectionDependencies = ["Win32"]}-      render defaultRenderSettings 0 (renderConditional conditional) `shouldBe` [+      let conditional = Conditional "os(windows)" (section ()) {sectionDependencies = ["Win32"]} Nothing+      concatMap (render defaultRenderSettings 0) (renderConditional conditional) `shouldBe` [           "if os(windows)"         , "  build-depends:"         , "      Win32"         ] +    it "renders conditionals with else-branch" $ do+      let conditional = Conditional "os(windows)" (section ()) {sectionDependencies = ["Win32"]} (Just $ (section ()) {sectionDependencies = ["unix"]})+      concatMap (render defaultRenderSettings 0) (renderConditional conditional) `shouldBe` [+          "if os(windows)"+        , "  build-depends:"+        , "      Win32"+        , "else"+        , "  build-depends:"+        , "      unix"+        ]+     it "renders nested conditionals" $ do-      let conditional = (section $ Condition "arch(i386)"){sectionGhcOptions = ["-threaded"], sectionConditionals = [innerConditional]}-          innerConditional = (section $ Condition "os(windows)"){sectionDependencies = ["Win32"]}-      render defaultRenderSettings 0 (renderConditional conditional) `shouldBe` [+      let conditional = Conditional "arch(i386)" (section ()) {sectionGhcOptions = ["-threaded"], sectionConditionals = [innerConditional]} Nothing+          innerConditional = Conditional "os(windows)" (section ()) {sectionDependencies = ["Win32"]} Nothing+      concatMap (render defaultRenderSettings 0) (renderConditional conditional) `shouldBe` [           "if arch(i386)"         , "  ghc-options: -threaded"         , "  if os(windows)"         , "    build-depends:"         , "        Win32"+        ]++  describe "renderFlag" $ do+    it "renders flags" $ do+      let flag = (Flag "foo" (Just "some flag") True False)+      render defaultRenderSettings 0 (renderFlag flag) `shouldBe` [+          "flag foo"+        , "  description: some flag"+        , "  manual: True"+        , "  default: False"         ]    describe "formatDescription" $ do