Distribution/Types/PackageDescription/Lens.hs

    {-# LANGUAGE OverloadedStrings #-}
    {-# LANGUAGE RankNTypes #-}
    module Distribution.Types.PackageDescription.Lens (
        PackageDescription,
        module Distribution.Types.PackageDescription.Lens,
        ) where

    import Distribution.Compat.Lens
    import Distribution.Compat.Prelude
    import Prelude ()

    import Distribution.Compiler                  (CompilerFlavor)
    import Distribution.License                   (License)
    import Distribution.ModuleName                (ModuleName)
    import Distribution.Types.Benchmark           (Benchmark, benchmarkModules)
    import Distribution.Types.Benchmark.Lens      (benchmarkName, benchmarkBuildInfo)
    import Distribution.Types.BuildInfo           (BuildInfo)
    import Distribution.Types.BuildType           (BuildType)
    import Distribution.Types.ComponentName       (ComponentName(..))
    import Distribution.Types.Executable          (Executable, exeModules)
    import Distribution.Types.Executable.Lens     (exeName, exeBuildInfo)
    import Distribution.Types.ForeignLib          (ForeignLib, foreignLibModules)
    import Distribution.Types.ForeignLib.Lens     (foreignLibName, foreignLibBuildInfo)
    import Distribution.Types.Library             (Library, explicitLibModules)
    import Distribution.Types.Library.Lens        (libName, libBuildInfo)
    import Distribution.Types.PackageDescription  (PackageDescription)
    import Distribution.Types.PackageId           (PackageIdentifier)
    import Distribution.Types.SetupBuildInfo      (SetupBuildInfo)
    import Distribution.Types.SourceRepo          (SourceRepo)
    import Distribution.Types.TestSuite           (TestSuite, testModules)
    import Distribution.Types.TestSuite.Lens      (testName, testBuildInfo)
    import Distribution.Types.UnqualComponentName ( UnqualComponentName )
    import Distribution.Version                   (Version, VersionRange)

    import qualified Distribution.SPDX                     as SPDX
    import qualified Distribution.Types.PackageDescription as T

    package :: Lens' PackageDescription PackageIdentifier
    package f s = fmap (\x -> s { T.package = x }) (f (T.package s))
    {-# INLINE package #-}

    licenseRaw :: Lens' PackageDescription (Either SPDX.License License)
    licenseRaw f s = fmap (\x -> s { T.licenseRaw = x }) (f (T.licenseRaw s))
    {-# INLINE licenseRaw #-}

    licenseFiles :: Lens' PackageDescription [String]
    licenseFiles f s = fmap (\x -> s { T.licenseFiles = x }) (f (T.licenseFiles s))
    {-# INLINE licenseFiles #-}

    copyright :: Lens' PackageDescription String
    copyright f s = fmap (\x -> s { T.copyright = x }) (f (T.copyright s))
    {-# INLINE copyright #-}

    maintainer :: Lens' PackageDescription String
    maintainer f s = fmap (\x -> s { T.maintainer = x }) (f (T.maintainer s))
    {-# INLINE maintainer #-}

    author :: Lens' PackageDescription String
    author f s = fmap (\x -> s { T.author = x }) (f (T.author s))
    {-# INLINE author #-}

    stability :: Lens' PackageDescription String
    stability f s = fmap (\x -> s { T.stability = x }) (f (T.stability s))
    {-# INLINE stability #-}

    testedWith :: Lens' PackageDescription [(CompilerFlavor,VersionRange)]
    testedWith f s = fmap (\x -> s { T.testedWith = x }) (f (T.testedWith s))
    {-# INLINE testedWith #-}

    homepage :: Lens' PackageDescription String
    homepage f s = fmap (\x -> s { T.homepage = x }) (f (T.homepage s))
    {-# INLINE homepage #-}

    pkgUrl :: Lens' PackageDescription String
    pkgUrl f s = fmap (\x -> s { T.pkgUrl = x }) (f (T.pkgUrl s))
    {-# INLINE pkgUrl #-}

    bugReports :: Lens' PackageDescription String
    bugReports f s = fmap (\x -> s { T.bugReports = x }) (f (T.bugReports s))
    {-# INLINE bugReports #-}

    sourceRepos :: Lens' PackageDescription [SourceRepo]
    sourceRepos f s = fmap (\x -> s { T.sourceRepos = x }) (f (T.sourceRepos s))
    {-# INLINE sourceRepos #-}

    synopsis :: Lens' PackageDescription String
    synopsis f s = fmap (\x -> s { T.synopsis = x }) (f (T.synopsis s))
    {-# INLINE synopsis #-}

    description :: Lens' PackageDescription String
    description f s = fmap (\x -> s { T.description = x }) (f (T.description s))
    {-# INLINE description #-}

    category :: Lens' PackageDescription String
    category f s = fmap (\x -> s { T.category = x }) (f (T.category s))
    {-# INLINE category #-}

    customFieldsPD :: Lens' PackageDescription [(String,String)]
    customFieldsPD f s = fmap (\x -> s { T.customFieldsPD = x }) (f (T.customFieldsPD s))
    {-# INLINE customFieldsPD #-}

    specVersionRaw :: Lens' PackageDescription (Either Version VersionRange)
    specVersionRaw f s = fmap (\x -> s { T.specVersionRaw = x }) (f (T.specVersionRaw s))
    {-# INLINE specVersionRaw #-}

    buildTypeRaw :: Lens' PackageDescription (Maybe BuildType)
    buildTypeRaw f s = fmap (\x -> s { T.buildTypeRaw = x }) (f (T.buildTypeRaw s))
    {-# INLINE buildTypeRaw #-}

    setupBuildInfo :: Lens' PackageDescription (Maybe SetupBuildInfo)
    setupBuildInfo f s = fmap (\x -> s { T.setupBuildInfo = x }) (f (T.setupBuildInfo s))
    {-# INLINE setupBuildInfo #-}

    library :: Lens' PackageDescription (Maybe Library)
    library f s = fmap (\x -> s { T.library = x }) (f (T.library s))
    {-# INLINE library #-}

    subLibraries :: Lens' PackageDescription [Library]
    subLibraries f s = fmap (\x -> s { T.subLibraries = x }) (f (T.subLibraries s))
    {-# INLINE subLibraries #-}

    executables :: Lens' PackageDescription [Executable]
    executables f s = fmap (\x -> s { T.executables = x }) (f (T.executables s))
    {-# INLINE executables #-}

    foreignLibs :: Lens' PackageDescription [ForeignLib]
    foreignLibs f s = fmap (\x -> s { T.foreignLibs = x }) (f (T.foreignLibs s))
    {-# INLINE foreignLibs #-}

    testSuites :: Lens' PackageDescription [TestSuite]
    testSuites f s = fmap (\x -> s { T.testSuites = x }) (f (T.testSuites s))
    {-# INLINE testSuites #-}

    benchmarks :: Lens' PackageDescription [Benchmark]
    benchmarks f s = fmap (\x -> s { T.benchmarks = x }) (f (T.benchmarks s))
    {-# INLINE benchmarks #-}

    dataFiles :: Lens' PackageDescription [FilePath]
    dataFiles f s = fmap (\x -> s { T.dataFiles = x }) (f (T.dataFiles s))
    {-# INLINE dataFiles #-}

    dataDir :: Lens' PackageDescription FilePath
    dataDir f s = fmap (\x -> s { T.dataDir = x }) (f (T.dataDir s))
    {-# INLINE dataDir #-}

    extraSrcFiles :: Lens' PackageDescription [String]
    extraSrcFiles f s = fmap (\x -> s { T.extraSrcFiles = x }) (f (T.extraSrcFiles s))
    {-# INLINE extraSrcFiles #-}

    extraTmpFiles :: Lens' PackageDescription [String]
    extraTmpFiles f s = fmap (\x -> s { T.extraTmpFiles = x }) (f (T.extraTmpFiles s))
    {-# INLINE extraTmpFiles #-}

    extraDocFiles :: Lens' PackageDescription [String]
    extraDocFiles f s = fmap (\x -> s { T.extraDocFiles = x }) (f (T.extraDocFiles s))
    {-# INLINE extraDocFiles #-}

    -- | @since 2.4
    componentModules :: Monoid r => ComponentName -> Getting r PackageDescription [ModuleName]
    componentModules cname = case cname of
        CLibName         -> library  . traverse . getting explicitLibModules
        CSubLibName name ->
          componentModules' name subLibraries (libName . non "") explicitLibModules
        CFLibName   name ->
          componentModules' name foreignLibs  foreignLibName     foreignLibModules
        CExeName    name ->
          componentModules' name executables  exeName            exeModules
        CTestName   name ->
          componentModules' name testSuites   testName           testModules
        CBenchName  name ->
          componentModules' name benchmarks   benchmarkName      benchmarkModules
      where
        componentModules'
            :: Monoid r
            => UnqualComponentName
            -> Traversal' PackageDescription [a]
            -> Traversal' a UnqualComponentName
            -> (a -> [ModuleName])
            -> Getting r PackageDescription [ModuleName]
        componentModules' name pdL nameL modules =
            pdL
          . traverse
          . filtered ((== name) . view nameL)
          . getting modules

        -- This are easily wrongly used, so we have them here locally only.
        non :: Eq a => a -> Lens' (Maybe a) a
        non x afb s = f <$> afb (fromMaybe x s)
            where f y = if x == y then Nothing else Just y

        filtered :: (a -> Bool) -> Traversal' a a
        filtered p f s = if p s then f s else pure s

    -- | @since 2.4
    componentBuildInfo :: ComponentName -> Traversal' PackageDescription BuildInfo
    componentBuildInfo cname = case cname of
        CLibName         ->
          library  . traverse . libBuildInfo
        CSubLibName name ->
          componentBuildInfo' name subLibraries (libName . non "") libBuildInfo
        CFLibName   name ->
          componentBuildInfo' name foreignLibs  foreignLibName     foreignLibBuildInfo
        CExeName    name ->
          componentBuildInfo' name executables  exeName            exeBuildInfo
        CTestName   name ->
          componentBuildInfo' name testSuites   testName           testBuildInfo
        CBenchName  name ->
          componentBuildInfo' name benchmarks   benchmarkName      benchmarkBuildInfo
      where
        componentBuildInfo' :: UnqualComponentName
                             -> Traversal' PackageDescription [a]
                             -> Traversal' a UnqualComponentName
                             -> Traversal' a BuildInfo
                             -> Traversal' PackageDescription BuildInfo
        componentBuildInfo' name pdL nameL biL =
            pdL
          . traverse
          . filtered ((== name) . view nameL)
          . biL

        -- This are easily wrongly used, so we have them here locally only.
        -- We have to repeat these, as everything is exported from this module.
        non :: Eq a => a -> Lens' (Maybe a) a
        non x afb s = f <$> afb (fromMaybe x s)
            where f y = if x == y then Nothing else Just y

        filtered :: (a -> Bool) -> Traversal' a a
        filtered p f s = if p s then f s else pure s