Commit 92f018c2 authored by Duncan Coutts's avatar Duncan Coutts Committed by Mikhail Glushenkov

New module for new style project configuration files

This defines the new cabal.project files and introduces the notion of a
project root (and the logic for finding it). Also has support for
implicit projects when no cabal.project file is defined.

Supports both reading and writing project files or fragments. The
printing & parsing round trips correctly. QC tests to follow.

This is a key part of the new nix-local-build branch approach, based
around projects with clear configuration state held in a project file
(or extra files).

This has support for file and dirs as packages within a project,
including by glob. It supports both globs that much match a target, and
optional globs that are allowed to match nothing. It has partial support
for local tarball, remote http tarball and remote source repo packages.

(cherry picked from commit 324b3240)
parent fe3596b9
......@@ -39,7 +39,9 @@ module Distribution.Client.Config (
withProgramOptionsFields,
userConfigDiff,
userConfigUpdate,
createDefaultConfigFile
createDefaultConfigFile,
remoteRepoFields
) where
import Distribution.Client.Types
......
......@@ -261,6 +261,9 @@ data ConstraintSource =
-- | Main config file, which is ~/.cabal/config by default.
ConstraintSourceMainConfig FilePath
-- | Local cabal.project file
| ConstraintSourceProjectConfig FilePath
-- | Sandbox config file, which is ./cabal.sandbox.config by default.
| ConstraintSourceSandboxConfig FilePath
......@@ -298,6 +301,8 @@ instance Binary ConstraintSource
showConstraintSource :: ConstraintSource -> String
showConstraintSource (ConstraintSourceMainConfig path) =
"main config " ++ path
showConstraintSource (ConstraintSourceProjectConfig path) =
"project config " ++ path
showConstraintSource (ConstraintSourceSandboxConfig path) =
"sandbox config " ++ path
showConstraintSource (ConstraintSourceUserConfig path)= "user config " ++ path
......
This diff is collapsed.
This diff is collapsed.
{-# LANGUAGE DeriveGeneric, DeriveDataTypeable #-}
-- | Handling project configuration, types.
--
module Distribution.Client.ProjectConfig.Types (
-- * Types for project config
ProjectConfig(..),
ProjectConfigBuildOnly(..),
ProjectConfigShared(..),
PackageConfig(..),
-- * Resolving configuration
SolverSettings(..),
BuildTimeSettings(..),
) where
import Distribution.Client.Types
( RemoteRepo )
import Distribution.Client.Dependency.Types
( PreSolver, ConstraintSource )
import Distribution.Client.Targets
( UserConstraint )
import Distribution.Client.BuildReports.Types
( ReportLevel(..) )
import Distribution.Package
( PackageName, PackageId, UnitId, Dependency )
import Distribution.Version
( Version )
import Distribution.System
( Platform )
import Distribution.PackageDescription
( FlagAssignment, SourceRepo(..) )
import Distribution.Simple.Compiler
( Compiler, CompilerFlavor
, OptimisationLevel(..), ProfDetailLevel, DebugInfoLevel(..) )
import Distribution.Simple.Setup
( Flag, AllowNewer(..) )
import Distribution.Simple.InstallDirs
( PathTemplate )
import Distribution.Utils.NubList
( NubList )
import Distribution.Verbosity
( Verbosity )
import Data.Map (Map)
import Distribution.Compat.Binary (Binary)
import Distribution.Compat.Semigroup
import GHC.Generics (Generic)
-------------------------------
-- Project config types
--
-- | This type corresponds directly to what can be written in the
-- @cabal.project@ file. Other sources of configuration can also be injected
-- into this type, such as the user-wide @~/.cabal/config@ file and the
-- command line of @cabal configure@ or @cabal build@.
--
-- Since it corresponds to the external project file it is an instance of
-- 'Monoid' and all the fields can be empty. This also means there has to
-- be a step where we resolve configuration. At a minimum resolving means
-- applying defaults but it can also mean merging information from multiple
-- sources. For example for package-specific configuration the project file
-- can specify configuration that applies to all local packages, and then
-- additional configuration for a specific package.
--
-- Future directions: multiple profiles, conditionals. If we add these
-- features then the gap between configuration as written in the config file
-- and resolved settings we actually use will become even bigger.
--
data ProjectConfig
= ProjectConfig {
-- | Packages in this project, including local dirs, local .cabal files
-- local and remote tarballs. Where these are file globs, they must
-- match something.
projectPackages :: [String],
-- | Like 'projectConfigPackageGlobs' but /optional/ in the sense that
-- file globs are allowed to match nothing. The primary use case for
-- this is to be able to say @optional-packages: */@ to automagically
-- pick up deps that we unpack locally.
projectPackagesOptional :: [String],
-- | Packages in this project from remote source repositories.
projectPackagesRepo :: [SourceRepo],
-- | Packages in this project from hackage repositories.
projectPackagesNamed :: [Dependency],
projectConfigBuildOnly :: ProjectConfigBuildOnly,
projectConfigShared :: ProjectConfigShared,
projectConfigLocalPackages :: PackageConfig,
projectConfigSpecificPackage :: Map PackageName PackageConfig
}
deriving (Eq, Show, Generic)
-- | That part of the project configuration that only affects /how/ we build
-- and not the /value/ of the things we build. This means this information
-- does not need to be tracked for changes since it does not affect the
-- outcome.
--
data ProjectConfigBuildOnly
= ProjectConfigBuildOnly {
projectConfigVerbosity :: Flag Verbosity,
projectConfigDryRun :: Flag Bool,
projectConfigOnlyDeps :: Flag Bool,
projectConfigSummaryFile :: NubList PathTemplate,
projectConfigLogFile :: Flag PathTemplate,
projectConfigBuildReports :: Flag ReportLevel,
projectConfigReportPlanningFailure :: Flag Bool,
projectConfigSymlinkBinDir :: Flag FilePath,
projectConfigOneShot :: Flag Bool,
projectConfigNumJobs :: Flag (Maybe Int),
projectConfigOfflineMode :: Flag Bool,
projectConfigKeepTempFiles :: Flag Bool,
projectConfigHttpTransport :: Flag String,
projectConfigIgnoreExpiry :: Flag Bool,
projectConfigCacheDir :: Flag FilePath,
projectConfigLogsDir :: Flag FilePath,
projectConfigWorldFile :: Flag FilePath,
projectConfigRootCmd :: Flag String
}
deriving (Eq, Show, Generic)
-- | Project configuration that is shared between all packages in the project.
-- In particular this includes configuration that affects the solver.
--
data ProjectConfigShared
= ProjectConfigShared {
projectConfigProgramPaths :: Map String FilePath,
projectConfigProgramArgs :: Map String [String],
projectConfigProgramPathExtra :: NubList FilePath,
projectConfigHcFlavor :: Flag CompilerFlavor,
projectConfigHcPath :: Flag FilePath,
projectConfigHcPkg :: Flag FilePath,
projectConfigHaddockIndex :: Flag PathTemplate,
-- Things that only make sense for manual mode, not --local mode
-- too much control!
--projectConfigUserInstall :: Flag Bool,
--projectConfigInstallDirs :: InstallDirs (Flag PathTemplate),
--TODO: [required eventually] decide what to do with InstallDirs
-- currently we don't allow it to be specified in the config file
--projectConfigPackageDBs :: [Maybe PackageDB],
-- configuration used both by the solver and other phases
projectConfigRemoteRepos :: NubList RemoteRepo, -- ^ Available Hackage servers.
projectConfigLocalRepos :: NubList FilePath,
-- solver configuration
projectConfigConstraints :: [(UserConstraint, ConstraintSource)],
projectConfigPreferences :: [Dependency],
projectConfigFlagAssignment :: FlagAssignment, --TODO: [required eventually] must be per-package, not global
projectConfigCabalVersion :: Flag Version, --TODO: [required eventually] unused
projectConfigSolver :: Flag PreSolver,
projectConfigAllowNewer :: Maybe AllowNewer,
projectConfigMaxBackjumps :: Flag Int,
projectConfigReorderGoals :: Flag Bool,
projectConfigStrongFlags :: Flag Bool
-- More things that only make sense for manual mode, not --local mode
-- too much control!
--projectConfigIndependentGoals :: Flag Bool,
--projectConfigShadowPkgs :: Flag Bool,
--projectConfigReinstall :: Flag Bool,
--projectConfigAvoidReinstalls :: Flag Bool,
--projectConfigOverrideReinstall :: Flag Bool,
--projectConfigUpgradeDeps :: Flag Bool
}
deriving (Eq, Show, Generic)
-- | Project configuration that is specific to each package, that is where we
-- can in principle have different values for different packages in the same
-- project.
--
data PackageConfig
= PackageConfig {
packageConfigVanillaLib :: Flag Bool,
packageConfigSharedLib :: Flag Bool,
packageConfigDynExe :: Flag Bool,
packageConfigProf :: Flag Bool, --TODO: [code cleanup] sort out
packageConfigProfLib :: Flag Bool, -- this duplication
packageConfigProfExe :: Flag Bool, -- and consistency
packageConfigProfDetail :: Flag ProfDetailLevel,
packageConfigProfLibDetail :: Flag ProfDetailLevel,
packageConfigConfigureArgs :: [String],
packageConfigOptimization :: Flag OptimisationLevel,
packageConfigProgPrefix :: Flag PathTemplate,
packageConfigProgSuffix :: Flag PathTemplate,
packageConfigExtraLibDirs :: [FilePath],
packageConfigExtraFrameworkDirs :: [FilePath],
packageConfigExtraIncludeDirs :: [FilePath],
packageConfigGHCiLib :: Flag Bool,
packageConfigSplitObjs :: Flag Bool,
packageConfigStripExes :: Flag Bool,
packageConfigStripLibs :: Flag Bool,
packageConfigTests :: Flag Bool,
packageConfigBenchmarks :: Flag Bool,
packageConfigCoverage :: Flag Bool,
packageConfigRelocatable :: Flag Bool,
packageConfigDebugInfo :: Flag DebugInfoLevel,
packageConfigRunTests :: Flag Bool, --TODO: [required eventually] use this
packageConfigDocumentation :: Flag Bool, --TODO: [required eventually] use this
packageConfigHaddockHoogle :: Flag Bool, --TODO: [required eventually] use this
packageConfigHaddockHtml :: Flag Bool, --TODO: [required eventually] use this
packageConfigHaddockHtmlLocation :: Flag String, --TODO: [required eventually] use this
packageConfigHaddockExecutables :: Flag Bool, --TODO: [required eventually] use this
packageConfigHaddockTestSuites :: Flag Bool, --TODO: [required eventually] use this
packageConfigHaddockBenchmarks :: Flag Bool, --TODO: [required eventually] use this
packageConfigHaddockInternal :: Flag Bool, --TODO: [required eventually] use this
packageConfigHaddockCss :: Flag FilePath, --TODO: [required eventually] use this
packageConfigHaddockHscolour :: Flag Bool, --TODO: [required eventually] use this
packageConfigHaddockHscolourCss :: Flag FilePath, --TODO: [required eventually] use this
packageConfigHaddockContents :: Flag PathTemplate --TODO: [required eventually] use this
}
deriving (Eq, Show, Generic)
instance Binary ProjectConfig
instance Binary ProjectConfigBuildOnly
instance Binary ProjectConfigShared
instance Binary PackageConfig
instance Monoid ProjectConfig where
mempty = gmempty
mappend = (<>)
instance Semigroup ProjectConfig where
(<>) = gmappend
instance Monoid ProjectConfigBuildOnly where
mempty = gmempty
mappend = (<>)
instance Semigroup ProjectConfigBuildOnly where
(<>) = gmappend
instance Monoid ProjectConfigShared where
mempty = gmempty
mappend = (<>)
instance Semigroup ProjectConfigShared where
(<>) = gmappend
instance Monoid PackageConfig where
mempty = gmempty
mappend = (<>)
instance Semigroup PackageConfig where
(<>) = gmappend
----------------------------------------
-- Resolving configuration to settings
--
-- | Resolved configuration for the solver. The idea is that this is easier to
-- use than the raw configuration because in the raw configuration everything
-- is optional (monoidial). In the 'BuildTimeSettings' every field is filled
-- in, if only with the defaults.
--
-- Use 'resolveSolverSettings' to make one from the project config (by
-- applying defaults etc).
--
data SolverSettings
= SolverSettings {
solverSettingRemoteRepos :: [RemoteRepo], -- ^ Available Hackage servers.
solverSettingLocalRepos :: [FilePath],
solverSettingConstraints :: [(UserConstraint, ConstraintSource)],
solverSettingPreferences :: [Dependency],
solverSettingFlagAssignment :: FlagAssignment, --TODO: [required eventually] must be per-package, not global
solverSettingCabalVersion :: Maybe Version, --TODO: [required eventually] unused
solverSettingSolver :: PreSolver,
solverSettingAllowNewer :: AllowNewer,
solverSettingMaxBackjumps :: Maybe Int,
solverSettingReorderGoals :: Bool,
solverSettingStrongFlags :: Bool
-- Things that only make sense for manual mode, not --local mode
-- too much control!
--solverSettingIndependentGoals :: Bool,
--solverSettingShadowPkgs :: Bool,
--solverSettingReinstall :: Bool,
--solverSettingAvoidReinstalls :: Bool,
--solverSettingOverrideReinstall :: Bool,
--solverSettingUpgradeDeps :: Bool
}
deriving (Eq, Show, Generic)
instance Binary SolverSettings
-- | Resolved configuration for things that affect how we build and not the
-- value of the things we build. The idea is that this is easier to use than
-- the raw configuration because in the raw configuration everything is
-- optional (monoidial). In the 'BuildTimeSettings' every field is filled in,
-- if only with the defaults.
--
-- Use 'resolveBuildTimeSettings' to make one from the project config (by
-- applying defaults etc).
--
data BuildTimeSettings
= BuildTimeSettings {
buildSettingDryRun :: Bool,
buildSettingOnlyDeps :: Bool,
buildSettingSummaryFile :: [PathTemplate],
buildSettingLogFile :: Maybe (Compiler -> Platform
-> PackageId -> UnitId
-> FilePath),
buildSettingLogVerbosity :: Verbosity,
buildSettingBuildReports :: ReportLevel,
buildSettingReportPlanningFailure :: Bool,
buildSettingSymlinkBinDir :: [FilePath],
buildSettingOneShot :: Bool,
buildSettingNumJobs :: Int,
buildSettingOfflineMode :: Bool,
buildSettingKeepTempFiles :: Bool,
buildSettingRemoteRepos :: [RemoteRepo],
buildSettingLocalRepos :: [FilePath],
buildSettingCacheDir :: FilePath,
buildSettingHttpTransport :: Maybe String,
buildSettingIgnoreExpiry :: Bool,
buildSettingRootCmd :: Maybe String
}
......@@ -23,6 +23,7 @@ module Distribution.Client.Setup
, buildCommand, BuildFlags(..), BuildExFlags(..), SkipAddSourceDepsCheck(..)
, replCommand, testCommand, benchmarkCommand
, installCommand, InstallFlags(..), installOptions, defaultInstallFlags
, defaultSolver, defaultMaxBackjumps
, listCommand, ListFlags(..)
, updateCommand
, upgradeCommand
......
......@@ -69,7 +69,7 @@ import qualified Distribution.Client.List as List
--TODO: temporary import, just to force these modules to be built.
-- It will be replaced by import of new build command once merged.
import Distribution.Client.RebuildMonad ()
import Distribution.Client.DistDirLayout ()
import Distribution.Client.ProjectConfig ()
import Distribution.Client.Install (install)
import Distribution.Client.Configure (configure)
......
......@@ -181,6 +181,9 @@ executable cabal
Distribution.Client.ParseUtils
Distribution.Client.PkgConfigDb
Distribution.Client.PlanIndex
Distribution.Client.ProjectConfig
Distribution.Client.ProjectConfig.Types
Distribution.Client.ProjectConfig.Legacy
Distribution.Client.Run
Distribution.Client.RebuildMonad
Distribution.Client.Sandbox
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment