Skip to content

[WIP] Add glob deps #4241

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

Closed
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
2 changes: 1 addition & 1 deletion Cabal/Distribution/PackageDescription/Check.hs
Original file line number Diff line number Diff line change
Expand Up @@ -635,7 +635,7 @@ checkFields pkg =

depMissingInternalExecutable =
[ dep
| dep@(ExeDependency _ eName _) <- internalExeDeps
| dep@(ExeDependency _ (Just eName) _) <- internalExeDeps
, not $ eName `elem` internalExecutables
]

Expand Down
2 changes: 1 addition & 1 deletion Cabal/Distribution/Parsec/Class.hs
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ instance Parsec ExeDependency where
parsec = do
name <- lexemeParsec
_ <- P.char ':'
exe <- lexemeParsec
exe <- (Just <$> lexemeParsec) <|> (P.char '*' >> pure Nothing)
ver <- parsec <|> pure anyVersion
return (ExeDependency name exe ver)

Expand Down
17 changes: 12 additions & 5 deletions Cabal/Distribution/Simple/BuildToolDepends.hs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ desugarBuildTool :: PackageDescription
-> Maybe ExeDependency
desugarBuildTool pkg led =
if foundLocal
then Just $ ExeDependency (packageName pkg) toolName reqVer
then Just $ ExeDependency (packageName pkg) (Just toolName) reqVer
else Map.lookup name whiteMap
where
LegacyExeDependency name reqVer = led
Expand All @@ -44,7 +44,7 @@ desugarBuildTool pkg led =
, "cpphs", "greencard", "hspec-discover"
]
whiteMap = Map.fromList $ flip map whitelist $ \n ->
(n, ExeDependency (mkPackageName n) (mkUnqualComponentName n) reqVer)
(n, ExeDependency (mkPackageName n) (Just $ mkUnqualComponentName n) reqVer)

-- | Get everything from "build-tool-depends", along with entries from
-- "build-tools" that we know how to desugar.
Expand Down Expand Up @@ -84,13 +84,20 @@ isInternal pkg (ExeDependency n _ _) = n == packageName pkg

