Skip to content

Commit

Permalink
Complete the build-depends internal reform in Cabal
Browse files Browse the repository at this point in the history
  • Loading branch information
Ericson2314 committed Jan 26, 2017
1 parent b9896bb commit 67f932e
Show file tree
Hide file tree
Showing 9 changed files with 123 additions and 103 deletions.
1 change: 0 additions & 1 deletion Cabal/Distribution/Backpack/ComponentsGraph.hs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import Distribution.Simple.BuildToolDepends
import Distribution.Simple.LocalBuildInfo
import Distribution.Types.ComponentRequestedSpec
import Distribution.Types.Dependency
import Distribution.Types.UnqualComponentName
import Distribution.Compat.Graph (Node(..))
import qualified Distribution.Compat.Graph as Graph
import Distribution.Types.Mixin
Expand Down
1 change: 0 additions & 1 deletion Cabal/Distribution/Backpack/ConfiguredComponent.hs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import Distribution.Backpack.Id

import Distribution.Types.IncludeRenaming
import Distribution.Types.Mixin
import Distribution.Types.UnqualComponentName
import Distribution.Types.ComponentInclude
import Distribution.Package
import Distribution.PackageDescription as PD hiding (Flag)
Expand Down
13 changes: 5 additions & 8 deletions Cabal/Distribution/Backpack/PreExistingComponent.hs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import Prelude ()

import Distribution.Backpack.ModuleShape
import Distribution.Backpack
import Distribution.Types.ComponentName

import qualified Data.Map as Map
import Distribution.Package
Expand All @@ -18,12 +19,8 @@ import Distribution.InstalledPackageInfo (InstalledPackageInfo)
-- we don't need to know how to build.
data PreExistingComponent
= PreExistingComponent {
-- | The 'PackageName' that, when we see it in 'PackageDescription',
-- we should map this to. This may DISAGREE with 'pc_pkgid' for
-- internal dependencies: e.g., an internal component @lib@
-- may be munged to @z-pkg-z-lib@, but we still want to use
-- it when we see @lib@ in @build-depends@
pc_pkgname :: PackageName,
pc_compname :: ComponentName,
pc_pkgid :: PackageId,
pc_uid :: UnitId,
pc_cid :: ComponentId,
Expand All @@ -34,10 +31,11 @@ data PreExistingComponent
-- | Convert an 'InstalledPackageInfo' into a 'PreExistingComponent',
-- which was brought into scope under the 'PackageName' (important for
-- a package qualified reference.)
ipiToPreExistingComponent :: (PackageName, InstalledPackageInfo) -> PreExistingComponent
ipiToPreExistingComponent (pn, ipi) =
ipiToPreExistingComponent :: (PackageName, ComponentName, InstalledPackageInfo) -> PreExistingComponent
ipiToPreExistingComponent (pn, cn, ipi) =
PreExistingComponent {
pc_pkgname = pn,
pc_compname = cn,
pc_pkgid = Installed.sourcePackageId ipi,
pc_uid = Installed.installedUnitId ipi,
pc_cid = Installed.installedComponentId ipi,
Expand All @@ -46,4 +44,3 @@ ipiToPreExistingComponent (pn, ipi) =
(Map.fromList (Installed.instantiatedWith ipi)),
pc_shape = shapeInstalledPackage ipi
}

7 changes: 4 additions & 3 deletions Cabal/Distribution/PackageDescription/Parse.hs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import Distribution.Types.ForeignLib
import Distribution.Types.ForeignLibType
import Distribution.Types.UnqualComponentName
import Distribution.Types.LibDependency
import Distribution.Types.CondTree
import Distribution.ParseUtils hiding (parseFields)
import Distribution.PackageDescription
import Distribution.PackageDescription.Utils
Expand Down Expand Up @@ -425,8 +426,8 @@ binfoFieldDescrs =
, commaListFieldWithSep vcat "build-depends"
disp parse
buildDependencies
(\xs binfo -> binfo{targetBuildDepends=map buildDependencyToDependency xs,
implicitMixins=map buildDependencyToMixin xs})
(\xs binfo -> binfo{targetBuildDepends=map libDependencyToDependency xs,
implicitMixins=map libDependencyToMixin xs})
, commaListFieldWithSep vcat "mixins"
disp parse
mixins (\xs binfo -> binfo{mixins=xs})
Expand Down Expand Up @@ -1106,7 +1107,7 @@ parsePackageDescription file = do
-- to check the CondTree, rather than grovel everywhere
-- inside the conditional bits).
deps <- liftM concat
. traverse (lift . fmap (map buildDependencyToDependency) . parseConstraint)
. traverse (lift . fmap (map libDependencyToDependency) . parseConstraint)
. filter isConstraint
$ simplFlds

