From 32ff1cac28206ae320c2cb39dce2d07d74991799 Mon Sep 17 00:00:00 2001 From: Duncan Coutts Date: Sun, 24 Dec 2017 16:19:57 +0000 Subject: [PATCH] Add 'all-packages' section to cabal.project files Prior to this we had options that apply to all local packages, or options that apply to specific named packages. This new section allows all the same options but applies them to all packages local or not. --- .../Client/ProjectConfig/Legacy.hs | 67 ++++++++++++++----- .../Client/ProjectConfig/Types.hs | 4 ++ .../Distribution/Client/ProjectPlanning.hs | 18 +++-- .../Distribution/Client/ProjectConfig.hs | 11 +-- 4 files changed, 71 insertions(+), 29 deletions(-) diff --git a/cabal-install/Distribution/Client/ProjectConfig/Legacy.hs b/cabal-install/Distribution/Client/ProjectConfig/Legacy.hs index 8893dccf90a..814313f1e9a 100644 --- a/cabal-install/Distribution/Client/ProjectConfig/Legacy.hs +++ b/cabal-install/Distribution/Client/ProjectConfig/Legacy.hs @@ -102,6 +102,7 @@ data LegacyProjectConfig = LegacyProjectConfig { legacyPackagesNamed :: [Dependency], legacySharedConfig :: LegacySharedConfig, + legacyAllConfig :: LegacyPackageConfig, legacyLocalConfig :: LegacyPackageConfig, legacySpecificConfig :: MapMappend PackageName LegacyPackageConfig } deriving Generic @@ -226,6 +227,7 @@ convertLegacyProjectConfig legacyPackagesNamed, legacySharedConfig = LegacySharedConfig globalFlags configShFlags configExFlags installSharedFlags, + legacyAllConfig, legacyLocalConfig = LegacyPackageConfig configFlags installPerPkgFlags haddockFlags, legacySpecificConfig @@ -238,15 +240,18 @@ convertLegacyProjectConfig projectPackagesNamed = legacyPackagesNamed, projectConfigBuildOnly = configBuildOnly, - projectConfigShared = configAllPackages, + projectConfigShared = configPackagesShared, projectConfigProvenance = mempty, + projectConfigAllPackages = configAllPackages, projectConfigLocalPackages = configLocalPackages, projectConfigSpecificPackage = fmap perPackage legacySpecificConfig } where + configAllPackages = convertLegacyPerPackageFlags g i h + where LegacyPackageConfig g i h = legacyAllConfig configLocalPackages = convertLegacyPerPackageFlags configFlags installPerPkgFlags haddockFlags - configAllPackages = convertLegacyAllPackageFlags + configPackagesShared= convertLegacyAllPackageFlags globalFlags (configFlags <> configShFlags) configExFlags installSharedFlags configBuildOnly = convertLegacyBuildOnlyFlags @@ -436,6 +441,7 @@ convertToLegacyProjectConfig projectPackagesOptional, projectPackagesRepo, projectPackagesNamed, + projectConfigAllPackages, projectConfigLocalPackages, projectConfigSpecificPackage } = @@ -445,6 +451,8 @@ convertToLegacyProjectConfig legacyPackagesRepo = projectPackagesRepo, legacyPackagesNamed = projectPackagesNamed, legacySharedConfig = convertToLegacySharedConfig projectConfig, + legacyAllConfig = convertToLegacyPerPackageConfig + projectConfigAllPackages, legacyLocalConfig = convertToLegacyAllPackageConfig projectConfig <> convertToLegacyPerPackageConfig projectConfigLocalPackages, @@ -1030,6 +1038,7 @@ legacyPackageConfigFieldDescrs = legacyPackageConfigSectionDescrs :: [SectionDescr LegacyProjectConfig] legacyPackageConfigSectionDescrs = [ packageRepoSectionDescr + , allPackagesOptionsSectionDescr , packageSpecificOptionsSectionDescr , liftSection legacyLocalConfig @@ -1074,26 +1083,48 @@ packageRepoSectionDescr = } } +packageSpecificOptionsFieldDescrs :: [FieldDescr LegacyPackageConfig] +packageSpecificOptionsFieldDescrs = + legacyPackageConfigFieldDescrs + ++ programOptionsFieldDescrs + (configProgramArgs . legacyConfigureFlags) + (\args pkgconf -> pkgconf { + legacyConfigureFlags = (legacyConfigureFlags pkgconf) { + configProgramArgs = args + } + } + ) + ++ liftFields + legacyConfigureFlags + (\flags pkgconf -> pkgconf { + legacyConfigureFlags = flags + } + ) + programLocationsFieldDescrs + +allPackagesOptionsSectionDescr :: SectionDescr LegacyProjectConfig +allPackagesOptionsSectionDescr = + SectionDescr { + sectionName = "all-packages", + sectionFields = packageSpecificOptionsFieldDescrs, + sectionSubsections = [], + sectionGet = (\x->[("", x)]) + . legacyAllConfig, + sectionSet = + \lineno unused pkgsconf projconf -> do + unless (null unused) $ + syntaxError lineno "the section 'all-packages' takes no arguments" + return projconf { + legacyAllConfig = legacyAllConfig projconf <> pkgsconf + }, + sectionEmpty = mempty + } + packageSpecificOptionsSectionDescr :: SectionDescr LegacyProjectConfig packageSpecificOptionsSectionDescr = SectionDescr { sectionName = "package", - sectionFields = legacyPackageConfigFieldDescrs - ++ programOptionsFieldDescrs - (configProgramArgs . legacyConfigureFlags) - (\args pkgconf -> pkgconf { - legacyConfigureFlags = (legacyConfigureFlags pkgconf) { - configProgramArgs = args - } - } - ) - ++ liftFields - legacyConfigureFlags - (\flags pkgconf -> pkgconf { - legacyConfigureFlags = flags - } - ) - programLocationsFieldDescrs, + sectionFields = packageSpecificOptionsFieldDescrs, sectionSubsections = [], sectionGet = \projconf -> [ (display pkgname, pkgconf) diff --git a/cabal-install/Distribution/Client/ProjectConfig/Types.hs b/cabal-install/Distribution/Client/ProjectConfig/Types.hs index ec125ac03bc..73353f636c0 100644 --- a/cabal-install/Distribution/Client/ProjectConfig/Types.hs +++ b/cabal-install/Distribution/Client/ProjectConfig/Types.hs @@ -113,6 +113,10 @@ data ProjectConfig projectConfigShared :: ProjectConfigShared, projectConfigProvenance :: Set ProjectConfigProvenance, + -- | Configuration to be applied to *all* packages, + -- whether named in `cabal.project` or not. + projectConfigAllPackages :: PackageConfig, + -- | Configuration to be applied to *local* packages; i.e., -- any packages which are explicitly named in `cabal.project`. projectConfigLocalPackages :: PackageConfig, diff --git a/cabal-install/Distribution/Client/ProjectPlanning.hs b/cabal-install/Distribution/Client/ProjectPlanning.hs index 8e7020bcd05..6f77825bf59 100644 --- a/cabal-install/Distribution/Client/ProjectPlanning.hs +++ b/cabal-install/Distribution/Client/ProjectPlanning.hs @@ -590,6 +590,7 @@ rebuildInstallPlan verbosity , ElaboratedSharedConfig ) phaseElaboratePlan ProjectConfig { projectConfigShared, + projectConfigAllPackages, projectConfigLocalPackages, projectConfigSpecificPackage, projectConfigBuildOnly @@ -617,6 +618,7 @@ rebuildInstallPlan verbosity sourcePackageHashes defaultInstallDirs projectConfigShared + projectConfigAllPackages projectConfigLocalPackages (getMapMappend projectConfigSpecificPackage) let instantiatedPlan = instantiateInstallPlan elaboratedPlan @@ -1142,6 +1144,7 @@ elaborateInstallPlan -> InstallDirs.InstallDirTemplates -> ProjectConfigShared -> PackageConfig + -> PackageConfig -> Map PackageName PackageConfig -> LogProgress (ElaboratedInstallPlan, ElaboratedSharedConfig) elaborateInstallPlan verbosity platform compiler compilerprogdb pkgConfigDB @@ -1151,6 +1154,7 @@ elaborateInstallPlan verbosity platform compiler compilerprogdb pkgConfigDB sourcePackageHashes defaultInstallDirs sharedPackageConfig + allPackagesConfig localPackagesConfig perPackageConfig = do x <- elaboratedInstallPlan @@ -1758,14 +1762,14 @@ elaborateInstallPlan verbosity platform compiler compilerprogdb pkgConfigDB lookupPerPkgOption :: (Package pkg, Monoid m) => pkg -> (PackageConfig -> m) -> m - lookupPerPkgOption pkg f - -- the project config specifies values that apply to packages local to - -- but by default non-local packages get all default config values - -- the project, and can specify per-package values for any package, - | isLocalToProject pkg = local `mappend` perpkg - | otherwise = perpkg + lookupPerPkgOption pkg f = + global `mappend` local `mappend` perpkg where - local = f localPackagesConfig + global = f allPackagesConfig + local | isLocalToProject pkg + = f localPackagesConfig + | otherwise + = mempty perpkg = maybe mempty f (Map.lookup (packageName pkg) perPackageConfig) inplacePackageDbs = storePackageDbs diff --git a/cabal-install/tests/UnitTests/Distribution/Client/ProjectConfig.hs b/cabal-install/tests/UnitTests/Distribution/Client/ProjectConfig.hs index 23c76e27742..ec5ddabdcf9 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/ProjectConfig.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/ProjectConfig.hs @@ -284,6 +284,7 @@ instance Arbitrary ProjectConfig where <*> arbitrary <*> arbitrary <*> arbitrary + <*> arbitrary <*> (MapMappend . fmap getNonMEmpty . Map.fromList <$> shortListOf 3 arbitrary) -- package entries with no content are equivalent to @@ -297,7 +298,8 @@ instance Arbitrary ProjectConfig where , projectConfigShared = x5 , projectConfigProvenance = x6 , projectConfigLocalPackages = x7 - , projectConfigSpecificPackage = x8 } = + , projectConfigSpecificPackage = x8 + , projectConfigAllPackages = x9 } = [ ProjectConfig { projectPackages = x0' , projectPackagesOptional = x1' , projectPackagesRepo = x2' @@ -307,10 +309,11 @@ instance Arbitrary ProjectConfig where , projectConfigProvenance = x6' , projectConfigLocalPackages = x7' , projectConfigSpecificPackage = (MapMappend - (fmap getNonMEmpty x8')) } - | ((x0', x1', x2', x3'), (x4', x5', x6', x7', x8')) + (fmap getNonMEmpty x8')) + , projectConfigAllPackages = x9' } + | ((x0', x1', x2', x3'), (x4', x5', x6', x7', x8', x9')) <- shrink ((x0, x1, x2, x3), - (x4, x5, x6, x7, fmap NonMEmpty (getMapMappend x8))) + (x4, x5, x6, x7, fmap NonMEmpty (getMapMappend x8), x9)) ] newtype PackageLocationString