{-# LANGUAGE CPP #-}
module Hackage.Security.Client.Repository (
Metadata
, Binary
, RemoteFile(..)
, CachedFile(..)
, IndexFile(..)
, remoteFileDefaultFormat
, remoteFileDefaultInfo
, Repository(..)
, AttemptNr(..)
, LogMessage(..)
, UpdateFailure(..)
, SomeRemoteError(..)
, DownloadedFile(..)
, mirrorsUnsupported
, remoteRepoPath
, remoteRepoPath'
, IsCached(..)
, mustCache
) where
import Control.Exception
import Data.Typeable (Typeable)
import qualified Codec.Archive.Tar.Index as Tar
import qualified Data.ByteString.Lazy as BS.L
import Distribution.Package
import Distribution.Text
import Hackage.Security.Client.Formats
import Hackage.Security.Client.Verify
import Hackage.Security.Trusted
import Hackage.Security.TUF
import Hackage.Security.Util.Checked
import Hackage.Security.Util.Path
import Hackage.Security.Util.Pretty
import Hackage.Security.Util.Some
import Hackage.Security.Util.Stack
data Metadata
data Binary
data RemoteFile :: * -> * -> * where
RemoteTimestamp :: RemoteFile (FormatUn :- ()) Metadata
RemoteRoot :: Maybe (Trusted FileInfo) -> RemoteFile (FormatUn :- ()) Metadata
RemoteSnapshot :: Trusted FileInfo -> RemoteFile (FormatUn :- ()) Metadata
RemoteMirrors :: Trusted FileInfo -> RemoteFile (FormatUn :- ()) Metadata
RemoteIndex :: HasFormat fs FormatGz
-> Formats fs (Trusted FileInfo)
-> RemoteFile fs Binary
RemotePkgTarGz :: PackageIdentifier
-> Trusted FileInfo
-> RemoteFile (FormatGz :- ()) Binary
deriving instance Show (RemoteFile fs typ)
instance Pretty (RemoteFile fs typ) where
pretty :: RemoteFile fs typ -> String
pretty RemoteTimestamp = "timestamp"
pretty (RemoteRoot _) = "root"
pretty (RemoteSnapshot _) = "snapshot"
pretty (RemoteMirrors _) = "mirrors"
pretty (RemoteIndex _ _) = "index"
pretty (RemotePkgTarGz pkgId :: PackageIdentifier
pkgId _) = "package " String -> ShowS
forall a. [a] -> [a] -> [a]
++ PackageIdentifier -> String
forall a. Pretty a => a -> String
display PackageIdentifier
pkgId
data CachedFile =
CachedTimestamp
| CachedRoot
| CachedSnapshot
| CachedMirrors
deriving (CachedFile -> CachedFile -> Bool
(CachedFile -> CachedFile -> Bool)
-> (CachedFile -> CachedFile -> Bool) -> Eq CachedFile
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CachedFile -> CachedFile -> Bool
$c/= :: CachedFile -> CachedFile -> Bool
== :: CachedFile -> CachedFile -> Bool
$c== :: CachedFile -> CachedFile -> Bool
Eq, Eq CachedFile
Eq CachedFile =>
(CachedFile -> CachedFile -> Ordering)
-> (CachedFile -> CachedFile -> Bool)
-> (CachedFile -> CachedFile -> Bool)
-> (CachedFile -> CachedFile -> Bool)
-> (CachedFile -> CachedFile -> Bool)
-> (CachedFile -> CachedFile -> CachedFile)
-> (CachedFile -> CachedFile -> CachedFile)
-> Ord CachedFile
CachedFile -> CachedFile -> Bool
CachedFile -> CachedFile -> Ordering
CachedFile -> CachedFile -> CachedFile
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: CachedFile -> CachedFile -> CachedFile
$cmin :: CachedFile -> CachedFile -> CachedFile
max :: CachedFile -> CachedFile -> CachedFile
$cmax :: CachedFile -> CachedFile -> CachedFile
>= :: CachedFile -> CachedFile -> Bool
$c>= :: CachedFile -> CachedFile -> Bool
> :: CachedFile -> CachedFile -> Bool
$c> :: CachedFile -> CachedFile -> Bool
<= :: CachedFile -> CachedFile -> Bool
$c<= :: CachedFile -> CachedFile -> Bool
< :: CachedFile -> CachedFile -> Bool
$c< :: CachedFile -> CachedFile -> Bool
compare :: CachedFile -> CachedFile -> Ordering
$ccompare :: CachedFile -> CachedFile -> Ordering
$cp1Ord :: Eq CachedFile
Ord, Int -> CachedFile -> ShowS
[CachedFile] -> ShowS
CachedFile -> String
(Int -> CachedFile -> ShowS)
-> (CachedFile -> String)
-> ([CachedFile] -> ShowS)
-> Show CachedFile
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CachedFile] -> ShowS
$cshowList :: [CachedFile] -> ShowS
show :: CachedFile -> String
$cshow :: CachedFile -> String
showsPrec :: Int -> CachedFile -> ShowS
$cshowsPrec :: Int -> CachedFile -> ShowS
Show)
instance Pretty CachedFile where
pretty :: CachedFile -> String
pretty CachedTimestamp = "timestamp"
pretty CachedRoot = "root"
pretty CachedSnapshot = "snapshot"
pretty CachedMirrors = "mirrors"
remoteFileDefaultFormat :: RemoteFile fs typ -> Some (HasFormat fs)
remoteFileDefaultFormat :: RemoteFile fs typ -> Some (HasFormat fs)
remoteFileDefaultFormat RemoteTimestamp = HasFormat (FormatUn :- ()) FormatUn -> Some (HasFormat fs)
forall (f :: * -> *) a. f a -> Some f
Some (HasFormat (FormatUn :- ()) FormatUn -> Some (HasFormat fs))
-> HasFormat (FormatUn :- ()) FormatUn -> Some (HasFormat fs)
forall a b. (a -> b) -> a -> b
$ Format FormatUn -> HasFormat (FormatUn :- ()) FormatUn
forall f fs. Format f -> HasFormat (f :- fs) f
HFZ Format FormatUn
FUn
remoteFileDefaultFormat (RemoteRoot _) = HasFormat (FormatUn :- ()) FormatUn -> Some (HasFormat fs)
forall (f :: * -> *) a. f a -> Some f
Some (HasFormat (FormatUn :- ()) FormatUn -> Some (HasFormat fs))
-> HasFormat (FormatUn :- ()) FormatUn -> Some (HasFormat fs)
forall a b. (a -> b) -> a -> b
$ Format FormatUn -> HasFormat (FormatUn :- ()) FormatUn
forall f fs. Format f -> HasFormat (f :- fs) f
HFZ Format FormatUn
FUn
remoteFileDefaultFormat (RemoteSnapshot _) = HasFormat (FormatUn :- ()) FormatUn -> Some (HasFormat fs)
forall (f :: * -> *) a. f a -> Some f
Some (HasFormat (FormatUn :- ()) FormatUn -> Some (HasFormat fs))
-> HasFormat (FormatUn :- ()) FormatUn -> Some (HasFormat fs)
forall a b. (a -> b) -> a -> b
$ Format FormatUn -> HasFormat (FormatUn :- ()) FormatUn
forall f fs. Format f -> HasFormat (f :- fs) f
HFZ Format FormatUn
FUn
remoteFileDefaultFormat (RemoteMirrors _) = HasFormat (FormatUn :- ()) FormatUn -> Some (HasFormat fs)
forall (f :: * -> *) a. f a -> Some f
Some (HasFormat (FormatUn :- ()) FormatUn -> Some (HasFormat fs))
-> HasFormat (FormatUn :- ()) FormatUn -> Some (HasFormat fs)
forall a b. (a -> b) -> a -> b
$ Format FormatUn -> HasFormat (FormatUn :- ()) FormatUn
forall f fs. Format f -> HasFormat (f :- fs) f
HFZ Format FormatUn
FUn
remoteFileDefaultFormat (RemotePkgTarGz _ _) = HasFormat (FormatGz :- ()) FormatGz -> Some (HasFormat fs)
forall (f :: * -> *) a. f a -> Some f
Some (HasFormat (FormatGz :- ()) FormatGz -> Some (HasFormat fs))
-> HasFormat (FormatGz :- ()) FormatGz -> Some (HasFormat fs)
forall a b. (a -> b) -> a -> b
$ Format FormatGz -> HasFormat (FormatGz :- ()) FormatGz
forall f fs. Format f -> HasFormat (f :- fs) f
HFZ Format FormatGz
FGz
remoteFileDefaultFormat (RemoteIndex pf :: HasFormat fs FormatGz
pf _) = HasFormat fs FormatGz -> Some (HasFormat fs)
forall (f :: * -> *) a. f a -> Some f
Some HasFormat fs FormatGz
pf
remoteFileDefaultInfo :: RemoteFile fs typ -> Maybe (Trusted FileInfo)
remoteFileDefaultInfo :: RemoteFile fs typ -> Maybe (Trusted FileInfo)
remoteFileDefaultInfo RemoteTimestamp = Maybe (Trusted FileInfo)
forall a. Maybe a
Nothing
remoteFileDefaultInfo (RemoteRoot info :: Maybe (Trusted FileInfo)
info) = Maybe (Trusted FileInfo)
info
remoteFileDefaultInfo (RemoteSnapshot info :: Trusted FileInfo
info) = Trusted FileInfo -> Maybe (Trusted FileInfo)
forall a. a -> Maybe a
Just Trusted FileInfo
info
remoteFileDefaultInfo (RemoteMirrors info :: Trusted FileInfo
info) = Trusted FileInfo -> Maybe (Trusted FileInfo)
forall a. a -> Maybe a
Just Trusted FileInfo
info
remoteFileDefaultInfo (RemotePkgTarGz _ info :: Trusted FileInfo
info) = Trusted FileInfo -> Maybe (Trusted FileInfo)
forall a. a -> Maybe a
Just Trusted FileInfo
info
remoteFileDefaultInfo (RemoteIndex pf :: HasFormat fs FormatGz
pf info :: Formats fs (Trusted FileInfo)
info) = Trusted FileInfo -> Maybe (Trusted FileInfo)
forall a. a -> Maybe a
Just (Trusted FileInfo -> Maybe (Trusted FileInfo))
-> Trusted FileInfo -> Maybe (Trusted FileInfo)
forall a b. (a -> b) -> a -> b
$ HasFormat fs FormatGz
-> Formats fs (Trusted FileInfo) -> Trusted FileInfo
forall fs f a. HasFormat fs f -> Formats fs a -> a
formatsLookup HasFormat fs FormatGz
pf Formats fs (Trusted FileInfo)
info
data Repository down = DownloadedFile down => Repository {
Repository down
-> forall fs typ.
Throws SomeRemoteError =>
AttemptNr
-> RemoteFile fs typ -> Verify (Some (HasFormat fs), down typ)
repGetRemote :: forall fs typ. Throws SomeRemoteError
=> AttemptNr
-> RemoteFile fs typ
-> Verify (Some (HasFormat fs), down typ)
, Repository down -> CachedFile -> IO (Maybe (Path Absolute))
repGetCached :: CachedFile -> IO (Maybe (Path Absolute))
, Repository down -> IO (Path Absolute)
repGetCachedRoot :: IO (Path Absolute)
, Repository down -> IO ()
repClearCache :: IO ()
, Repository down -> forall a. (Handle -> IO a) -> IO a
repWithIndex :: forall a. (Handle -> IO a) -> IO a
, Repository down -> IO TarIndex
repGetIndexIdx :: IO Tar.TarIndex
, Repository down -> IO () -> IO ()
repLockCache :: IO () -> IO ()
, Repository down -> forall a. Maybe [Mirror] -> IO a -> IO a
repWithMirror :: forall a. Maybe [Mirror] -> IO a -> IO a
, Repository down -> LogMessage -> IO ()
repLog :: LogMessage -> IO ()
, Repository down -> RepoLayout
repLayout :: RepoLayout
, Repository down -> IndexLayout
repIndexLayout :: IndexLayout
, Repository down -> String
repDescription :: String
}
instance Show (Repository down) where
show :: Repository down -> String
show = Repository down -> String
forall (down :: * -> *). Repository down -> String
repDescription
mirrorsUnsupported :: Maybe [Mirror] -> IO a -> IO a
mirrorsUnsupported :: Maybe [Mirror] -> IO a -> IO a
mirrorsUnsupported _ = IO a -> IO a
forall a. a -> a
id
newtype AttemptNr = AttemptNr Int
deriving (AttemptNr -> AttemptNr -> Bool
(AttemptNr -> AttemptNr -> Bool)
-> (AttemptNr -> AttemptNr -> Bool) -> Eq AttemptNr
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: AttemptNr -> AttemptNr -> Bool
$c/= :: AttemptNr -> AttemptNr -> Bool
== :: AttemptNr -> AttemptNr -> Bool
$c== :: AttemptNr -> AttemptNr -> Bool
Eq, Eq AttemptNr
Eq AttemptNr =>
(AttemptNr -> AttemptNr -> Ordering)
-> (AttemptNr -> AttemptNr -> Bool)
-> (AttemptNr -> AttemptNr -> Bool)
-> (AttemptNr -> AttemptNr -> Bool)
-> (AttemptNr -> AttemptNr -> Bool)
-> (AttemptNr -> AttemptNr -> AttemptNr)
-> (AttemptNr -> AttemptNr -> AttemptNr)
-> Ord AttemptNr
AttemptNr -> AttemptNr -> Bool
AttemptNr -> AttemptNr -> Ordering
AttemptNr -> AttemptNr -> AttemptNr
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: AttemptNr -> AttemptNr -> AttemptNr
$cmin :: AttemptNr -> AttemptNr -> AttemptNr
max :: AttemptNr -> AttemptNr -> AttemptNr
$cmax :: AttemptNr -> AttemptNr -> AttemptNr
>= :: AttemptNr -> AttemptNr -> Bool
$c>= :: AttemptNr -> AttemptNr -> Bool
> :: AttemptNr -> AttemptNr -> Bool
$c> :: AttemptNr -> AttemptNr -> Bool
<= :: AttemptNr -> AttemptNr -> Bool
$c<= :: AttemptNr -> AttemptNr -> Bool
< :: AttemptNr -> AttemptNr -> Bool
$c< :: AttemptNr -> AttemptNr -> Bool
compare :: AttemptNr -> AttemptNr -> Ordering
$ccompare :: AttemptNr -> AttemptNr -> Ordering
$cp1Ord :: Eq AttemptNr
Ord, Integer -> AttemptNr
AttemptNr -> AttemptNr
AttemptNr -> AttemptNr -> AttemptNr
(AttemptNr -> AttemptNr -> AttemptNr)
-> (AttemptNr -> AttemptNr -> AttemptNr)
-> (AttemptNr -> AttemptNr -> AttemptNr)
-> (AttemptNr -> AttemptNr)
-> (AttemptNr -> AttemptNr)
-> (AttemptNr -> AttemptNr)
-> (Integer -> AttemptNr)
-> Num AttemptNr
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
fromInteger :: Integer -> AttemptNr
$cfromInteger :: Integer -> AttemptNr
signum :: AttemptNr -> AttemptNr
$csignum :: AttemptNr -> AttemptNr
abs :: AttemptNr -> AttemptNr
$cabs :: AttemptNr -> AttemptNr
negate :: AttemptNr -> AttemptNr
$cnegate :: AttemptNr -> AttemptNr
* :: AttemptNr -> AttemptNr -> AttemptNr
$c* :: AttemptNr -> AttemptNr -> AttemptNr
- :: AttemptNr -> AttemptNr -> AttemptNr
$c- :: AttemptNr -> AttemptNr -> AttemptNr
+ :: AttemptNr -> AttemptNr -> AttemptNr
$c+ :: AttemptNr -> AttemptNr -> AttemptNr
Num)
data LogMessage =
LogRootUpdated
| LogVerificationError VerificationError
| forall fs typ. LogDownloading (RemoteFile fs typ)
| forall fs. LogUpdating (RemoteFile fs Binary)
| LogSelectedMirror MirrorDescription
| forall fs. LogCannotUpdate (RemoteFile fs Binary) UpdateFailure
| LogMirrorFailed MirrorDescription SomeException
| LogLockWait (Path Absolute)
| LogLockWaitDone (Path Absolute)
| LogUnlock (Path Absolute)
data UpdateFailure =
UpdateImpossibleUnsupported
| UpdateImpossibleNoLocalCopy
| UpdateFailedTwice
| UpdateFailed SomeException
class DownloadedFile (down :: * -> *) where
downloadedVerify :: down a -> Trusted FileInfo -> IO Bool
downloadedRead :: down Metadata -> IO BS.L.ByteString
downloadedCopyTo :: down a -> Path Absolute -> IO ()
data SomeRemoteError :: * where
SomeRemoteError :: Exception e => e -> SomeRemoteError
deriving (Typeable)
#if MIN_VERSION_base(4,8,0)
deriving instance Show SomeRemoteError
instance Exception SomeRemoteError where displayException :: SomeRemoteError -> String
displayException = SomeRemoteError -> String
forall a. Pretty a => a -> String
pretty
#else
instance Exception SomeRemoteError
instance Show SomeRemoteError where show = pretty
#endif
instance Pretty SomeRemoteError where
pretty :: SomeRemoteError -> String
pretty (SomeRemoteError ex :: e
ex) = e -> String
forall e. Exception e => e -> String
displayException e
ex
remoteRepoPath :: RepoLayout -> RemoteFile fs typ -> Formats fs RepoPath
remoteRepoPath :: RepoLayout -> RemoteFile fs typ -> Formats fs RepoPath
remoteRepoPath RepoLayout{..} = RemoteFile fs typ -> Formats fs RepoPath
forall fs typ. RemoteFile fs typ -> Formats fs RepoPath
go
where
go :: RemoteFile fs typ -> Formats fs RepoPath
go :: RemoteFile fs typ -> Formats fs RepoPath
go RemoteTimestamp = RepoPath -> Formats fs RepoPath
forall a. a -> Formats (FormatUn :- ()) a
FsUn (RepoPath -> Formats fs RepoPath)
-> RepoPath -> Formats fs RepoPath
forall a b. (a -> b) -> a -> b
$ RepoPath
repoLayoutTimestamp
go (RemoteRoot _) = RepoPath -> Formats fs RepoPath
forall a. a -> Formats (FormatUn :- ()) a
FsUn (RepoPath -> Formats fs RepoPath)
-> RepoPath -> Formats fs RepoPath
forall a b. (a -> b) -> a -> b
$ RepoPath
repoLayoutRoot
go (RemoteSnapshot _) = RepoPath -> Formats fs RepoPath
forall a. a -> Formats (FormatUn :- ()) a
FsUn (RepoPath -> Formats fs RepoPath)
-> RepoPath -> Formats fs RepoPath
forall a b. (a -> b) -> a -> b
$ RepoPath
repoLayoutSnapshot
go (RemoteMirrors _) = RepoPath -> Formats fs RepoPath
forall a. a -> Formats (FormatUn :- ()) a
FsUn (RepoPath -> Formats fs RepoPath)
-> RepoPath -> Formats fs RepoPath
forall a b. (a -> b) -> a -> b
$ RepoPath
repoLayoutMirrors
go (RemotePkgTarGz pId :: PackageIdentifier
pId _) = RepoPath -> Formats fs RepoPath
forall a. a -> Formats (FormatGz :- ()) a
FsGz (RepoPath -> Formats fs RepoPath)
-> RepoPath -> Formats fs RepoPath
forall a b. (a -> b) -> a -> b
$ PackageIdentifier -> RepoPath
repoLayoutPkgTarGz PackageIdentifier
pId
go (RemoteIndex _ lens :: Formats fs (Trusted FileInfo)
lens) = (forall f. Format f -> Trusted FileInfo -> RepoPath)
-> Formats fs (Trusted FileInfo) -> Formats fs RepoPath
forall a b fs.
(forall f. Format f -> a -> b) -> Formats fs a -> Formats fs b
formatsMap forall f. Format f -> Trusted FileInfo -> RepoPath
forall f a. Format f -> a -> RepoPath
goIndex Formats fs (Trusted FileInfo)
lens
goIndex :: Format f -> a -> RepoPath
goIndex :: Format f -> a -> RepoPath
goIndex FUn _ = RepoPath
repoLayoutIndexTar
goIndex FGz _ = RepoPath
repoLayoutIndexTarGz
remoteRepoPath' :: RepoLayout -> RemoteFile fs typ -> HasFormat fs f -> RepoPath
remoteRepoPath' :: RepoLayout -> RemoteFile fs typ -> HasFormat fs f -> RepoPath
remoteRepoPath' repoLayout :: RepoLayout
repoLayout file :: RemoteFile fs typ
file format :: HasFormat fs f
format =
HasFormat fs f -> Formats fs RepoPath -> RepoPath
forall fs f a. HasFormat fs f -> Formats fs a -> a
formatsLookup HasFormat fs f
format (Formats fs RepoPath -> RepoPath)
-> Formats fs RepoPath -> RepoPath
forall a b. (a -> b) -> a -> b
$ RepoLayout -> RemoteFile fs typ -> Formats fs RepoPath
forall fs typ.
RepoLayout -> RemoteFile fs typ -> Formats fs RepoPath
remoteRepoPath RepoLayout
repoLayout RemoteFile fs typ
file
data IsCached :: * -> * where
CacheAs :: CachedFile -> IsCached Metadata
DontCache :: IsCached Binary
CacheIndex :: IsCached Binary
deriving instance Eq (IsCached typ)
deriving instance Show (IsCached typ)
mustCache :: RemoteFile fs typ -> IsCached typ
mustCache :: RemoteFile fs typ -> IsCached typ
mustCache RemoteTimestamp = CachedFile -> IsCached Metadata
CacheAs CachedFile
CachedTimestamp
mustCache (RemoteRoot _) = CachedFile -> IsCached Metadata
CacheAs CachedFile
CachedRoot
mustCache (RemoteSnapshot _) = CachedFile -> IsCached Metadata
CacheAs CachedFile
CachedSnapshot
mustCache (RemoteMirrors _) = CachedFile -> IsCached Metadata
CacheAs CachedFile
CachedMirrors
mustCache (RemoteIndex {}) = IsCached typ
IsCached Binary
CacheIndex
mustCache (RemotePkgTarGz _ _) = IsCached typ
IsCached Binary
DontCache
instance Pretty LogMessage where
pretty :: LogMessage -> String
pretty LogRootUpdated =
"Root info updated"
pretty (LogVerificationError err :: VerificationError
err) =
"Verification error: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ VerificationError -> String
forall a. Pretty a => a -> String
pretty VerificationError
err
pretty (LogDownloading file :: RemoteFile fs typ
file) =
"Downloading " String -> ShowS
forall a. [a] -> [a] -> [a]
++ RemoteFile fs typ -> String
forall a. Pretty a => a -> String
pretty RemoteFile fs typ
file
pretty (LogUpdating file :: RemoteFile fs Binary
file) =
"Updating " String -> ShowS
forall a. [a] -> [a] -> [a]
++ RemoteFile fs Binary -> String
forall a. Pretty a => a -> String
pretty RemoteFile fs Binary
file
pretty (LogSelectedMirror mirror :: String
mirror) =
"Selected mirror " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
mirror
pretty (LogCannotUpdate file :: RemoteFile fs Binary
file ex :: UpdateFailure
ex) =
"Cannot update " String -> ShowS
forall a. [a] -> [a] -> [a]
++ RemoteFile fs Binary -> String
forall a. Pretty a => a -> String
pretty RemoteFile fs Binary
file String -> ShowS
forall a. [a] -> [a] -> [a]
++ " (" String -> ShowS
forall a. [a] -> [a] -> [a]
++ UpdateFailure -> String
forall a. Pretty a => a -> String
pretty UpdateFailure
ex String -> ShowS
forall a. [a] -> [a] -> [a]
++ ")"
pretty (LogMirrorFailed mirror :: String
mirror ex :: SomeException
ex) =
"Exception " String -> ShowS
forall a. [a] -> [a] -> [a]
++ SomeException -> String
forall e. Exception e => e -> String
displayException SomeException
ex String -> ShowS
forall a. [a] -> [a] -> [a]
++ " when using mirror " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
mirror
pretty (LogLockWait file :: Path Absolute
file) =
"Waiting to acquire cache lock on " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Path Absolute -> String
forall a. Pretty a => a -> String
pretty Path Absolute
file
pretty (LogLockWaitDone file :: Path Absolute
file) =
"Acquired cache lock on " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Path Absolute -> String
forall a. Pretty a => a -> String
pretty Path Absolute
file
pretty (LogUnlock file :: Path Absolute
file) =
"Released cache lock on " String -> ShowS
forall a. [a] -> [a] -> [a]
++ Path Absolute -> String
forall a. Pretty a => a -> String
pretty Path Absolute
file
instance Pretty UpdateFailure where
pretty :: UpdateFailure -> String
pretty UpdateImpossibleUnsupported =
"server does not provide incremental downloads"
pretty UpdateImpossibleNoLocalCopy =
"no local copy"
pretty UpdateFailedTwice =
"update failed twice"
pretty (UpdateFailed ex :: SomeException
ex) =
SomeException -> String
forall e. Exception e => e -> String
displayException SomeException
ex