cabal-lenses (empty) → 0.1
raw patch · 13 files changed
+508/−0 lines, 13 filesdep +Cabaldep +basedep +lenssetup-changed
Dependencies added: Cabal, base, lens, unordered-containers
Files
- LICENSE +24/−0
- README.md +4/−0
- Setup.hs +2/−0
- cabal-lenses.cabal +44/−0
- lib/CabalLenses.hs +18/−0
- lib/CabalLenses/CondVars.hs +92/−0
- lib/CabalLenses/Package.hs +37/−0
- lib/CabalLenses/PackageDescription.hs +103/−0
- lib/CabalLenses/Section.hs +26/−0
- lib/CabalLenses/Traversals/BuildInfo.hs +32/−0
- lib/CabalLenses/Traversals/Dependency.hs +33/−0
- lib/CabalLenses/Traversals/Internal.hs +78/−0
- lib/CabalLenses/Version.hs +15/−0
+ LICENSE view
@@ -0,0 +1,24 @@+Copyright (c) 2011, Daniel Trstenjak+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:+ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.+ * Redistributions in binary form must reproduce the above copyright+ notice, this list of conditions and the following disclaimer in the+ documentation and/or other materials provided with the distribution.+ * Neither the name of the <organization> nor the+ names of its contributors may be used to endorse or promote products+ derived from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL DANIEL TRSTENJAK BE LIABLE FOR ANY+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,4 @@+cabal-lenses+============++Lenses and traversals (compatible with the [lens library](<https://hackage.haskell.org/package/lens>)) for the [Cabal library](<https://hackage.haskell.org/package/Cabal>).
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ cabal-lenses.cabal view
@@ -0,0 +1,44 @@+name: cabal-lenses+version: 0.1+cabal-version: >=1.9.2+build-type: Simple+license: BSD3+license-file: LICENSE+maintainer: daniel.trstenjak@gmail.com+synopsis: Lenses and traversals for the Cabal library.+description:+ Lenses and traversals (compatible with the <https://hackage.haskell.org/package/lens lens>) library) for+ the <https://hackage.haskell.org/package/Cabal Cabal> library.+category: Utils+author: Daniel Trstenjak+data-dir: ""+extra-source-files: + README.md+ +source-repository head+ type: git+ location: https://github.com/dan-t/cabal-lenses+ +library+ build-depends: + base >=3 && <5,+ lens >=4.0.1 && <4.1,+ unordered-containers >=0.2.3.3 && <0.3,+ Cabal >=1.18.0 && <1.21+ exposed-modules: + CabalLenses+ CabalLenses.PackageDescription+ CabalLenses.Package+ CabalLenses.Version+ CabalLenses.CondVars+ CabalLenses.Section+ CabalLenses.Traversals.BuildInfo+ CabalLenses.Traversals.Dependency+ other-modules:+ CabalLenses.Traversals.Internal+ exposed: True+ buildable: True+ cpp-options: -DCABAL+ hs-source-dirs: lib+ other-modules: Paths_cabal_lenses+ ghc-options: -W
+ lib/CabalLenses.hs view
@@ -0,0 +1,18 @@++module CabalLenses+ ( module CabalLenses.CondVars+ , module CabalLenses.PackageDescription+ , module CabalLenses.Package+ , module CabalLenses.Version+ , module CabalLenses.Section+ , module CabalLenses.Traversals.BuildInfo+ , module CabalLenses.Traversals.Dependency+ ) where++import CabalLenses.CondVars+import CabalLenses.PackageDescription+import CabalLenses.Package+import CabalLenses.Version+import CabalLenses.Section+import CabalLenses.Traversals.BuildInfo+import CabalLenses.Traversals.Dependency
+ lib/CabalLenses/CondVars.hs view
@@ -0,0 +1,92 @@+{-# Language TemplateHaskell, PatternGuards #-}++module CabalLenses.CondVars+ ( CondVars(..)+ , fromDefaults+ , enableFlag+ , disableFlag+ , eval+ ) where++import qualified Distribution.PackageDescription as PD+import Distribution.PackageDescription (Condition(..))+import qualified Distribution.System as S+import Distribution.System (OS(..), Arch(..))+import Distribution.Compiler (CompilerFlavor(..), buildCompilerFlavor)+import Distribution.Version (Version(..), withinRange)+import qualified Data.HashMap.Strict as HM+import Control.Lens++type FlagName = String+type FlagMap = HM.HashMap FlagName Bool+++-- | The variables that are used to resolve the conditionals inside of the cabal file.+-- Holds the enable state of the cabal flags, the used OS, ARCH, CompilerFlavor and+-- compiler version.+data CondVars = CondVars+ { flags :: FlagMap -- ^ the enable state of the flags, initialized with the default flag values in the cabal file+ , os :: OS -- ^ the used OS, by default the one cabal was build on+ , arch :: Arch -- ^ the used ARCH, by default the one cabal was build on+ , compilerFlavor :: CompilerFlavor -- ^ the used CompilerFlavor, by default the one cabal was build on+ , compilerVersion :: Maybe Version -- ^ the user specified compiler version+ } deriving (Show)+++makeLensesFor [ ("flags", "flagsL")+ ] ''CondVars+++-- | Create a 'CondVars' from the default flags of the cabal package description.+-- The 'os', 'arch' and 'compilerFlavor' fields are initialized by the ones the cabal library was build on.+fromDefaults :: PD.GenericPackageDescription -> CondVars+fromDefaults pkgDescrp = CondVars { flags = flags+ , os = S.buildOS+ , arch = S.buildArch+ , compilerFlavor = buildCompilerFlavor+ , compilerVersion = Nothing+ }+ where+ flags = HM.fromList $ map nameWithDflt (PD.genPackageFlags pkgDescrp)++ nameWithDflt PD.MkFlag { PD.flagName = PD.FlagName name, PD.flagDefault = dflt } =+ (name, dflt)+++-- | Enable the given flag in 'CondVars'.+enableFlag :: FlagName -> CondVars -> CondVars+enableFlag flag condVars =+ condVars & flagsL %~ HM.insert flag True+++-- | Disable the given flag in 'CondVars'.+disableFlag :: FlagName -> CondVars -> CondVars+disableFlag flag condVars =+ condVars & flagsL %~ HM.insert flag False+++-- | Evaluate the 'Condition' using the 'CondVars'.+eval :: CondVars -> Condition PD.ConfVar -> Bool+eval condVars = eval'+ where+ eval' (Var var) = hasVar var+ eval' (Lit val) = val+ eval' (CNot c) = not $ eval' c+ eval' (COr c1 c2) = eval' c1 || eval' c2+ eval' (CAnd c1 c2) = eval' c1 && eval' c2++ hasVar (PD.OS osVar) = osVar == os condVars+ hasVar (PD.Arch archVar) = archVar == arch condVars+ hasVar (PD.Impl cflavor vrange)+ | Just version <- compilerVersion condVars+ = cflavor == compilerFlavor condVars && version `withinRange` vrange++ | otherwise+ = cflavor == compilerFlavor condVars++ hasVar (PD.Flag (PD.FlagName name))+ | Just v <- HM.lookup name (flags condVars)+ = v++ | otherwise+ = False
+ lib/CabalLenses/Package.hs view
@@ -0,0 +1,37 @@+{-# LANGUAGE TemplateHaskell #-}++-- |+-- Lenses for several data types of the 'Distribution.Package' module.+-- All lenses are named after their field names with a 'L' appended.++module CabalLenses.Package where++import Distribution.Package (PackageName(..) , PackageIdentifier(..) , Dependency(..))+import Distribution.Version (VersionRange)+import Control.Lens (makeLensesFor, Lens', lens)+++pkgNameString :: Lens' PackageName String+pkgNameString = lens getString setString+ where+ getString (PackageName str) = str+ setString _ = PackageName+++makeLensesFor [ ("pkgName" , "pkgNameL")+ , ("pkgVersion", "pkgVersionL")+ ] ''PackageIdentifier+++depPackageName :: Lens' Dependency PackageName+depPackageName = lens getPkgName setPkgName+ where+ getPkgName (Dependency pkgName _) = pkgName+ setPkgName (Dependency _ range) newPkgName = Dependency newPkgName range+++depVersionRange :: Lens' Dependency VersionRange+depVersionRange = lens getRange setRange+ where+ getRange (Dependency _ range) = range+ setRange (Dependency pkgName _) = Dependency pkgName
+ lib/CabalLenses/PackageDescription.hs view
@@ -0,0 +1,103 @@+{-# LANGUAGE TemplateHaskell #-}++-- |+-- Lenses for several data types of the 'Distribution.PackageDescription' module.+-- All lenses are named after their field names with a 'L' appended.++module CabalLenses.PackageDescription where++import Distribution.PackageDescription ( GenericPackageDescription(..)+ , PackageDescription(..)+ , Library(..)+ , Executable(..)+ , TestSuite(..)+ , Benchmark(..)+ , BuildInfo(..)+ , CondTree(..)+ )+import Control.Lens (makeLensesFor)+++makeLensesFor [ ("packageDescription", "packageDescriptionL")+ , ("genPackageFlags" , "genPackageFlagsL")+ , ("condLibrary" , "condLibraryL")+ , ("condExecutables" , "condExecutablesL")+ , ("condTestSuites" , "condTestSuitesL")+ , ("condBenchmarks" , "condBenchmarksL")+ ] ''GenericPackageDescription+++makeLensesFor [ ("package" , "packageL")+ , ("license" , "licenseL")+ , ("licenseFile" , "licenseFileL")+ , ("copyright" , "copyrightL")+ , ("maintainer" , "maintainerL")+ , ("author" , "authorL")+ , ("stability" , "stabilityL")+ , ("testedWith" , "testedWithL")+ , ("homepage" , "homepageL")+ , ("pkgUrl" , "pkgUrlL")+ , ("bugReports" , "bugReports")+ , ("sourceRepos" , "sourceReposL")+ , ("synopsis" , "synopsisL")+ , ("description" , "descriptionL")+ , ("category" , "categoryL")+ , ("customFieldsPD", "customFieldsPDL")+ , ("buildDepends" , "buildDependsL")+ , ("specVersionRaw", "specVersionRawL")+ , ("buildType" , "buildTypeL")+ , ("library" , "libraryL")+ , ("executables" , "executablesL")+ , ("testSuites" , "testSuitesL")+ , ("benchmarks" , "benchmarksL")+ , ("dataFiles" , "dataFilesL")+ , ("dataDir" , "dataDirL")+ , ("extraSrcFiles" , "extraSrcFilesL")+ , ("extraTmpFiles" , "extraTmpFilesL")+ ] ''PackageDescription+++makeLensesFor [ ("exposedModules", "exposedModulesL")+ , ("libExposed" , "libExposedL")+ , ("libBuildInfo" , "libBuildInfoL")+ ] ''Library+++makeLensesFor [ ("exeName" , "exeNameL")+ , ("modulePath", "modulePathL")+ , ("buildInfo" , "buildInfoL")+ ] ''Executable+++makeLensesFor [ ("testName" , "testNameL")+ , ("testInterface", "testInterfaceL")+ , ("testBuildInfo", "testBuildInfoL")+ , ("testEnabled" , "testEnabledL")+ ] ''TestSuite+++makeLensesFor [ ("benchmarkName", "benchmarkNameL")+ , ("benchmarkInterface", "benchmarkInterfaceL")+ , ("benchmarkBuildInfo", "benchmarkBuildInfoL")+ , ("benchmarkEnabled" , "benchmarkEnabledL")+ ] ''Benchmark+++makeLensesFor [ ("hsSourceDirs" , "hsSourceDirsL")+ , ("options" , "optionsL")+ , ("defaultLanguage" , "defaultLanguageL")+ , ("cppOptions" , "cppOptionsL")+ , ("cSources" , "cSourcesL")+ , ("ccOptions" , "ccOptionsL")+ , ("extraLibDirs" , "extraLibDirsL")+ , ("extraLibs" , "extraLibsL")+ , ("ldOptions" , "ldOptionsL")+ , ("includeDirs" , "includeDirsL")+ , ("includes" , "includesL")+ ] ''BuildInfo+++makeLensesFor [ ("condTreeData" , "condTreeDataL")+ , ("condTreeConstraints", "condTreeConstraintsL")+ , ("condTreeComponents" , "condTreeComponentsL")+ ] ''CondTree
+ lib/CabalLenses/Section.hs view
@@ -0,0 +1,26 @@++module CabalLenses.Section+ ( Section(..)+ , allSections+ ) where++import Distribution.PackageDescription (GenericPackageDescription(..))++type Name = String++-- | A section of the cabal file.+data Section = Library+ | Executable Name+ | TestSuite Name+ | Benchmark Name+ deriving (Show, Eq)+++-- | All sections defined in 'GenericPackageDescription'.+allSections :: GenericPackageDescription -> [Section]+allSections pkgDescr =+ concat [ maybe [] (const [Library]) (condLibrary pkgDescr)+ , map (Executable . fst) (condExecutables pkgDescr)+ , map (TestSuite . fst) (condTestSuites pkgDescr)+ , map (Benchmark . fst) (condBenchmarks pkgDescr)+ ]
+ lib/CabalLenses/Traversals/BuildInfo.hs view
@@ -0,0 +1,32 @@+{-# LANGUAGE Rank2Types #-}++module CabalLenses.Traversals.BuildInfo+ ( buildInfo+ , buildInfoIf+ ) where++import CabalLenses.Section (Section(..))+import CabalLenses.Traversals.Internal (traverseData, traverseDataIf)+import CabalLenses.CondVars (CondVars)+import CabalLenses.PackageDescription+import Control.Lens+import Distribution.PackageDescription (GenericPackageDescription, BuildInfo)+++-- | A traversal for all 'BuildInfo' of 'Section'.+buildInfo :: Section -> Traversal' GenericPackageDescription BuildInfo+buildInfo Library = condLibraryL . _Just . traverseData . libBuildInfoL+buildInfo (Executable name) = condExecutablesL . traverse . having name . _2 . traverseData . buildInfoL+buildInfo (TestSuite name) = condTestSuitesL . traverse . having name . _2 . traverseData . testBuildInfoL+buildInfo (Benchmark name) = condBenchmarksL . traverse . having name . _2 . traverseData . benchmarkBuildInfoL+++-- | A traversal for the 'BuildInfo' of 'Section' that match 'CondVars'.+buildInfoIf :: CondVars -> Section -> Traversal' GenericPackageDescription BuildInfo+buildInfoIf condVars Library = condLibraryL . _Just . traverseDataIf condVars . libBuildInfoL+buildInfoIf condVars (Executable name) = condExecutablesL . traverse . having name . _2 . traverseDataIf condVars . buildInfoL+buildInfoIf condVars (TestSuite name) = condTestSuitesL . traverse . having name . _2 . traverseDataIf condVars . testBuildInfoL+buildInfoIf condVars (Benchmark name) = condBenchmarksL . traverse . having name . _2 . traverseDataIf condVars . benchmarkBuildInfoL+++having name = filtered ((== name) . fst)
+ lib/CabalLenses/Traversals/Dependency.hs view
@@ -0,0 +1,33 @@+{-# LANGUAGE Rank2Types #-}++module CabalLenses.Traversals.Dependency+ ( dependency+ , dependencyIf+ ) where++import CabalLenses.Section (Section(..))+import CabalLenses.Traversals.Internal (traverseDependency, traverseDependencyIf)+import CabalLenses.CondVars (CondVars)+import CabalLenses.PackageDescription+import Control.Lens+import Distribution.PackageDescription (GenericPackageDescription)+import Distribution.Package (Dependency)+++-- | A traversal for all 'Dependency' of 'Section'.+dependency :: Section -> Traversal' GenericPackageDescription Dependency+dependency Library = condLibraryL . _Just . traverseDependency+dependency (Executable name) = condExecutablesL . traverse . having name . _2 . traverseDependency+dependency (TestSuite name) = condTestSuitesL . traverse . having name . _2 . traverseDependency+dependency (Benchmark name) = condBenchmarksL . traverse . having name . _2 . traverseDependency+++-- | A traversal for the 'Dependency' of 'Section' that match 'CondVars'.+dependencyIf :: CondVars -> Section -> Traversal' GenericPackageDescription Dependency+dependencyIf condVars Library = condLibraryL . _Just . traverseDependencyIf condVars+dependencyIf condVars (Executable name) = condExecutablesL . traverse . having name . _2 . traverseDependencyIf condVars+dependencyIf condVars (TestSuite name) = condTestSuitesL . traverse . having name . _2 . traverseDependencyIf condVars+dependencyIf condVars (Benchmark name) = condBenchmarksL . traverse . having name . _2 . traverseDependencyIf condVars+++having name = filtered ((== name) . fst)
+ lib/CabalLenses/Traversals/Internal.hs view
@@ -0,0 +1,78 @@+{-# LANGUAGE TupleSections, Rank2Types #-}++module CabalLenses.Traversals.Internal+ ( traverseDataIf+ , traverseData+ , traverseDependencyIf+ , traverseDependency+ ) where++import CabalLenses.CondVars (CondVars)+import qualified CabalLenses.CondVars as CV+import Distribution.PackageDescription (CondTree(..), ConfVar)+import Distribution.Package (Dependency(..))+import Data.Traversable (traverse)+import Control.Applicative (Applicative, pure, (<$>), (<*>))+import Control.Lens (Traversal')++type CondTree' a = CondTree ConfVar [Dependency] a+++-- | A traversal for all 'condTreeData' of 'CondTree' that match 'CondVars'.+traverseDataIf :: CondVars -> Traversal' (CondTree' dat) dat+traverseDataIf condVars f (CondNode dat constr comps) =+ CondNode <$> f dat+ <*> pure constr+ <*> (traverse . traverseCompIf condVars) f comps + where+ traverseCompIf condVars f (cond, ifComp, elseComp) =+ (,,) <$> pure cond <*> ifComp' <*> elseComp'+ where+ ifComp' | condMatches = traverseDataIf condVars f ifComp+ | otherwise = pure ifComp++ elseComp' | condMatches = pure elseComp+ | otherwise = (traverse . traverseDataIf condVars) f elseComp++ condMatches = CV.eval condVars cond+++-- | A traversal for all 'condTreeData' (the if and else branches) of the 'CondTree'.+traverseData :: Traversal' (CondTree' dat) dat+traverseData f (CondNode dat constr comps) =+ CondNode <$> f dat+ <*> pure constr+ <*> (traverse . traverseComp) f comps+ where+ traverseComp f (cond, ifComp, elseComp) =+ (,,) <$> pure cond <*> traverseData f ifComp <*> (traverse . traverseData) f elseComp+++-- | A traversal for all 'condTreeConstraints' of 'CondTree' that match 'CondVars'.+traverseDependencyIf :: CondVars -> Traversal' (CondTree' dat) Dependency+traverseDependencyIf condVars f (CondNode dat constr comps) =+ CondNode <$> pure dat+ <*> traverse f constr+ <*> (traverse . traverseCompIf condVars) f comps + where+ traverseCompIf condVars f (cond, ifComp, elseComp) =+ (,,) <$> pure cond <*> ifComp' <*> elseComp'+ where+ ifComp' | condMatches = traverseDependencyIf condVars f ifComp+ | otherwise = pure ifComp++ elseComp' | condMatches = pure elseComp+ | otherwise = (traverse . traverseDependencyIf condVars) f elseComp++ condMatches = CV.eval condVars cond+++-- | A traversal for all 'condTreeConstraints' (the if and else branches) of the 'CondTree'.+traverseDependency :: Traversal' (CondTree' dat) Dependency+traverseDependency f (CondNode dat constr comps) =+ CondNode <$> pure dat+ <*> traverse f constr+ <*> (traverse . traverseComp) f comps+ where+ traverseComp f (cond, ifComp, elseComp) =+ (,,) <$> pure cond <*> traverseDependency f ifComp <*> (traverse . traverseDependency) f elseComp
+ lib/CabalLenses/Version.hs view
@@ -0,0 +1,15 @@+{-# LANGUAGE TemplateHaskell #-}++-- |+-- Lenses for several data types of the 'Distribution.Version' module.+-- All lenses are named after their field names with a 'L' appended.++module CabalLenses.Version where++import Distribution.Version (Version(..))+import Control.Lens (makeLensesFor)+++makeLensesFor [ ("versionBranch", "versionBranchL")+ , ("versionTags" , "versionTagsL")+ ] ''Version