Copyright | Isaac Jones 2003-2004 |
---|---|
License | BSD3 |
Maintainer | cabal-devel@haskell.org |
Portability | portable |
Safe Haskell | Safe-Inferred |
Language | Haskell98 |
Defines a package identifier along with a parser and pretty printer for it.
PackageIdentifier
s consist of a name and an exact version. It also defines
a Dependency
data type. A dependency is a package name and a version
range, like "foo >= 1.2 && < 2"
.
- newtype PackageName = PackageName {}
- data PackageIdentifier = PackageIdentifier {}
- type PackageId = PackageIdentifier
- newtype InstalledPackageId = InstalledPackageId String
- data PackageKey
- mkPackageKey :: Bool -> PackageId -> [PackageKey] -> [(ModuleName, (PackageKey, ModuleName))] -> PackageKey
- packageKeyHash :: PackageKey -> String
- packageKeyLibraryName :: PackageId -> PackageKey -> String
- data Dependency = Dependency PackageName VersionRange
- thisPackageVersion :: PackageIdentifier -> Dependency
- notThisPackageVersion :: PackageIdentifier -> Dependency
- simplifyDependency :: Dependency -> Dependency
- class Package pkg where
- packageId :: pkg -> PackageIdentifier
- packageName :: Package pkg => pkg -> PackageName
- packageVersion :: Package pkg => pkg -> Version
- class Package pkg => PackageFixedDeps pkg where
- depends :: pkg -> [PackageIdentifier]
- class Package pkg => PackageInstalled pkg where
- installedPackageId :: pkg -> InstalledPackageId
- installedDepends :: pkg -> [InstalledPackageId]
Package ids
newtype PackageName
data PackageIdentifier
The name and version of a package.
PackageIdentifier | |
|
type PackageId = PackageIdentifier
Type alias so we can use the shorter name PackageId.
Installed package identifiers
newtype InstalledPackageId
An InstalledPackageId uniquely identifies an instance of an installed
package. There can be at most one package with a given InstalledPackageId
in a package database, or overlay of databases.
Package keys (used for linker symbols and library name)
data PackageKey
A PackageKey
is the notion of "package ID" which is visible to the
compiler. Why is this not a PackageId
? The PackageId
is a user-visible
concept written explicity in Cabal files; on the other hand, a PackageKey
may contain, for example, information about the transitive dependency
tree of a package. Why is this not an InstalledPackageId
? A PackageKey
affects the ABI because it is used for linker symbols; however, an
InstalledPackageId
can be used to distinguish two ABI-compatible versions
of a library.
The key is defined to be a 128-bit MD5 hash, separated into two 64-bit components (the most significant component coming first) which are individually base-62 encoded (A-Z, a-z, 0-9).
key ::= hash64 hash64 hash64 ::= [A-Za-z0-9]{11}
The string that is hashed is specified as raw_key:
raw_key ::= package_id "n" holes_nl depends_nl package_id ::= package_name "-" package_version holes_nl ::= "" | hole_inst "n" holes_nl hole_inst ::= modulename " " key ":" modulename depends_nl ::= "" | depend "n" depends_nl depend ::= key
The holes list MUST be sorted by the first modulename; the depends list MUST be sorted by the key. holes describes the backing implementations of all holes in the package; depends describes all of the build-depends of a package. A package key MAY be used in holes even if it is not mentioned in depends: depends contains STRICTLY packages which are textually mentioned in the package description.
The trailing newline is MANDATORY.
There is also a variant of package key which is prefixed by a informational string. This key MUST NOT be used in the computation of the hash proper, but it is useful for human-readable consumption.
infokey ::= infostring "_" key infostring ::= [A-Za-z0-9-]+
For example, Cabal provides a key with the first five characters of the package name for linker symbols.
PackageKey !String !Word64 !Word64 | Modern package key which is a hash of the PackageId and the transitive dependency key. Manually inline it here so we can get the instances we need. Also contains a short informative string |
OldPackageKey !PackageId | Old-style package key which is just a |
mkPackageKey :: Bool -> PackageId -> [PackageKey] -> [(ModuleName, (PackageKey, ModuleName))] -> PackageKey
Generates a PackageKey
from a PackageId
, sorted package keys of the
immediate dependencies.
packageKeyHash :: PackageKey -> String
packageKeyLibraryName :: PackageId -> PackageKey -> String
Package source dependencies
data Dependency
Describes a dependency on a source package (API)
simplifyDependency :: Dependency -> Dependency
Simplify the VersionRange
expression in a Dependency
.
See simplifyVersionRange
.
Package classes
class Package pkg where
Class of things that have a PackageIdentifier
Types in this class are all notions of a package. This allows us to have different types for the different phases that packages go though, from simple name/id, package description, configured or installed packages.
Not all kinds of packages can be uniquely identified by a
PackageIdentifier
. In particular, installed packages cannot, there may be
many installed instances of the same source package.
packageId :: pkg -> PackageIdentifier
packageName :: Package pkg => pkg -> PackageName
packageVersion :: Package pkg => pkg -> Version
class Package pkg => PackageFixedDeps pkg where
Subclass of packages that have specific versioned dependencies.
So for example a not-yet-configured package has dependencies on version ranges, not specific versions. A configured or an already installed package depends on exact versions. Some operations or data structures (like dependency graphs) only make sense on this subclass of package types.
depends :: pkg -> [PackageIdentifier]
class Package pkg => PackageInstalled pkg where
Class of installed packages.
The primary data type which is an instance of this package is
InstalledPackageInfo
, but when we are doing install plans in Cabal install
we may have other, installed package-like things which contain more metadata.
Installed packages have exact dependencies installedDepends
.
installedPackageId :: pkg -> InstalledPackageId
installedDepends :: pkg -> [InstalledPackageId]