{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Distribution.Package (
PackageName(..),
PackageIdentifier(..),
PackageId,
ComponentId(..),
UnitId(..),
mkUnitId,
mkLegacyUnitId,
getHSLibraryName,
InstalledPackageId,
AbiHash(..),
Dependency(..),
thisPackageVersion,
notThisPackageVersion,
simplifyDependency,
Package(..), packageName, packageVersion,
HasUnitId(..),
installedPackageId,
PackageInstalled(..),
) where
import Distribution.Version
( Version(..), VersionRange, anyVersion, thisVersion
, notThisVersion, simplifyVersionRange )
import qualified Distribution.Compat.ReadP as Parse
import qualified Text.PrettyPrint as Disp
import Distribution.Compat.ReadP
import Distribution.Compat.Binary
import Distribution.Text
import Control.DeepSeq (NFData(..))
import qualified Data.Char as Char
( isDigit, isAlphaNum, )
import Data.Data ( Data )
import Data.List ( intercalate )
import Data.Typeable ( Typeable )
import GHC.Generics (Generic)
import Text.PrettyPrint ((<>), (<+>), text)
newtype PackageName = PackageName { unPackageName :: String }
deriving (Generic, Read, Show, Eq, Ord, Typeable, Data)
instance Binary PackageName
instance Text PackageName where
disp (PackageName n) = Disp.text n
parse = do
ns <- Parse.sepBy1 component (Parse.char '-')
return (PackageName (intercalate "-" ns))
where
component = do
cs <- Parse.munch1 Char.isAlphaNum
if all Char.isDigit cs then Parse.pfail else return cs
instance NFData PackageName where
rnf (PackageName pkg) = rnf pkg
type PackageId = PackageIdentifier
data PackageIdentifier
= PackageIdentifier {
pkgName :: PackageName,
pkgVersion :: Version
}
deriving (Generic, Read, Show, Eq, Ord, Typeable, Data)
instance Binary PackageIdentifier
instance Text PackageIdentifier where
disp (PackageIdentifier n v) = case v of
Version [] _ -> disp n
_ -> disp n <> Disp.char '-' <> disp v
parse = do
n <- parse
v <- (Parse.char '-' >> parse) <++ return (Version [] [])
return (PackageIdentifier n v)
instance NFData PackageIdentifier where
rnf (PackageIdentifier name version) = rnf name `seq` rnf version
data ComponentId
= ComponentId String
deriving (Generic, Read, Show, Eq, Ord, Typeable, Data)
{-# DEPRECATED InstalledPackageId "Use UnitId instead" #-}
type InstalledPackageId = UnitId
instance Binary ComponentId
instance Text ComponentId where
disp (ComponentId str) = text str
parse = ComponentId `fmap` Parse.munch1 abi_char
where abi_char c = Char.isAlphaNum c || c `elem` "-_."
instance NFData ComponentId where
rnf (ComponentId pk) = rnf pk
getHSLibraryName :: UnitId -> String
getHSLibraryName (SimpleUnitId (ComponentId s)) = "HS" ++ s
newtype UnitId = SimpleUnitId ComponentId
deriving (Generic, Read, Show, Eq, Ord, Typeable, Data, Binary, Text, NFData)
mkUnitId :: String -> UnitId
mkUnitId = SimpleUnitId . ComponentId
mkLegacyUnitId :: PackageId -> UnitId
mkLegacyUnitId = SimpleUnitId . ComponentId . display
data Dependency = Dependency PackageName VersionRange
deriving (Generic, Read, Show, Eq, Typeable, Data)
instance Binary Dependency
instance Text Dependency where
disp (Dependency name ver) =
disp name <+> disp ver
parse = do name <- parse
Parse.skipSpaces
ver <- parse <++ return anyVersion
Parse.skipSpaces
return (Dependency name ver)
thisPackageVersion :: PackageIdentifier -> Dependency
thisPackageVersion (PackageIdentifier n v) =
Dependency n (thisVersion v)
notThisPackageVersion :: PackageIdentifier -> Dependency
notThisPackageVersion (PackageIdentifier n v) =
Dependency n (notThisVersion v)
simplifyDependency :: Dependency -> Dependency
simplifyDependency (Dependency name range) =
Dependency name (simplifyVersionRange range)
class Package pkg where
packageId :: pkg -> PackageIdentifier
packageName :: Package pkg => pkg -> PackageName
packageName = pkgName . packageId
packageVersion :: Package pkg => pkg -> Version
packageVersion = pkgVersion . packageId
instance Package PackageIdentifier where
packageId = id
class Package pkg => HasUnitId pkg where
installedUnitId :: pkg -> UnitId
{-# DEPRECATED installedPackageId "Use installedUnitId instead" #-}
installedPackageId :: HasUnitId pkg => pkg -> UnitId
installedPackageId = installedUnitId
class (HasUnitId pkg) => PackageInstalled pkg where
installedDepends :: pkg -> [UnitId]
newtype AbiHash = AbiHash String
deriving (Eq, Show, Read, Generic)
instance Binary AbiHash
instance Text AbiHash where
disp (AbiHash abi) = Disp.text abi
parse = fmap AbiHash (Parse.munch Char.isAlphaNum)