Skip to content

Commit b9cfe19

Browse files
committed
Support wildcard build-tool-depends entries in Cabal
They look like pkg:* <optional version bound> and denote a dependency on every executable in the package. In the case of internal package dependencies, it is easy to expand the wildcard for internal dependencies, but not possible in Cabal alone for external ones, as the exact set of exe deps depends on the version resolved in cabal-install's build plan.
1 parent bbd5803 commit b9cfe19

File tree

5 files changed

+28
-13
lines changed

5 files changed

+28
-13
lines changed

Cabal/Distribution/PackageDescription/Check.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,7 @@ checkFields pkg =
635635

636636
depMissingInternalExecutable =
637637
[ dep
638-
| dep@(ExeDependency _ eName _) <- internalExeDeps
638+
| dep@(ExeDependency _ (Just eName) _) <- internalExeDeps
639639
, not $ eName `elem` internalExecutables
640640
]
641641

Cabal/Distribution/Parsec/Class.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ instance Parsec ExeDependency where
141141
parsec = do
142142
name <- lexemeParsec
143143
_ <- P.char ':'
144-
exe <- lexemeParsec
144+
exe <- (Just <$> lexemeParsec) <|> (P.char '*' >> pure Nothing)
145145
ver <- parsec <|> pure anyVersion
146146
return (ExeDependency name exe ver)
147147

Cabal/Distribution/Simple/BuildToolDepends.hs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ desugarBuildTool :: PackageDescription
3434
-> Maybe ExeDependency
3535
desugarBuildTool pkg led =
3636
if foundLocal
37-
then Just $ ExeDependency (packageName pkg) toolName reqVer
37+
then Just $ ExeDependency (packageName pkg) (Just toolName) reqVer
3838
else Map.lookup name whiteMap
3939
where
4040
LegacyExeDependency name reqVer = led
@@ -44,7 +44,7 @@ desugarBuildTool pkg led =
4444
, "cpphs", "greencard", "hspec-discover"
4545
]
4646
whiteMap = Map.fromList $ flip map whitelist $ \n ->
47-
(n, ExeDependency (mkPackageName n) (mkUnqualComponentName n) reqVer)
47+
(n, ExeDependency (mkPackageName n) (Just $ mkUnqualComponentName n) reqVer)
4848

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

8585
-- | Get internal "build-tool-depends", along with internal "build-tools"
8686
--
87-
-- This is a tiny function, but used in a number of places. The same
88-
-- restrictions that apply to `isInternal` also apply to this function.
87+
-- Besides filtering to just internal deps, this also desugars wildcard deps
88+
-- since we know the same version/configuration of the package will be used to
89+
-- install them, and thus we know the precise set of executables that wildcard
90+
-- expands to.
91+
--
92+
-- The same restrictions that apply to `isInternal` also apply to this function.
8993
getAllInternalToolDependencies :: PackageDescription
9094
-> BuildInfo
9195
-> [UnqualComponentName]
9296
getAllInternalToolDependencies pkg bi =
9397
[ toolname
94-
| dep@(ExeDependency _ toolname _) <- getAllToolDependencies pkg bi
98+
| dep@(ExeDependency _ optToolname _) <- getAllToolDependencies pkg bi
9599
, isInternal pkg dep
100+
, toolname <- case optToolname of
101+
Just tn -> pure tn
102+
Nothing -> exeName <$> executables pkg
96103
]

Cabal/Distribution/Simple/Configure.hs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,9 @@ configure (pkg_descr0', pbi) cfg = do
571571
++ intercalate "," unsupportedFLibs
572572

573573
-- Configure certain external build tools, see below for which ones.
574+
--
575+
-- TODO: HACK we're currently ignoring wildcard deps as we don't know
576+
-- precisely which executables the resolved package will contain.
574577
let requiredBuildTools = do
575578
bi <- enabledBuildInfos pkg_descr enabled
576579
-- First, we collect any tool dep that we know is external. This is,
@@ -581,7 +584,7 @@ configure (pkg_descr0', pbi) cfg = do
581584
-- 2. `build-tool-depends` that aren't from the current package.
582585
let externBuildToolDeps =
583586
[ LegacyExeDependency (unUnqualComponentName eName) versionRange
584-
| buildTool@(ExeDependency _ eName versionRange)
587+
| buildTool@(ExeDependency _ (Just eName) versionRange)
585588
<- getAllToolDependencies pkg_descr bi
586589
, not $ isInternal pkg_descr buildTool ]
587590
-- Second, we collect any build-tools entry we don't know how to

Cabal/Distribution/Types/ExeDependency.hs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ import Text.PrettyPrint ((<+>), text)
2323
--
2424
data ExeDependency = ExeDependency
2525
PackageName
26-
UnqualComponentName -- name of executable component of package
26+
-- Name of specific executable component of package, or
27+
-- nothing for a wilcard dependency on them all
28+
(Maybe UnqualComponentName)
2729
VersionRange
2830
deriving (Generic, Read, Show, Eq, Typeable, Data)
2931

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

3335
instance Text ExeDependency where
3436
disp (ExeDependency name exe ver) =
35-
(disp name <<>> text ":" <<>> disp exe) <+> disp ver
37+
(disp name <<>> text ":" <<>> exe') <+> disp ver
38+
where exe' = case exe of
39+
Just e -> disp e
40+
Nothing -> text "*"
3641

3742
parse = do name <- parse
3843
_ <- Parse.char ':'
39-
exe <- parse
44+
exe <- (Just <$> parse) <++ (Parse.char '*' >> pure Nothing)
4045
Parse.skipSpaces
4146
ver <- parse <++ return anyVersion
4247
Parse.skipSpaces
4348
return (ExeDependency name exe ver)
4449

45-
qualifiedExeName :: ExeDependency -> ComponentName
46-
qualifiedExeName (ExeDependency _ ucn _) = CExeName ucn
50+
qualifiedExeName :: ExeDependency -> Maybe ComponentName
51+
qualifiedExeName (ExeDependency _ ucn _) = CExeName <$> ucn

0 commit comments

Comments
 (0)