-- | Get internal "build-tool-depends", along with internal "build-tools"
--
-- This is a tiny function, but used in a number of places. The same
-- restrictions that apply to `isInternal` also apply to this function.
-- Besides filtering to just internal deps, this also desugars wildcard deps
-- since we know the same version/configuration of the package will be used to
-- install them, and thus we know the precise set of executables that wildcard
-- expands to.
--
-- The same restrictions that apply to `isInternal` also apply to this function.
getAllInternalToolDependencies :: PackageDescription
-> BuildInfo
-> [UnqualComponentName]
getAllInternalToolDependencies pkg bi =
[ toolname
| dep@(ExeDependency _ toolname _) <- getAllToolDependencies pkg bi
| dep@(ExeDependency _ optToolname _) <- getAllToolDependencies pkg bi
, isInternal pkg dep
, toolname <- case optToolname of
Just tn -> pure tn
Nothing -> exeName <$> executables pkg
]
5 changes: 4 additions & 1 deletion Cabal/Distribution/Simple/Configure.hs
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,9 @@ configure (pkg_descr0', pbi) cfg = do
++ intercalate "," unsupportedFLibs

-- Configure certain external build tools, see below for which ones.
--
-- TODO: HACK we're currently ignoring wildcard deps as we don't know
-- precisely which executables the resolved package will contain.
let requiredBuildTools = do
bi <- enabledBuildInfos pkg_descr enabled
-- First, we collect any tool dep that we know is external. This is,
Expand All @@ -581,7 +584,7 @@ configure (pkg_descr0', pbi) cfg = do
-- 2. `build-tool-depends` that aren't from the current package.
let externBuildToolDeps =
[ LegacyExeDependency (unUnqualComponentName eName) versionRange
| buildTool@(ExeDependency _ eName versionRange)
| buildTool@(ExeDependency _ (Just eName) versionRange)
<- getAllToolDependencies pkg_descr bi
, not $ isInternal pkg_descr buildTool ]
-- Second, we collect any build-tools entry we don't know how to
Expand Down
15 changes: 10 additions & 5 deletions Cabal/Distribution/Types/ExeDependency.hs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ import Text.PrettyPrint ((<+>), text)
--
data ExeDependency = ExeDependency
PackageName
UnqualComponentName -- name of executable component of package
-- Name of specific executable component of package, or
-- nothing for a wilcard dependency on them all
(Maybe UnqualComponentName)
VersionRange
deriving (Generic, Read, Show, Eq, Typeable, Data)

Expand All @@ -32,15 +34,18 @@ instance NFData ExeDependency where rnf = genericRnf

instance Text ExeDependency where
disp (ExeDependency name exe ver) =
(disp name <<>> text ":" <<>> disp exe) <+> disp ver
(disp name <<>> text ":" <<>> exe') <+> disp ver
where exe' = case exe of
Just e -> disp e
Nothing -> text "*"

parse = do name <- parse
_ <- Parse.char ':'
exe <- parse
exe <- (Just <$> parse) <++ (Parse.char '*' >> pure Nothing)
Parse.skipSpaces
ver <- parse <++ return anyVersion
Parse.skipSpaces
return (ExeDependency name exe ver)

qualifiedExeName :: ExeDependency -> ComponentName
qualifiedExeName (ExeDependency _ ucn _) = CExeName ucn
qualifiedExeName :: ExeDependency -> Maybe ComponentName
qualifiedExeName (ExeDependency _ ucn _) = CExeName <$> ucn
41 changes: 36 additions & 5 deletions cabal-install/Distribution/Client/ProjectPlanning.hs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ module Distribution.Client.ProjectPlanning (
import Prelude ()
import Distribution.Client.Compat.Prelude

import Distribution.Client.ProjectPlanning.Types
import Distribution.Client.ProjectPlanning.Types as Ty
import Distribution.Client.PackageHash
import Distribution.Client.RebuildMonad
import Distribution.Client.ProjectConfig
Expand Down Expand Up @@ -95,12 +95,14 @@ import Distribution.ModuleName
import Distribution.Package hiding
(InstalledPackageId, installedPackageId)
import Distribution.Types.Dependency
import Distribution.Types.ExeDependency
import Distribution.Types.PkgconfigDependency
import Distribution.Types.UnqualComponentName
import Distribution.System
import qualified Distribution.PackageDescription as Cabal
import qualified Distribution.PackageDescription as PD
import qualified Distribution.PackageDescription.Configuration as PD
import Distribution.Simple.BuildToolDepends
import Distribution.Simple.PackageIndex (InstalledPackageIndex)
import Distribution.Simple.Compiler hiding (Flag)
import qualified Distribution.Simple.GHC as GHC --TODO: [code cleanup] eliminate
Expand Down Expand Up @@ -1011,7 +1013,7 @@ planPackages comp platform solver SolverSettings{..}
-- former we just apply all these flags to all local targets which
-- is silly. We should check if the flags are appropriate.
[ LabeledPackageConstraint
(PackageConstraint (scopeToplevel pkgname)
(PackageConstraint (scopeToplevel pkgname)
(PackagePropertyFlags flags))
ConstraintSourceConfigFlagOrTarget
| let flags = solverSettingFlagAssignment
Expand Down Expand Up @@ -1270,12 +1272,42 @@ elaborateInstallPlan verbosity platform compiler compilerprogdb pkgConfigDB
compLibDependencies =
-- concatMap (elaborateLibSolverId mapDep) external_lib_dep_sids
ordNub (map (\ci -> ConfiguredId (ci_pkgid ci) (ci_id ci)) (cc_includes cc))

filterExeMapDep :: SolverId -> [ElaboratedPlanPackage]
filterExeMapDep = filter go . mapDep
where
toolDeps = getAllToolDependencies pd $ Cabal.componentBuildInfo comp
exeKV :: [(PackageName, Maybe (Set UnqualComponentName))]
exeKV = map go' toolDeps where
go' (ExeDependency p n _) = (p, Set.singleton <$> n)

-- Nothing means wildcard, the complete subset
exeMap :: Map PackageName (Maybe (Set UnqualComponentName))
exeMap = Map.fromListWith mappend exeKV

go (InstallPlan.Installed _) = error "unexpected state"
go (InstallPlan.PreExisting _) = True
go (InstallPlan.Configured (ElaboratedConfiguredPackage {
elabPkgSourceId = PackageIdentifier { pkgName, .. },
elabPkgOrComp,
..
})) = case elabPkgOrComp of
ElabPackage _ -> True
ElabComponent comp' ->
case Ty.compSolverName comp' of
CD.ComponentExe n
| Just maybeSet <- Map.lookup pkgName exeMap
-> case maybeSet of
Nothing -> True -- Wildcard, accept anything
Just set -> Set.member n set
_ -> error "unexpected state"

compExeDependencies =
map confInstId
(concatMap (elaborateExeSolverId mapDep) external_exe_dep_sids) ++
(concatMap (elaborateExeSolverId filterExeMapDep) external_exe_dep_sids) ++
cc_internal_build_tools cc
compExeDependencyPaths =
concatMap (elaborateExePath mapDep) external_exe_dep_sids ++
concatMap (elaborateExePath filterExeMapDep) external_exe_dep_sids ++
[ path
| cid' <- cc_internal_build_tools cc
, Just path <- [Map.lookup cid' exe_map]]
Expand Down Expand Up @@ -2985,4 +3017,3 @@ improveInstallPlanWithInstalledPackages installedPkgIdSet =

--TODO: decide what to do if we encounter broken installed packages,
-- since overwriting is never safe.