Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Global configuration for project commands #4888

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
.cabal-sandbox/
cabal.sandbox.config
cabal.project.local
cabal.config.local
.ghc.environment.*
cabal-dev/
.hpc/
Expand Down
12 changes: 9 additions & 3 deletions Cabal/doc/nix-local-build.rst
Original file line number Diff line number Diff line change
Expand Up @@ -481,11 +481,17 @@ following sources (later entries override earlier ones):

1. ``~/.cabal/config`` (the user-wide global configuration)

2. ``cabal.project`` (the project configuratoin)
2. ``cabal.config.local`` (the project-wide global configuration)

3. ``cabal.project.freeze`` (the output of ``cabal new-freeze``)
3. ``cabal.project`` (the project configuration)

4. ``cabal.project.local`` (the output of ``cabal new-configure``)
4. ``cabal.project.freeze`` (the output of ``cabal new-freeze``)

5. ``cabal.project.local`` (the output of ``cabal new-configure``)

The project configuration files ``cabal.project`` and ``cabal.project.local``
specify options for project packages only, while the global configuration files
``~/.cabal/config`` and ``cabal.config.local`` affect *all* packages.


Specifying the local packages
Expand Down
2 changes: 1 addition & 1 deletion cabal-install/Distribution/Client/CmdInstall.hs
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ establishDummyProjectBaseContext verbosity cliConfig tmpDir localPackages = do
createDirectoryIfMissingVerbose verbosity True $ distProjectCacheDirectory distDirLayout