Expand Down
4 changes: 2 additions & 2 deletions Cabal/Distribution/PackageDescription/Parsec/FieldDescr.hs
Original file line number Diff line number Diff line change
Expand Up @@ -431,8 +431,8 @@ binfoFieldDescrs =
, commaListFieldWithSep vcat "build-depends"
disp parsec
buildDependencies
(\xs binfo -> binfo{targetBuildDepends=map buildDependencyToDependency xs,
implicitMixins=map buildDependencyToMixin xs})
(\xs binfo -> binfo{targetBuildDepends=map libDependencyToDependency xs,
implicitMixins=map libDependencyToMixin xs})
, commaListFieldWithSep vcat "mixins"
disp parsec
mixins (\xs binfo -> binfo{mixins=xs})
Expand Down
73 changes: 44 additions & 29 deletions Cabal/Distribution/Simple/Configure.hs
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,10 @@ import Distribution.InstalledPackageInfo (InstalledPackageInfo)
import qualified Distribution.Simple.PackageIndex as PackageIndex
import Distribution.Simple.PackageIndex (InstalledPackageIndex)
import Distribution.PackageDescription as PD hiding (Flag)
import Distribution.Types.BuildInfo (buildDependencies)
import Distribution.Types.PackageDescription as PD
import Distribution.Types.DependencyMap
import Distribution.Types.LibDependency
import Distribution.PackageDescription.PrettyPrint
import Distribution.PackageDescription.Configuration
import Distribution.PackageDescription.Check hiding (doesFileExist)
Expand Down Expand Up @@ -132,8 +134,8 @@ import System.IO
( hPutStrLn, hClose )
import Distribution.Text
( Text(disp), defaultStyle, display, simpleParse )
import Text.PrettyPrint
( Doc, (<+>), ($+$), char, comma, hsep, nest
import Text.PrettyPrint as PP
( Doc, (<+>), ($+$), char, comma, empty, hsep, nest
, punctuate, quotes, render, renderStyle, sep, text )
import Distribution.Compat.Environment ( lookupEnv )
import Distribution.Compat.Exception ( catchExit, catchIO )
Expand Down Expand Up @@ -841,7 +843,7 @@ dependencySatisfiable
dependencySatisfiable
use_external_internal_deps
exact_config pn installedPackageSet allConstraintsMap
d@(Dependency depName vr)
d@(Dependency depName _)

-- When we are doing per-component configure, the behavior is very
-- uniform: if an exact configuration is requested, check for the
Expand Down Expand Up @@ -991,7 +993,7 @@ configureDependencies
-> IO [(PackageName, ComponentName, InstalledPackageInfo)]
configureDependencies verbosity use_external_internal_deps
installedPackageSet requiredDepsMap pkg_descr = do
let selectDependencies :: [Dependency] ->
let selectDependencies :: [LibDependency] ->
([FailedDependency], [ResolvedDependency])
selectDependencies =
partitionEithers
Expand All @@ -1000,15 +1002,20 @@ configureDependencies verbosity use_external_internal_deps
requiredDepsMap use_external_internal_deps)

(failedDeps, allPkgDeps) =
selectDependencies (buildDepends pkg_descr)
selectDependencies (buildDependencies =<< allBuildInfo pkg_descr)

