Skip to content

Commit 5bcde6a

Browse files
authored
Merge pull request #5117 from Ericson2314/pd-component-lens
Add more lenses for PackageDescription and GenericPackageDescription
2 parents c641f1a + ba2a3c4 commit 5bcde6a

File tree

7 files changed

+111
-95
lines changed

7 files changed

+111
-95
lines changed

Cabal/Distribution/PackageDescription/Check.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1655,7 +1655,7 @@ checkUnicodeXFields gpd
16551655
xfields :: [(String,String)]
16561656
xfields = DList.runDList $ mconcat
16571657
[ toDListOf (L.packageDescription . L.customFieldsPD . traverse) gpd
1658-
, toDListOf (L.buildInfos . L.customFieldsBI . traverse) gpd
1658+
, toDListOf (L.traverseBuildInfos . L.customFieldsBI . traverse) gpd
16591659
]
16601660

16611661
-- | cabal-version <2.2 + Paths_module + default-extensions: doesn't build.

Cabal/Distribution/PackageDescription/Configuration.hs

Lines changed: 14 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,12 @@ module Distribution.PackageDescription.Configuration (
3737
import Prelude ()
3838
import Distribution.Compat.Prelude
3939

40+
-- lens
41+
import qualified Distribution.Types.BuildInfo.Lens as L
42+
import qualified Distribution.Types.GenericPackageDescription.Lens as L
43+
import qualified Distribution.Types.PackageDescription.Lens as L
44+
import qualified Distribution.Types.SetupBuildInfo.Lens as L
45+
4046
import Distribution.PackageDescription
4147
import Distribution.PackageDescription.Utils
4248
import Distribution.Version
@@ -47,7 +53,6 @@ import Distribution.Text
4753
import Distribution.Compat.Lens
4854
import Distribution.Compat.ReadP as ReadP hiding ( char )
4955
import qualified Distribution.Compat.ReadP as ReadP ( char )
50-
import qualified Distribution.Types.BuildInfo.Lens as L
5156
import Distribution.Types.ComponentRequestedSpec
5257
import Distribution.Types.ForeignLib
5358
import Distribution.Types.Component
@@ -577,77 +582,17 @@ transformAllBuildInfos :: (BuildInfo -> BuildInfo)
577582
-> (SetupBuildInfo -> SetupBuildInfo)
578583
-> GenericPackageDescription
579584
-> GenericPackageDescription
580-
transformAllBuildInfos onBuildInfo onSetupBuildInfo gpd = gpd'
581-
where
582-
onLibrary lib = lib { libBuildInfo = onBuildInfo $ libBuildInfo lib }
583-
onExecutable exe = exe { buildInfo = onBuildInfo $ buildInfo exe }
584-
onTestSuite tst = tst { testBuildInfo = onBuildInfo $ testBuildInfo tst }
585-
onBenchmark bmk = bmk { benchmarkBuildInfo =
586-
onBuildInfo $ benchmarkBuildInfo bmk }
587-
588-
pd = packageDescription gpd
589-
pd' = pd {
590-
library = fmap onLibrary (library pd),
591-
subLibraries = map onLibrary (subLibraries pd),
592-
executables = map onExecutable (executables pd),
593-
testSuites = map onTestSuite (testSuites pd),
594-
benchmarks = map onBenchmark (benchmarks pd),
595-
setupBuildInfo = fmap onSetupBuildInfo (setupBuildInfo pd)
596-
}
597-
598-
gpd' = transformAllCondTrees onLibrary onExecutable
599-
onTestSuite onBenchmark id
600-
$ gpd { packageDescription = pd' }
585+
transformAllBuildInfos onBuildInfo onSetupBuildInfo =
586+
over L.traverseBuildInfos onBuildInfo
587+
. over (L.packageDescription . L.setupBuildInfo . traverse) onSetupBuildInfo
601588

602589
-- | Walk a 'GenericPackageDescription' and apply @f@ to all nested
603590
-- @build-depends@ fields.
604591
transformAllBuildDepends :: (Dependency -> Dependency)
605592
-> GenericPackageDescription
606593
-> GenericPackageDescription
607-
transformAllBuildDepends f gpd = gpd'
608-
where
609-
onBI bi = bi { targetBuildDepends = map f $ targetBuildDepends bi }
610-
onSBI stp = stp { setupDepends = map f $ setupDepends stp }
611-
612-
gpd' = transformAllCondTrees id id id id (map f)
613-
. transformAllBuildInfos onBI onSBI
614-
$ gpd
615-
616-
-- | Walk all 'CondTree's inside a 'GenericPackageDescription' and apply
617-
-- appropriate transformations to all nodes. Helper function used by
618-
-- 'transformAllBuildDepends' and 'transformAllBuildInfos'.
619-
transformAllCondTrees :: (Library -> Library)
620-
-> (Executable -> Executable)
621-
-> (TestSuite -> TestSuite)
622-
-> (Benchmark -> Benchmark)
623-
-> ([Dependency] -> [Dependency])
624-
-> GenericPackageDescription -> GenericPackageDescription
625-
transformAllCondTrees onLibrary onExecutable
626-
onTestSuite onBenchmark onDepends gpd = gpd'
627-
where
628-
gpd' = gpd {
629-
condLibrary = condLib',
630-
condSubLibraries = condSubLibs',
631-
condExecutables = condExes',
632-
condTestSuites = condTests',
633-
condBenchmarks = condBenchs'
634-
}
635-
636-
condLib = condLibrary gpd
637-
condSubLibs = condSubLibraries gpd
638-
condExes = condExecutables gpd
639-
condTests = condTestSuites gpd
640-
condBenchs = condBenchmarks gpd
641-
642-
condLib' = fmap (onCondTree onLibrary) condLib
643-
condSubLibs' = map (mapSnd $ onCondTree onLibrary) condSubLibs
644-
condExes' = map (mapSnd $ onCondTree onExecutable) condExes
645-
condTests' = map (mapSnd $ onCondTree onTestSuite) condTests
646-
condBenchs' = map (mapSnd $ onCondTree onBenchmark) condBenchs
647-
648-
mapSnd :: (a -> b) -> (c,a) -> (c,b)
649-
mapSnd = fmap
650-
651-
onCondTree :: (a -> b) -> CondTree v [Dependency] a
652-
-> CondTree v [Dependency] b
653-
onCondTree g = mapCondTree g onDepends id
594+
transformAllBuildDepends f =
595+
over (L.traverseBuildInfos . L.targetBuildDepends . traverse) f
596+
. over (L.packageDescription . L.setupBuildInfo . traverse . L.setupDepends . traverse) f
597+
-- cannot be point-free as normal because of higher rank
598+
. over (\f' -> L.allCondTrees $ traverseCondTreeC f') (map f)