globalConfig <- runRebuild ""
$ readGlobalConfig verbosity
$ readGlobalConfig verbosity distDirLayout
$ projectConfigConfigFile
$ projectConfigShared cliConfig
let projectConfig = globalConfig <> cliConfig
Expand Down
39 changes: 25 additions & 14 deletions cabal-install/Distribution/Client/Config.hs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
module Distribution.Client.Config (
SavedConfig(..),
loadConfig,
loadExactConfig,
getConfigFilePath,

showConfig,
Expand Down Expand Up @@ -92,7 +93,7 @@ import Distribution.Simple.Command
import Distribution.Simple.Program
( defaultProgramDb )
import Distribution.Simple.Utils
( die', notice, warn, lowercase, cabalVersion )
( debug, die', notice, warn, lowercase, cabalVersion )
import Distribution.Compiler
( CompilerFlavor(..), defaultCompilerFlavor )
import Distribution.Verbosity
Expand Down Expand Up @@ -613,31 +614,41 @@ extendToEffectiveConfig config = do
loadRawConfig :: Verbosity -> Flag FilePath -> IO SavedConfig
loadRawConfig verbosity configFileFlag = do
(source, configFile) <- getConfigFilePathAndSource configFileFlag
debug verbosity $ "Global config file path source is " ++ sourceMsg source ++ "."
minp <- loadExactConfig verbosity configFile
case minp of
Nothing -> createDefaultConfigFile verbosity configFile
Just conf -> return conf

where
sourceMsg CommandlineOption = "commandline option"
sourceMsg EnvironmentVariable = "env var CABAL_CONFIG"
sourceMsg Default = "default config file"

data ConfigFileSource = CommandlineOption
| EnvironmentVariable
| Default

-- | Like 'loadRawConfig', but loads only exactly the file given.
--
loadExactConfig :: Verbosity -> FilePath -> IO (Maybe SavedConfig)
loadExactConfig verbosity configFile = do
minp <- readConfigFile mempty configFile
case minp of
Nothing -> do
notice verbosity $ "Config file path source is " ++ sourceMsg source ++ "."
notice verbosity $ "Config file " ++ configFile ++ " not found."
createDefaultConfigFile verbosity configFile
debug verbosity $ "Config file " ++ configFile ++ " not found."
return Nothing
Just (ParseOk ws conf) -> do
debug verbosity $ "Config file " ++ configFile ++ " loaded."
unless (null ws) $ warn verbosity $
unlines (map (showPWarning configFile) ws)
return conf
return (Just conf)
Just (ParseFailed err) -> do
let (line, msg) = locatedErrorMsg err
die' verbosity $
"Error parsing config file " ++ configFile
++ maybe "" (\n -> ':' : show n) line ++ ":\n" ++ msg

where
sourceMsg CommandlineOption = "commandline option"
sourceMsg EnvironmentVariable = "env var CABAL_CONFIG"
sourceMsg Default = "default config file"

data ConfigFileSource = CommandlineOption
| EnvironmentVariable
| Default

-- | Returns the config file path, without checking that the file exists.
-- The order of precedence is: input flag, CABAL_CONFIG, default location.
getConfigFilePath :: Flag FilePath -> IO FilePath
Expand Down
30 changes: 21 additions & 9 deletions cabal-install/Distribution/Client/ProjectConfig.hs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ import Distribution.Client.GlobalFlags
import Distribution.Client.BuildReports.Types
( ReportLevel(..) )
import Distribution.Client.Config
( loadConfig, getConfigFilePath )
( getConfigFilePath, loadConfig, loadExactConfig )

import Distribution.Solver.Types.SourcePackage
import Distribution.Solver.Types.Settings
Expand Down Expand Up @@ -413,7 +413,7 @@ renderBadProjectRoot (BadProjectRootExplicitFile projectFile) =
--
readProjectConfig :: Verbosity -> Flag FilePath -> DistDirLayout -> Rebuild ProjectConfig
readProjectConfig verbosity configFileFlag distDirLayout = do
global <- readGlobalConfig verbosity configFileFlag
global <- readGlobalConfig verbosity distDirLayout configFileFlag
local <- readProjectLocalConfig verbosity distDirLayout
freeze <- readProjectLocalFreezeConfig verbosity distDirLayout
extra <- readProjectLocalExtraConfig verbosity distDirLayout
Expand Down Expand Up @@ -542,13 +542,25 @@ writeProjectConfigFile file =
writeFile file . showProjectConfig


-- | Read the user's @~/.cabal/config@ file.
--
readGlobalConfig :: Verbosity -> Flag FilePath -> Rebuild ProjectConfig
readGlobalConfig verbosity configFileFlag = do
config <- liftIO (loadConfig verbosity configFileFlag)
configFile <- liftIO (getConfigFilePath configFileFlag)
monitorFiles [monitorFileHashed configFile]
-- | Read the user's @~/.cabal/config@ file and any @cabal.config.local@ file in the
-- project root directory.
--
readGlobalConfig
:: Verbosity
-> DistDirLayout
-> Flag FilePath
-> Rebuild ProjectConfig
readGlobalConfig verbosity layout configFileFlag = do
userConfig <- liftIO (loadConfig verbosity configFileFlag)
userConfigFile <- liftIO (getConfigFilePath configFileFlag)
let localConfigFile = distProjectRootDirectory layout </> "cabal.config.local"
localConfig <- liftIO (loadExactConfig verbosity localConfigFile)
monitorFiles
[
monitorFileHashed userConfigFile,
monitorFileHashed localConfigFile
]
let config = userConfig <> fromMaybe mempty localConfig
return (convertLegacyGlobalConfig config)

reportParseResult :: Verbosity -> String -> FilePath -> ParseResult a -> IO a
Expand Down
7 changes: 4 additions & 3 deletions cabal-install/Distribution/Client/ProjectConfig/Legacy.hs
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,9 @@ convertLegacyGlobalConfig
savedHaddockFlags = haddockFlags
} =
mempty {
projectConfigShared = configAllPackages,
projectConfigLocalPackages = configLocalPackages,
projectConfigBuildOnly = configBuildOnly
projectConfigShared = configAllPackages,
projectConfigGlobalPackages = configLocalPackages,
projectConfigBuildOnly = configBuildOnly
}
where
--TODO: [code cleanup] eliminate use of default*Flags here and specify the
Expand Down Expand Up @@ -240,6 +240,7 @@ convertLegacyProjectConfig
projectConfigBuildOnly = configBuildOnly,
projectConfigShared = configAllPackages,
projectConfigProvenance = mempty,
projectConfigGlobalPackages = mempty,
projectConfigLocalPackages = configLocalPackages,
projectConfigSpecificPackage = fmap perPackage legacySpecificConfig
}
Expand Down
4 changes: 4 additions & 0 deletions cabal-install/Distribution/Client/ProjectConfig/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
projectConfigGlobalPackages :: PackageConfig,

-- | Configuration to be applied to *local* packages; i.e.,
-- any packages which are explicitly named in `cabal.project`.
projectConfigLocalPackages :: PackageConfig,
Expand Down
23 changes: 14 additions & 9 deletions cabal-install/Distribution/Client/ProjectPlanning.hs
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,7 @@ rebuildInstallPlan verbosity
, ElaboratedSharedConfig )
phaseElaboratePlan ProjectConfig {
projectConfigShared,
projectConfigGlobalPackages,
projectConfigLocalPackages,
projectConfigSpecificPackage,
projectConfigBuildOnly
Expand Down Expand Up @@ -613,6 +614,7 @@ rebuildInstallPlan verbosity
sourcePackageHashes
defaultInstallDirs
projectConfigShared
projectConfigGlobalPackages
projectConfigLocalPackages
(getMapMappend projectConfigSpecificPackage)
let instantiatedPlan = instantiateInstallPlan elaboratedPlan
Expand Down Expand Up @@ -1138,6 +1140,7 @@ elaborateInstallPlan
-> InstallDirs.InstallDirTemplates
-> ProjectConfigShared
-> PackageConfig
-> PackageConfig
-> Map PackageName PackageConfig
-> LogProgress (ElaboratedInstallPlan, ElaboratedSharedConfig)
elaborateInstallPlan verbosity platform compiler compilerprogdb pkgConfigDB
Expand All @@ -1146,7 +1149,8 @@ elaborateInstallPlan verbosity platform compiler compilerprogdb pkgConfigDB
solverPlan localPackages
sourcePackageHashes
defaultInstallDirs
sharedPackageConfig
sharedConfig
globalPackagesConfig
localPackagesConfig
perPackageConfig = do
x <- elaboratedInstallPlan
Expand Down Expand Up @@ -1240,7 +1244,7 @@ elaborateInstallPlan verbosity platform compiler compilerprogdb pkgConfigDB
-- For ease of testing, we let per-component builds be toggled
-- at the top level
cuz_flag
| fromFlagOrDefault True (projectConfigPerComponent sharedPackageConfig)
| fromFlagOrDefault True (projectConfigPerComponent sharedConfig)
= []
| otherwise = cuz "you passed --disable-per-component"

Expand Down Expand Up @@ -1754,14 +1758,15 @@ 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 = mconcat [global, local, perpkg]
where
local = f localPackagesConfig
local
-- 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 = f localPackagesConfig
| otherwise = mempty
global = f globalPackagesConfig
perpkg = maybe mempty f (Map.lookup (packageName pkg) perPackageConfig)

inplacePackageDbs = storePackageDbs
Expand Down
2 changes: 2 additions & 0 deletions cabal-install/changelog
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@
stay within the load command size limits of macOSs mach-o linker.
* Use [lfxtb] letters to differentiate component kind instead of
opaque "c" in dist-dir layout.
* New config file 'cabal.config.local' to specify project-wide
global options for project commands.

2.0.0.1 Mikhail Glushenkov <[email protected]> October 2017
* Support for GHC's numeric -g debug levels (#4673).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -297,7 +298,8 @@ instance Arbitrary ProjectConfig where
, projectConfigShared = x5
, projectConfigProvenance = x6
, projectConfigLocalPackages = x7
, projectConfigSpecificPackage = x8 } =
, projectConfigSpecificPackage = x8
, projectConfigGlobalPackages = x9 } =
[ ProjectConfig { projectPackages = x0'
, projectPackagesOptional = x1'
, projectPackagesRepo = x2'
Expand All @@ -306,11 +308,12 @@ instance Arbitrary ProjectConfig where
, projectConfigShared = x5'
, projectConfigProvenance = x6'
, projectConfigLocalPackages = x7'
, projectConfigSpecificPackage = (MapMappend
(fmap getNonMEmpty x8')) }
| ((x0', x1', x2', x3'), (x4', x5', x6', x7', x8'))
, projectConfigSpecificPackage =
MapMappend (fmap getNonMEmpty x8')
, projectConfigGlobalPackages = 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
Expand Down