internalPkgDeps = [ pkgid
| InternalDependency _ pkgid <- allPkgDeps ]
internalPkgDeps =
[ pkgid | InternalDependency _ pkgid <- allPkgDeps ]
-- NB: we have to SAVE the package name, because this is the only
-- way we can be able to resolve package names in the package
-- description.
externalPkgDeps = [ (pn, pkg)
| ExternalDependency (Dependency pn _) pkg <- allPkgDeps ]
externalPkgDeps =
[ (pn, cn, pkgid)
| ExternalDependency (LibDependency pn mcn _) pkgid <- allPkgDeps
, let cn = case mcn of
Nothing -> CLibName
Just n -> CSubLibName n
]

when (not (null internalPkgDeps)
&& not (newPackageDepsBehaviour pkg_descr)) $
Expand Down Expand Up @@ -1144,12 +1151,12 @@ data ResolvedDependency
-- | An external dependency from the package database, OR an
-- internal dependency which we are getting from the package
-- database.
= ExternalDependency Dependency InstalledPackageInfo
= ExternalDependency LibDependency InstalledPackageInfo
-- | An internal dependency ('PackageId' should be a library name)
-- which we are going to have to build. (The
-- 'PackageId' here is a hack to get a modest amount of
-- polymorphism out of the 'Package' typeclass.)
| InternalDependency Dependency PackageId
| InternalDependency LibDependency PackageId

data FailedDependency = DependencyNotExists PackageName
| DependencyMissingInternal PackageName PackageName
Expand All @@ -1163,11 +1170,11 @@ selectDependency :: PackageId -- ^ Package id of current package
-- use
-> UseExternalInternalDeps -- ^ Are we configuring a
-- single component?
-> Dependency
-> LibDependency
-> Either FailedDependency ResolvedDependency
selectDependency pkgid installedIndex requiredDepsMap
use_external_internal_deps
dep@(Dependency dep_pkgname vr) =
dep@(LibDependency dep_pkgname dep_mb_compname vr) =
-- If the dependency specification matches anything in the internal package
-- index, then we prefer that match to anything in the second.
-- For example:
Expand All @@ -1181,35 +1188,43 @@ selectDependency pkgid installedIndex requiredDepsMap
--
-- We want "build-depends: MyLibrary" always to match the internal library
-- even if there is a newer installed library "MyLibrary-0.2".
do_external Nothing
case dep_mb_compname of
Just intLibName ->
if use_external_internal_deps
then do_external $ Just intLibName
else do_internal
_ -> do_external Nothing
where
do_internal = Right (InternalDependency dep
(PackageIdentifier dep_pkgname (packageVersion pkgid)))
do_external is_internal = case Map.lookup dep_pkgname requiredDepsMap of
do_external mb_intLibName = case Map.lookup (dep_pkgname, compName) requiredDepsMap of
-- If we know the exact pkg to use, then use it.
Just pkginstance -> Right (ExternalDependency dep pkginstance)
-- Otherwise we just pick an arbitrary instance of the latest version.
Nothing -> case PackageIndex.lookupDependency installedIndex dep' of
[] -> Left $
case is_internal of
Just cname -> DependencyMissingInternal dep_pkgname
(computeCompatPackageName (packageName pkgid) cname)
Nothing -> DependencyNotExists dep_pkgname
pkgs -> Right $ ExternalDependency dep $
case last pkgs of
Nothing -> case PackageIndex.lookupDependency installedIndex legacyDep of
[] -> Left errVal
pkgs -> Right $ ExternalDependency dep $ case last pkgs of
(_ver, pkginstances) -> head pkginstances
where
dep' | Just cname <- is_internal
= Dependency (computeCompatPackageName (packageName pkgid) cname) vr
| otherwise = dep
(legacyDep, compName, errVal) = case mb_intLibName of
Nothing -> ( Dependency dep_pkgname vr
, CLibName
, DependencyNotExists dep_pkgname
)
Just intLibName -> ( Dependency extIntPkgName vr
, cname
, DependencyMissingInternal dep_pkgname extIntPkgName
)
where extIntPkgName = computeCompatPackageName (packageName pkgid) cname
cname = CSubLibName intLibName
-- NB: here computeCompatPackageName we want to pick up the INDEFINITE ones
-- which is why we pass 'Nothing' as 'UnitId'