Cabal/Distribution/Types/BuildInfo/Lens.hs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
module Distribution.Types.BuildInfo.Lens (
22
BuildInfo,
33
HasBuildInfo (..),
4+
HasBuildInfos (..),
45
) where
56

67
import Prelude ()
@@ -314,3 +315,6 @@ instance HasBuildInfo BuildInfo where
314315

315316
mixins f s = fmap (\x -> s { T.mixins = x }) (f (T.mixins s))
316317
{-# INLINE mixins #-}
318+
319+
class HasBuildInfos a where
320+
traverseBuildInfos :: Traversal' a BuildInfo

Cabal/Distribution/Types/CondTree.hs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ module Distribution.Types.CondTree (
1515
mapTreeData,
1616
traverseCondTreeV,
1717
traverseCondBranchV,
18+
traverseCondTreeC,
19+
traverseCondBranchC,
1820
extractCondition,
1921
simplifyCondTree,
2022
ignoreConditions,
@@ -25,6 +27,9 @@ import Distribution.Compat.Prelude
2527

2628
import Distribution.Types.Condition
2729

30+
import qualified Distribution.Compat.Lens as L
31+
32+
2833
-- | A 'CondTree' is used to represent the conditional structure of
2934
-- a Cabal file, reflecting a syntax element subject to constraints,
3035
-- and then any number of sub-elements which may be enabled subject
@@ -108,18 +113,30 @@ mapTreeConds f = mapCondTree id id f
108113
mapTreeData :: (a -> b) -> CondTree v c a -> CondTree v c b
109114
mapTreeData f = mapCondTree f id id
110115

111-
-- | @Traversal (CondTree v c a) (CondTree w c a) v w@
112-
traverseCondTreeV :: Applicative f => (v -> f w) -> CondTree v c a -> f (CondTree w c a)
116+
-- | @@Traversal@@ for the variables
117+
traverseCondTreeV :: L.Traversal (CondTree v c a) (CondTree w c a) v w
113118
traverseCondTreeV f (CondNode a c ifs) =
114119
CondNode a c <$> traverse (traverseCondBranchV f) ifs
115120

116-
-- | @Traversal (CondBranch v c a) (CondBranch w c a) v w@
117-
traverseCondBranchV :: Applicative f => (v -> f w) -> CondBranch v c a -> f (CondBranch w c a)
121+
-- | @@Traversal@@ for the variables
122+
traverseCondBranchV :: L.Traversal (CondBranch v c a) (CondBranch w c a) v w
118123
traverseCondBranchV f (CondBranch cnd t me) = CondBranch
119124
<$> traverse f cnd
120125
<*> traverseCondTreeV f t
121126
<*> traverse (traverseCondTreeV f) me
122127

128+
-- | @@Traversal@@ for the aggregated constraints
129+
traverseCondTreeC :: L.Traversal (CondTree v c a) (CondTree v d a) c d
130+
traverseCondTreeC f (CondNode a c ifs) =
131+
CondNode a <$> f c <*> traverse (traverseCondBranchC f) ifs
132+
133+
-- | @@Traversal@@ for the aggregated constraints
134+
traverseCondBranchC :: L.Traversal (CondBranch v c a) (CondBranch v d a) c d
135+
traverseCondBranchC f (CondBranch cnd t me) = CondBranch cnd
136+
<$> traverseCondTreeC f t
137+
<*> traverse (traverseCondTreeC f) me
138+
139+
123140
-- | Extract the condition matched by the given predicate from a cond tree.
124141
--
125142
-- We use this mainly for extracting buildable conditions (see the Note above),

Cabal/Distribution/Types/GenericPackageDescription.hs

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ import qualified Distribution.Compat.ReadP as Parse
3636
import qualified Distribution.Compat.CharParsing as P
3737
import Distribution.Compat.ReadP ((+++))
3838

39+
-- lens
40+
import Distribution.Compat.Lens as L
41+
import qualified Distribution.Types.BuildInfo.Lens as L
42+
3943
import Distribution.Types.PackageDescription
4044

4145
import Distribution.Types.Dependency
@@ -56,7 +60,7 @@ import Distribution.Pretty
5660
import Distribution.Text
5761

5862
-- ---------------------------------------------------------------------------
59-
-- The GenericPackageDescription type
63+
-- The 'GenericPackageDescription' type
6064

6165
data GenericPackageDescription =
6266
GenericPackageDescription
@@ -83,6 +87,27 @@ instance Binary GenericPackageDescription
8387

8488
instance NFData GenericPackageDescription where rnf = genericRnf
8589

90+
emptyGenericPackageDescription :: GenericPackageDescription
91+
emptyGenericPackageDescription = GenericPackageDescription emptyPackageDescription [] Nothing [] [] [] [] []
92+
93+
-- -----------------------------------------------------------------------------
94+
-- Traversal Instances
95+
96+
instance L.HasBuildInfos GenericPackageDescription where
97+
traverseBuildInfos f (GenericPackageDescription p a1 x1 x2 x3 x4 x5 x6) =
98+
GenericPackageDescription
99+
<$> L.traverseBuildInfos f p
100+
<*> pure a1
101+
<*> (traverse . traverse . L.buildInfo) f x1
102+
<*> (traverse . L._2 . traverse . L.buildInfo) f x2
103+
<*> (traverse . L._2 . traverse . L.buildInfo) f x3
104+
<*> (traverse . L._2 . traverse . L.buildInfo) f x4
105+
<*> (traverse . L._2 . traverse . L.buildInfo) f x5
106+
<*> (traverse . L._2 . traverse . L.buildInfo) f x6
107+
108+
-- -----------------------------------------------------------------------------
109+
-- The Flag' type
110+
86111
-- | A flag can represent a feature to be included, or a way of linking
87112
-- a target against its dependencies, or in fact whatever you can think of.
88113
data Flag = MkFlag
@@ -313,6 +338,9 @@ parseFlagAssignment = mkFlagAssignment <$>
313338
return (f, False))
314339
-- {-# DEPRECATED parseFlagAssignment "Use parsecFlagAssignment. This symbol will be removed in Cabal-3.0 (est. Oct 2018)." #-}
315340

341+
-- -----------------------------------------------------------------------------
342+
-- The 'CondVar' type
343+
316344
-- | A @ConfVar@ represents the variable type used.
317345
data ConfVar = OS OS
318346
| Arch Arch
@@ -323,6 +351,3 @@ data ConfVar = OS OS
323351
instance Binary ConfVar
324352

325353
instance NFData ConfVar where rnf = genericRnf
326-
327-
emptyGenericPackageDescription :: GenericPackageDescription
328-
emptyGenericPackageDescription = GenericPackageDescription emptyPackageDescription [] Nothing [] [] [] [] []

Cabal/Distribution/Types/GenericPackageDescription/Lens.hs

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
{-# LANGUAGE Rank2Types #-}
12
module Distribution.Types.GenericPackageDescription.Lens (
23
GenericPackageDescription,
34
Flag,
@@ -10,11 +11,6 @@ import Prelude()
1011
import Distribution.Compat.Prelude
1112
import Distribution.Compat.Lens
1213

13-
import Distribution.Types.GenericPackageDescription (GenericPackageDescription(GenericPackageDescription), Flag(MkFlag), FlagName, ConfVar (..))
14-
15-
-- lens
16-
import Distribution.Types.BuildInfo.Lens
17-
1814
-- We import types from their packages, so we can remove unused imports
1915
-- and have wider inter-module dependency graph
2016
import Distribution.Types.CondTree (CondTree)
@@ -23,6 +19,9 @@ import Distribution.Types.Executable (Executable)
2319
import Distribution.Types.PackageDescription (PackageDescription)
2420
import Distribution.Types.Benchmark (Benchmark)
2521
import Distribution.Types.ForeignLib (ForeignLib)
22+
import Distribution.Types.GenericPackageDescription
23+
( GenericPackageDescription(GenericPackageDescription)
24+
, Flag(MkFlag), FlagName, ConfVar (..))
2625
import Distribution.Types.Library (Library)
2726
import Distribution.Types.TestSuite (TestSuite)
2827
import Distribution.Types.UnqualComponentName (UnqualComponentName)
@@ -66,19 +65,23 @@ packageDescription :: Lens' GenericPackageDescription PackageDescription
6665
packageDescription f (GenericPackageDescription x1 x2 x3 x4 x5 x6 x7 x8) = fmap (\y1 -> GenericPackageDescription y1 x2 x3 x4 x5 x6 x7 x8) (f x1)
6766
{-# INLINE packageDescription #-}
6867

69-
-------------------------------------------------------------------------------
70-
-- BuildInfos
71-
-------------------------------------------------------------------------------
68+
allCondTrees
69+
:: Applicative f
70+
=> (forall a. CondTree ConfVar [Dependency] a
71+
-> f (CondTree ConfVar [Dependency] a))
72+
-> GenericPackageDescription
73+
-> f GenericPackageDescription
74+
allCondTrees f (GenericPackageDescription p a1 x1 x2 x3 x4 x5 x6) =
75+
GenericPackageDescription
76+
<$> pure p
77+
<*> pure a1
78+
<*> traverse f x1
79+
<*> (traverse . _2) f x2
80+
<*> (traverse . _2) f x3
81+
<*> (traverse . _2) f x4
82+
<*> (traverse . _2) f x5
83+
<*> (traverse . _2) f x6
7284

73-
buildInfos :: Traversal' GenericPackageDescription BuildInfo
74-
buildInfos f (GenericPackageDescription x1 x2 x3 x4 x5 x6 x7 x8) =
75-
GenericPackageDescription x1 x2
76-
<$> (traverse . traverse . buildInfo) f x3
77-
<*> (traverse . _2 . traverse . buildInfo) f x4
78-
<*> (traverse . _2 . traverse . buildInfo) f x5
79-
<*> (traverse . _2 . traverse . buildInfo) f x6
80-
<*> (traverse . _2 . traverse . buildInfo) f x7
81-
<*> (traverse . _2 . traverse . buildInfo) f x8
8285

8386
-------------------------------------------------------------------------------
8487
-- Flag

Cabal/Distribution/Types/PackageDescription.hs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ import Distribution.Compat.Prelude
6464

6565
import Control.Monad ((<=<))
6666

67+
-- lens
68+
import qualified Distribution.Types.BuildInfo.Lens as L
6769
import Distribution.Types.Library
6870
import Distribution.Types.TestSuite
6971
import Distribution.Types.Executable
@@ -468,3 +470,23 @@ getComponent pkg cname =
468470
missingComponent =
469471
error $ "internal error: the package description contains no "
470472
++ "component corresponding to " ++ show cname
473+
474+
-- -----------------------------------------------------------------------------
475+
-- Traversal Instances
476+
477+
instance L.HasBuildInfos PackageDescription where
478+
traverseBuildInfos f (PackageDescription a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19
479+
x1 x2 x3 x4 x5 x6
480+
a20 a21 a22 a23 a24) =
481+
PackageDescription a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19
482+
<$> (traverse . L.buildInfo) f x1 -- library
483+
<*> (traverse . L.buildInfo) f x2 -- sub libraries
484+
<*> (traverse . L.buildInfo) f x3 -- executables
485+
<*> (traverse . L.buildInfo) f x4 -- foreign libs
486+
<*> (traverse . L.buildInfo) f x5 -- test suites
487+
<*> (traverse . L.buildInfo) f x6 -- benchmarks
488+
<*> pure a20 -- data files
489+
<*> pure a21 -- data dir
490+
<*> pure a22 -- exta src files
491+
<*> pure a23 -- extra temp files
492+
<*> pure a24 -- extra doc files

0 commit comments

Comments
 (0)