make LTS branch pre-releases
[cabal.git] / Cabal-syntax / src / Distribution / Types / PackageId.hs
blobb5c4764ad22627186fcce72336e7ab116529f59a
1 {-# LANGUAGE DeriveDataTypeable #-}
2 {-# LANGUAGE DeriveGeneric #-}
4 module Distribution.Types.PackageId
5 ( PackageIdentifier (..)
6 , PackageId
7 ) where
9 import Distribution.Compat.Prelude
10 import Prelude ()
12 import Distribution.Parsec (Parsec (..), simpleParsec)
13 import Distribution.Pretty
14 import Distribution.Types.PackageName
15 import Distribution.Version (Version, nullVersion)
17 import qualified Data.List.NonEmpty as NE
18 import qualified Distribution.Compat.CharParsing as P
19 import qualified Text.PrettyPrint as Disp
21 -- | Type alias so we can use the shorter name PackageId.
22 type PackageId = PackageIdentifier
24 -- | The name and version of a package.
25 data PackageIdentifier = PackageIdentifier
26 { pkgName :: PackageName
27 -- ^ The name of this package, eg. foo
28 , pkgVersion :: Version
29 -- ^ the version of this package, eg 1.2
31 deriving (Generic, Read, Show, Eq, Ord, Typeable, Data)
33 instance Binary PackageIdentifier
34 instance Structured PackageIdentifier
36 instance Pretty PackageIdentifier where
37 pretty (PackageIdentifier n v)
38 | v == nullVersion = pretty n -- if no version, don't show version.
39 | otherwise = pretty n <<>> Disp.char '-' <<>> pretty v
41 -- |
43 -- >>> simpleParsec "foo-bar-0" :: Maybe PackageIdentifier
44 -- Just (PackageIdentifier {pkgName = PackageName "foo-bar", pkgVersion = mkVersion [0]})
46 -- >>> simpleParsec "foo-bar" :: Maybe PackageIdentifier
47 -- Just (PackageIdentifier {pkgName = PackageName "foo-bar", pkgVersion = mkVersion []})
49 -- /Note:/ Stricter than 'Text' instance
51 -- >>> simpleParsec "foo-bar-0-0" :: Maybe PackageIdentifier
52 -- Nothing
54 -- >>> simpleParsec "foo-bar.0" :: Maybe PackageIdentifier
55 -- Nothing
57 -- >>> simpleParsec "foo-bar.4-2" :: Maybe PackageIdentifier
58 -- Nothing
60 -- >>> simpleParsec "1.2.3" :: Maybe PackageIdentifier
61 -- Nothing
62 instance Parsec PackageIdentifier where
63 parsec = do
64 xs' <- P.sepByNonEmpty component (P.char '-')
65 (v, xs) <- case simpleParsec (NE.last xs') of
66 Nothing -> return (nullVersion, toList xs') -- all components are version
67 Just v -> return (v, NE.init xs')
68 if not (null xs) && all (\c -> all (/= '.') c && not (all isDigit c)) xs
69 then return $ PackageIdentifier (mkPackageName (intercalate "-" xs)) v
70 else fail "all digits or a dot in a portion of package name"
71 where
72 component = P.munch1 (\c -> isAlphaNum c || c == '.')
74 instance NFData PackageIdentifier where
75 rnf (PackageIdentifier name version) = rnf name `seq` rnf version