reportSelectedDependencies :: Verbosity
-> [ResolvedDependency] -> IO ()
reportSelectedDependencies verbosity deps =
info verbosity $ unlines
[ "Dependency " ++ display (simplifyDependency dep)
[ "Dependency " ++ display (simplifyLibDependency dep)
++ ": using " ++ display pkgid
| resolved <- deps
, let (dep, pkgid) = case resolved of
Expand Down Expand Up @@ -1379,8 +1394,8 @@ combinedConstraints constraints dependencies installedPackages = do
| (pkgname, mb_cname, cid, Nothing) <- dependenciesPkgInfo ]

dispDependencies deps =
hsep [ text "--dependency="
<<>> quotes (disp pkgname <<>> (maybe empty disp mb_cname) <<>> char '=' <<>> disp cid)
hsep [text "--dependency="
<<>> quotes (disp pkgname <<>> (maybe PP.empty disp mb_cname) <<>> char '=' <<>> disp cid)
| (pkgname, mb_cname, cid) <- deps ]

-- -----------------------------------------------------------------------------
Expand Down
11 changes: 6 additions & 5 deletions Cabal/Distribution/Types/ExeDependency.hs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,12 @@ import Text.PrettyPrint ((<+>), text)

-- | Describes a dependency on an executable from a package
--
data ExeDependency = ExeDependency
PackageName
UnqualComponentName -- name of executable component of package
VersionRange
deriving (Generic, Read, Show, Eq, Typeable, Data)
data ExeDependency = ExeDependency {
exeDepPackageName :: PackageName,
exeDepExecutableName :: UnqualComponentName,
libDepVersionRange :: VersionRange
}
deriving (Generic, Read, Show, Eq, Typeable, Data)

instance Binary ExeDependency
instance NFData ExeDependency where rnf = genericRnf
Expand Down
54 changes: 0 additions & 54 deletions Cabal/Distribution/Types/LibDependency.exe

This file was deleted.

62 changes: 62 additions & 0 deletions Cabal/Distribution/Types/LibDependency.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DeriveDataTypeable #-}
module Distribution.Types.LibDependency (
LibDependency(..),
libDependencyToDependency,
libDependencyToMixin,
simplifyLibDependency,
) where

import Prelude ()
import Distribution.Compat.Prelude

import Distribution.Package
import Distribution.Types.UnqualComponentName
import Distribution.Types.Mixin
import Distribution.Types.Dependency
import Distribution.Types.IncludeRenaming
import Distribution.Version

import Distribution.Compat.ReadP
import Distribution.Text
import Text.PrettyPrint as PP ((<+>), text, empty)

-- | Like 'Dependency', but this corresponds exactly to the syntax we support in
-- a Cabal file.
data LibDependency = LibDependency {
libDepPackageName :: PackageName,
libDepLibraryName :: Maybe UnqualComponentName,
libDepVersionRange :: VersionRange
}
deriving (Generic, Read, Show, Eq, Typeable, Data)

instance Binary LibDependency
instance NFData LibDependency where rnf = genericRnf

instance Text LibDependency where
disp (LibDependency name mCname ver) =
(disp name <<>> dispMaybeCname) <+> disp ver
where
dispMaybeCname = case mCname of
Nothing -> PP.empty
Just cname -> text ":" <<>> disp cname

parse = do name <- parse
mb_cname <- option Nothing $ do
_ <- char ':'
fmap Just parse
skipSpaces
ver <- parse <++ return anyVersion
return (LibDependency name mb_cname ver)

libDependencyToDependency :: LibDependency -> Dependency
libDependencyToDependency (LibDependency pn _ vr) = Dependency pn vr

libDependencyToMixin :: LibDependency -> Mixin
libDependencyToMixin (LibDependency pn cn _) = Mixin pn cn defaultIncludeRenaming
-- | Simplify the 'VersionRange' expression in a 'Dependency'.
-- See 'simplifyVersionRange'.
--
simplifyLibDependency :: LibDependency -> LibDependency
simplifyLibDependency (LibDependency name mb_cname range) =
LibDependency name mb_cname (simplifyVersionRange range)

0 comments on commit 67f932e

Please sign in to comment.