Distribution.Client.IndexUtils

cabal-install-3.12.1.0: The command-line interface for Cabal and Hackage.

Copyright | (c) Duncan Coutts 2008
License | BSD-like
Maintainer | duncan@community.haskell.org
Stability | provisional
Portability | portable
Safe Haskell | None
Language | Haskell2010

Distribution.Client.IndexUtils

Contents

- preferred-versions utilities

Description

Extra utils related to the package indexes.

Synopsis

- getIndexFileAge :: Repo -> IO Double
- getInstalledPackages :: Verbosity -> Compiler -> PackageDBStack -> ProgramDb -> IO InstalledPackageIndex
- indexBaseName :: Repo -> FilePath
- getInstalledPackagesMonitorFiles :: Verbosity -> Compiler -> PackageDBStack -> ProgramDb -> Platform -> IO [FilePath]
- getSourcePackages :: Verbosity -> RepoContext -> IO SourcePackageDb
- getSourcePackagesMonitorFiles :: [Repo] -> [FilePath]
- data TotalIndexState
- getSourcePackagesAtIndexState :: Verbosity -> RepoContext -> Maybe TotalIndexState -> Maybe ActiveRepos -> IO (SourcePackageDb, TotalIndexState, ActiveRepos)
- data ActiveRepos
- filterSkippedActiveRepos :: ActiveRepos -> ActiveRepos
- data Index = RepoIndex RepoContext Repo
- data RepoIndexState
  - = IndexStateHead
  - | IndexStateTime !Timestamp
- data PackageEntry
  - = NormalPackage PackageId GenericPackageDescription ByteString BlockNo
  - | BuildTreeRef BuildTreeRefType PackageId GenericPackageDescription FilePath BlockNo
- parsePackageIndex :: Verbosity -> ByteString -> [IO (Maybe PackageOrDep)]
- updateRepoIndexCache :: Verbosity -> Index -> IO ()
- updatePackageIndexCacheFile :: Verbosity -> Index -> IO ()
- writeIndexTimestamp :: Index -> RepoIndexState -> IO ()
- currentIndexTimestamp :: Verbosity -> Index -> IO Timestamp
- data BuildTreeRefType
  - = SnapshotRef
  - | LinkRef
- refTypeFromTypeCode :: TypeCode -> BuildTreeRefType
- typeCodeFromRefType :: BuildTreeRefType -> TypeCode
- preferredVersions :: FilePath
- isPreferredVersions :: FilePath -> Bool
- parsePreferredVersionsWarnings :: ByteString -> [Either PreferredVersionsParseError Dependency]
- data PreferredVersionsParseError = PreferredVersionsParseError {
  - preferredVersionsParsecError :: String
  - preferredVersionsOriginalDependency :: String
  }

# Documentation

getIndexFileAge :: Repo -> IO Double #

Return the age of the index file in days (as a Double).

getInstalledPackages :: Verbosity -> Compiler -> PackageDBStack -> ProgramDb -> IO InstalledPackageIndex #

Reduced-verbosity version of `getInstalledPackages`

indexBaseName :: Repo -> FilePath #

Get filename base (i.e. without file extension) for index-related files

Secure cabal repositories use a new extended & incremental `01-index.tar`. In order to avoid issues resulting from clobbering new/old-style index data, we save them locally to different names.

Example: Use `indexBaseName repo . "tar.gz"` to compute the `FilePath` of the `00-index.tar.gz`/`01-index.tar.gz` file.

getInstalledPackagesMonitorFiles :: Verbosity -> Compiler -> PackageDBStack -> ProgramDb -> Platform -> IO [FilePath] #

A set of files (or directories) that can be monitored to detect when there might have been a change in the installed packages.

getSourcePackages :: Verbosity -> RepoContext -> IO SourcePackageDb #

Read a repository index from disk, from the local files specified by a list of `Repo`s.

All the `SourcePackage`s are marked as having come from the appropriate `Repo`.

This is a higher level wrapper used internally in cabal-install.

getSourcePackagesMonitorFiles :: [Repo] -> [FilePath] #

A set of files (or directories) that can be monitored to detect when there might have been a change in the source packages.

data TotalIndexState #

Index state of multiple repositories

#### Instances

Instances details

Parsec TotalIndexState # |
    >>> simpleParsec "HEAD" :: Maybe TotalIndexState
    Just (TIS IndexStateHead (fromList []))
    >>> simpleParsec "" :: Maybe TotalIndexState
    Nothing
    >>> simpleParsec "hackage.haskell.org HEAD" :: Maybe TotalIndexState
    Just (TIS IndexStateHead (fromList []))
    >>> simpleParsec "2020-02-04T12:34:56Z, hackage.haskell.org HEAD" :: Maybe TotalIndexState
    Just (TIS (IndexStateTime (TS 1580819696)) (fromList [(RepoName {unRepoName = "hackage.haskell.org"},IndexStateHead)]))
    >>> simpleParsec "hackage.haskell.org 2020-02-04T12:34:56Z" :: Maybe TotalIndexState
    Just (TIS IndexStateHead (fromList [(RepoName {unRepoName = "hackage.haskell.org"},IndexStateTime (TS 1580819696))]))
Instance details Defined in Distribution.Client.IndexUtils.IndexState Methods parsec :: CabalParsing m => m TotalIndexState #
Pretty TotalIndexState # |
Instance details Defined in Distribution.Client.IndexUtils.IndexState Methods pretty :: TotalIndexState -> Doc # prettyVersioned :: CabalSpecVersion -> TotalIndexState -> Doc #
Structured TotalIndexState # |
Instance details Defined in Distribution.Client.IndexUtils.IndexState Methods structure :: Proxy TotalIndexState -> Structure # structureHash' :: Tagged TotalIndexState MD5
Binary TotalIndexState # |
Instance details Defined in Distribution.Client.IndexUtils.IndexState Methods put :: TotalIndexState -> Put # get :: Get TotalIndexState # putList :: [TotalIndexState] -> Put #
NFData TotalIndexState # |
Instance details Defined in Distribution.Client.IndexUtils.IndexState Methods rnf :: TotalIndexState -> () #
Generic TotalIndexState # |
Instance details Defined in Distribution.Client.IndexUtils.IndexState Associated Types
type Rep TotalIndexState |
Instance details Defined in Distribution.Client.IndexUtils.IndexState type Rep TotalIndexState = D1 ('MetaData "TotalIndexState" "Distribution.Client.IndexUtils.IndexState" "cabal-install-3.12.1.0-G554PkJj2SpDqyarXp9tbt" 'False) (C1 ('MetaCons "TIS" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 RepoIndexState) :*: S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Map RepoName RepoIndexState))))
Methods from :: TotalIndexState -> Rep TotalIndexState x # to :: Rep TotalIndexState x -> TotalIndexState #
Show TotalIndexState # |
Instance details Defined in Distribution.Client.IndexUtils.IndexState Methods showsPrec :: Int -> TotalIndexState -> ShowS # show :: TotalIndexState -> String # showList :: [TotalIndexState] -> ShowS #
Eq TotalIndexState # |
Instance details Defined in Distribution.Client.IndexUtils.IndexState Methods (==) :: TotalIndexState -> TotalIndexState -> Bool # (/=) :: TotalIndexState -> TotalIndexState -> Bool #
type Rep TotalIndexState # |
Instance details Defined in Distribution.Client.IndexUtils.IndexState type Rep TotalIndexState = D1 ('MetaData "TotalIndexState" "Distribution.Client.IndexUtils.IndexState" "cabal-install-3.12.1.0-G554PkJj2SpDqyarXp9tbt" 'False) (C1 ('MetaCons "TIS" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 RepoIndexState) :*: S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Map RepoName RepoIndexState))))

getSourcePackagesAtIndexState :: Verbosity -> RepoContext -> Maybe TotalIndexState -> Maybe ActiveRepos -> IO (SourcePackageDb, TotalIndexState, ActiveRepos) #

Variant of `getSourcePackages` which allows getting the source packages at a particular `IndexState`.

Current choices are either the latest (aka HEAD), or the index as it was at a particular time.

Returns also the total index where repositories' RepoIndexState's are not HEAD. This is used in v2-freeze.

data ActiveRepos #

Ordered list of active repositories.

#### Instances

Instances details

Parsec ActiveRepos # | Note: empty string is not valid `ActiveRepos`.
    >>> simpleParsec "" :: Maybe ActiveRepos
    Nothing
    >>> simpleParsec ":none" :: Maybe ActiveRepos
    Just (ActiveRepos [])
    >>> simpleParsec ":rest" :: Maybe ActiveRepos
    Just (ActiveRepos [ActiveRepoRest CombineStrategyMerge])
    >>> simpleParsec "hackage.haskell.org, :rest, head.hackage:override" :: Maybe ActiveRepos
    Just (ActiveRepos [ActiveRepo (RepoName {unRepoName = "hackage.haskell.org"}) CombineStrategyMerge,ActiveRepoRest CombineStrategyMerge,ActiveRepo (RepoName {unRepoName = "head.hackage"}) CombineStrategyOverride])
Instance details Defined in Distribution.Client.IndexUtils.ActiveRepos Methods parsec :: CabalParsing m => m ActiveRepos #
Pretty ActiveRepos # |
Instance details Defined in Distribution.Client.IndexUtils.ActiveRepos Methods pretty :: ActiveRepos -> Doc # prettyVersioned :: CabalSpecVersion -> ActiveRepos -> Doc #
Structured ActiveRepos # |
Instance details Defined in Distribution.Client.IndexUtils.ActiveRepos Methods structure :: Proxy ActiveRepos -> Structure # structureHash' :: Tagged ActiveRepos MD5
Binary ActiveRepos # |
Instance details Defined in Distribution.Client.IndexUtils.ActiveRepos Methods put :: ActiveRepos -> Put # get :: Get ActiveRepos # putList :: [ActiveRepos] -> Put #
NFData ActiveRepos # |
Instance details Defined in Distribution.Client.IndexUtils.ActiveRepos Methods rnf :: ActiveRepos -> () #
Generic ActiveRepos # |
Instance details Defined in Distribution.Client.IndexUtils.ActiveRepos Associated Types
type Rep ActiveRepos |
Instance details Defined in Distribution.Client.IndexUtils.ActiveRepos type Rep ActiveRepos = D1 ('MetaData "ActiveRepos" "Distribution.Client.IndexUtils.ActiveRepos" "cabal-install-3.12.1.0-G554PkJj2SpDqyarXp9tbt" 'True) (C1 ('MetaCons "ActiveRepos" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 [ActiveRepoEntry])))
Methods from :: ActiveRepos -> Rep ActiveRepos x # to :: Rep ActiveRepos x -> ActiveRepos #
Show ActiveRepos # |
Instance details Defined in Distribution.Client.IndexUtils.ActiveRepos Methods showsPrec :: Int -> ActiveRepos -> ShowS # show :: ActiveRepos -> String # showList :: [ActiveRepos] -> ShowS #
Eq ActiveRepos # |
Instance details Defined in Distribution.Client.IndexUtils.ActiveRepos Methods (==) :: ActiveRepos -> ActiveRepos -> Bool # (/=) :: ActiveRepos -> ActiveRepos -> Bool #
type Rep ActiveRepos # |
Instance details Defined in Distribution.Client.IndexUtils.ActiveRepos type Rep ActiveRepos = D1 ('MetaData "ActiveRepos" "Distribution.Client.IndexUtils.ActiveRepos" "cabal-install-3.12.1.0-G554PkJj2SpDqyarXp9tbt" 'True) (C1 ('MetaCons "ActiveRepos" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 [ActiveRepoEntry])))

filterSkippedActiveRepos :: ActiveRepos -> ActiveRepos #

Note, this does nothing if `ActiveRepoRest` is present.

data Index #

Which index do we mean?

Constructors

RepoIndex RepoContext Repo | The main index for the specified repository

data RepoIndexState #

Specification of the state of a specific repo package index

Constructors

IndexStateHead | Use all available entries
IndexStateTime !Timestamp | Use all entries that existed at the specified time

#### Instances

Instances details

Parsec RepoIndexState # |
Instance details Defined in Distribution.Client.IndexUtils.IndexState Methods parsec :: CabalParsing m => m RepoIndexState #
Pretty RepoIndexState # |
Instance details Defined in Distribution.Client.IndexUtils.IndexState Methods pretty :: RepoIndexState -> Doc # prettyVersioned :: CabalSpecVersion -> RepoIndexState -> Doc #
Structured RepoIndexState # |
Instance details Defined in Distribution.Client.IndexUtils.IndexState Methods structure :: Proxy RepoIndexState -> Structure # structureHash' :: Tagged RepoIndexState MD5
Binary RepoIndexState # |
Instance details Defined in Distribution.Client.IndexUtils.IndexState Methods put :: RepoIndexState -> Put # get :: Get RepoIndexState # putList :: [RepoIndexState] -> Put #
NFData RepoIndexState # |
Instance details Defined in Distribution.Client.IndexUtils.IndexState Methods rnf :: RepoIndexState -> () #
Generic RepoIndexState # |
Instance details Defined in Distribution.Client.IndexUtils.IndexState Associated Types
type Rep RepoIndexState |
Instance details Defined in Distribution.Client.IndexUtils.IndexState type Rep RepoIndexState = D1 ('MetaData "RepoIndexState" "Distribution.Client.IndexUtils.IndexState" "cabal-install-3.12.1.0-G554PkJj2SpDqyarXp9tbt" 'False) (C1 ('MetaCons "IndexStateHead" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "IndexStateTime" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Timestamp)))
Methods from :: RepoIndexState -> Rep RepoIndexState x # to :: Rep RepoIndexState x -> RepoIndexState #
Show RepoIndexState # |
Instance details Defined in Distribution.Client.IndexUtils.IndexState Methods showsPrec :: Int -> RepoIndexState -> ShowS # show :: RepoIndexState -> String # showList :: [RepoIndexState] -> ShowS #
Eq RepoIndexState # |
Instance details Defined in Distribution.Client.IndexUtils.IndexState Methods (==) :: RepoIndexState -> RepoIndexState -> Bool # (/=) :: RepoIndexState -> RepoIndexState -> Bool #
type Rep RepoIndexState # |
Instance details Defined in Distribution.Client.IndexUtils.IndexState type Rep RepoIndexState = D1 ('MetaData "RepoIndexState" "Distribution.Client.IndexUtils.IndexState" "cabal-install-3.12.1.0-G554PkJj2SpDqyarXp9tbt" 'False) (C1 ('MetaCons "IndexStateHead" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "IndexStateTime" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'SourceStrict 'DecidedStrict) (Rec0 Timestamp)))

data PackageEntry #

An index entry is either a normal package, or a local build tree reference.

Constructors

NormalPackage PackageId GenericPackageDescription ByteString BlockNo |
BuildTreeRef BuildTreeRefType PackageId GenericPackageDescription FilePath BlockNo |

#### Instances

Instances details

Package PackageEntry # |
Instance details Defined in Distribution.Client.IndexUtils Methods packageId :: PackageEntry -> PackageIdentifier #

parsePackageIndex :: Verbosity -> ByteString -> [IO (Maybe PackageOrDep)] #

Read `00-index.tar.gz` and extract `.cabal` and `preferred-versions` files

We read the index using `read`, which gives us a lazily constructed `TarEntries`. We translate it to a list of entries using `tarEntriesList`, which preserves the lazy nature of `TarEntries`, and finally `concatMap` a function over this to translate it to a list of IO actions returning `PackageOrDep`s. We can use `lazySequence` to turn this into a list of `PackageOrDep`s, still maintaining the lazy nature of the original tar read.

updateRepoIndexCache :: Verbosity -> Index -> IO () #

It is not necessary to call this, as the cache will be updated when the index is read normally. However you can do the work earlier if you like.

updatePackageIndexCacheFile :: Verbosity -> Index -> IO () #

writeIndexTimestamp :: Index -> RepoIndexState -> IO () #

Write the `IndexState` to the filesystem

currentIndexTimestamp :: Verbosity -> Index -> IO Timestamp #

Read out the "current" index timestamp, i.e., what timestamp you would use to revert to this version.

Note: this is not the same as `readIndexTimestamp`! This resolves HEAD to the index's `isiHeadTime`, i.e. the index latest known timestamp.

Return NoTimestamp if the index has never been updated.

data BuildTreeRefType #

A build tree reference is either a link or a snapshot.

Constructors

SnapshotRef |
LinkRef |

#### Instances

Instances details

Structured BuildTreeRefType # |
Instance details Defined in Distribution.Client.IndexUtils Methods structure :: Proxy BuildTreeRefType -> Structure # structureHash' :: Tagged BuildTreeRefType MD5
Binary BuildTreeRefType # |
Instance details Defined in Distribution.Client.IndexUtils Methods put :: BuildTreeRefType -> Put # get :: Get BuildTreeRefType # putList :: [BuildTreeRefType] -> Put #
Generic BuildTreeRefType # |
Instance details Defined in Distribution.Client.IndexUtils Associated Types
type Rep BuildTreeRefType |
Instance details Defined in Distribution.Client.IndexUtils type Rep BuildTreeRefType = D1 ('MetaData "BuildTreeRefType" "Distribution.Client.IndexUtils" "cabal-install-3.12.1.0-G554PkJj2SpDqyarXp9tbt" 'False) (C1 ('MetaCons "SnapshotRef" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "LinkRef" 'PrefixI 'False) (U1 :: Type -> Type))
Methods from :: BuildTreeRefType -> Rep BuildTreeRefType x # to :: Rep BuildTreeRefType x -> BuildTreeRefType #
Show BuildTreeRefType # |
Instance details Defined in Distribution.Client.IndexUtils Methods showsPrec :: Int -> BuildTreeRefType -> ShowS # show :: BuildTreeRefType -> String # showList :: [BuildTreeRefType] -> ShowS #
Eq BuildTreeRefType # |
Instance details Defined in Distribution.Client.IndexUtils Methods (==) :: BuildTreeRefType -> BuildTreeRefType -> Bool # (/=) :: BuildTreeRefType -> BuildTreeRefType -> Bool #
type Rep BuildTreeRefType # |
Instance details Defined in Distribution.Client.IndexUtils type Rep BuildTreeRefType = D1 ('MetaData "BuildTreeRefType" "Distribution.Client.IndexUtils" "cabal-install-3.12.1.0-G554PkJj2SpDqyarXp9tbt" 'False) (C1 ('MetaCons "SnapshotRef" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "LinkRef" 'PrefixI 'False) (U1 :: Type -> Type))

refTypeFromTypeCode :: TypeCode -> BuildTreeRefType #

typeCodeFromRefType :: BuildTreeRefType -> TypeCode #

# preferred-versions utilities

preferredVersions :: FilePath #

Expected name of the 'preferred-versions' file.

Contains special constraints, such as a preferred version of a package or deprecations of certain package versions.

Expected format:

    binary > 0.9.0.0 || < 0.9.0.0
    text == 1.2.1.0

isPreferredVersions :: FilePath -> Bool #

Does the given filename match with the expected name of 'preferred-versions'?

parsePreferredVersionsWarnings :: ByteString -> [Either PreferredVersionsParseError Dependency] #

Parse `preferred-versions` file, collecting parse errors that can be shown in error messages.

data PreferredVersionsParseError #

Parser error of the `preferred-versions` file.

Constructors

PreferredVersionsParseError |
Fields preferredVersionsParsecError :: String Parser error to show to a user. preferredVersionsOriginalDependency :: String Original input that produced the parser error.

#### Instances

Instances details

Generic PreferredVersionsParseError # |
Instance details Defined in Distribution.Client.IndexUtils Associated Types
type Rep PreferredVersionsParseError |
Instance details Defined in Distribution.Client.IndexUtils type Rep PreferredVersionsParseError = D1 ('MetaData "PreferredVersionsParseError" "Distribution.Client.IndexUtils" "cabal-install-3.12.1.0-G554PkJj2SpDqyarXp9tbt" 'False) (C1 ('MetaCons "PreferredVersionsParseError" 'PrefixI 'True) (S1 ('MetaSel ('Just "preferredVersionsParsecError") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 String) :*: S1 ('MetaSel ('Just "preferredVersionsOriginalDependency") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 String)))
Methods from :: PreferredVersionsParseError -> Rep PreferredVersionsParseError x # to :: Rep PreferredVersionsParseError x -> PreferredVersionsParseError #
Read PreferredVersionsParseError # |
Instance details Defined in Distribution.Client.IndexUtils Methods readsPrec :: Int -> ReadS PreferredVersionsParseError # readList :: ReadS [PreferredVersionsParseError] # readPrec :: ReadPrec PreferredVersionsParseError # readListPrec :: ReadPrec [PreferredVersionsParseError] #
Show PreferredVersionsParseError # |
Instance details Defined in Distribution.Client.IndexUtils Methods showsPrec :: Int -> PreferredVersionsParseError -> ShowS # show :: PreferredVersionsParseError -> String # showList :: [PreferredVersionsParseError] -> ShowS #
Eq PreferredVersionsParseError # |
Instance details Defined in Distribution.Client.IndexUtils Methods (==) :: PreferredVersionsParseError -> PreferredVersionsParseError -> Bool # (/=) :: PreferredVersionsParseError -> PreferredVersionsParseError -> Bool #
Ord PreferredVersionsParseError # |
Instance details Defined in Distribution.Client.IndexUtils Methods compare :: PreferredVersionsParseError -> PreferredVersionsParseError -> Ordering # (<) :: PreferredVersionsParseError -> PreferredVersionsParseError -> Bool # (<=) :: PreferredVersionsParseError -> PreferredVersionsParseError -> Bool # (>) :: PreferredVersionsParseError -> PreferredVersionsParseError -> Bool # (>=) :: PreferredVersionsParseError -> PreferredVersionsParseError -> Bool # max :: PreferredVersionsParseError -> PreferredVersionsParseError -> PreferredVersionsParseError # min :: PreferredVersionsParseError -> PreferredVersionsParseError -> PreferredVersionsParseError #
type Rep PreferredVersionsParseError # |
Instance details Defined in Distribution.Client.IndexUtils type Rep PreferredVersionsParseError = D1 ('MetaData "PreferredVersionsParseError" "Distribution.Client.IndexUtils" "cabal-install-3.12.1.0-G554PkJj2SpDqyarXp9tbt" 'False) (C1 ('MetaCons "PreferredVersionsParseError" 'PrefixI 'True) (S1 ('MetaSel ('Just "preferredVersionsParsecError") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 String) :*: S1 ('MetaSel ('Just "preferredVersionsOriginalDependency") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 String)))