@@ -130,6 +130,8 @@ import Data.Either
130
130
import Data.List (stripPrefix )
131
131
import qualified Data.Map as Map
132
132
import qualified Data.Set as Set
133
+ import Data.Time (diffUTCTime , getCurrentTime )
134
+ import Data.Time.Clock.POSIX (posixDayLength )
133
135
import Distribution.Client.GZipUtils (maybeDecompress )
134
136
import Distribution.Client.Utils
135
137
( byteStringToFilePath
@@ -321,37 +323,13 @@ getSourcePackagesAtIndexState verbosity repoCtxt mb_idxState mb_activeRepos = do
321
323
return ()
322
324
IndexStateTime ts0 -> do
323
325
when (isiMaxTime isi /= ts0) $
324
- if ts0 > isiMaxTime isi
325
- then
326
- warn verbosity $
327
- " Requested index-state "
328
- ++ prettyShow ts0
329
- ++ " is newer than '"
330
- ++ unRepoName rname
331
- ++ " '!"
332
- ++ " Falling back to older state ("
333
- ++ prettyShow (isiMaxTime isi)
334
- ++ " )."
335
- else
336
- info verbosity $
337
- " Requested index-state "
338
- ++ prettyShow ts0
339
- ++ " does not exist in '"
340
- ++ unRepoName rname
341
- ++ " '!"
342
- ++ " Falling back to older state ("
343
- ++ prettyShow (isiMaxTime isi)
344
- ++ " )."
345
- info
346
- verbosity
347
- ( " index-state("
326
+ info verbosity $
327
+ " There is no index-state for '"
348
328
++ unRepoName rname
349
- ++ " ) = "
329
+ ++ " ' exactly at the requested timestamp ("
330
+ ++ prettyShow ts0
331
+ ++ " ). Falling back to the previous index-state that exists: "
350
332
++ prettyShow (isiMaxTime isi)
351
- ++ " (HEAD = "
352
- ++ prettyShow (isiHeadTime isi)
353
- ++ " )"
354
- )
355
333
356
334
pure
357
335
RepoData
@@ -440,15 +418,19 @@ readRepoIndex
440
418
-> IO (PackageIndex UnresolvedSourcePackage , [Dependency ], IndexStateInfo )
441
419
readRepoIndex verbosity repoCtxt repo idxState =
442
420
handleNotFound $ do
443
- when (isRepoRemote repo) $ warnIfIndexIsOld =<< getIndexFileAge repo
444
421
-- note that if this step fails due to a bad repo cache, the the procedure can still succeed by reading from the existing cache, which is updated regardless.
445
422
updateRepoIndexCache verbosity (RepoIndex repoCtxt repo)
446
423
`catchIO` (\ e -> warn verbosity $ " unable to update the repo index cache -- " ++ displayException e)
447
- readPackageIndexCacheFile
448
- verbosity
449
- mkAvailablePackage
450
- (RepoIndex repoCtxt repo)
451
- idxState
424
+ ret@ (_, _, isi) <-
425
+ readPackageIndexCacheFile
426
+ verbosity
427
+ mkAvailablePackage
428
+ (RepoIndex repoCtxt repo)
429
+ idxState
430
+ when (isRepoRemote repo) $ do
431
+ dieIfRequestedIdxIsNewer isi
432
+ warnIfIndexIsOld isi
433
+ pure ret
452
434
where
453
435
mkAvailablePackage pkgEntry =
454
436
SourcePackage
@@ -480,12 +462,32 @@ readRepoIndex verbosity repoCtxt repo idxState =
480
462
return (mempty , mempty , emptyStateInfo)
481
463
else ioError e
482
464
465
+ isOldThreshold :: Double
483
466
isOldThreshold = 15 -- days
484
- warnIfIndexIsOld dt = do
485
- when (dt >= isOldThreshold) $ case repo of
486
- RepoRemote {.. } -> warn verbosity $ errOutdatedPackageList repoRemote dt
487
- RepoSecure {.. } -> warn verbosity $ errOutdatedPackageList repoRemote dt
488
- RepoLocalNoIndex {} -> return ()
467
+ warnIfIndexIsOld isi = do
468
+ curTime <- getCurrentTime
469
+ case timestampToUTCTime (isiHeadTime isi) of
470
+ Nothing -> pure ()
471
+ Just ts -> do
472
+ let timeDiffInDays =
473
+ realToFrac (curTime `diffUTCTime` ts) / realToFrac posixDayLength
474
+ when (timeDiffInDays >= isOldThreshold) $ case repo of
475
+ RepoRemote {.. } ->
476
+ warn verbosity $ errOutdatedPackageList repoRemote timeDiffInDays
477
+ RepoSecure {.. } ->
478
+ warn verbosity $ errOutdatedPackageList repoRemote timeDiffInDays
479
+ RepoLocalNoIndex {} -> return ()
480
+
481
+ dieIfRequestedIdxIsNewer isi =
482
+ let latestTime = isiHeadTime isi
483
+ in case idxState of
484
+ IndexStateTime t -> when (t > latestTime) $ case repo of
485
+ RepoRemote {.. } ->
486
+ die' verbosity $ errRequestedIdxIsNewer repoRemote latestTime t
487
+ RepoSecure {.. } ->
488
+ die' verbosity $ errRequestedIdxIsNewer repoRemote latestTime t
489
+ RepoLocalNoIndex {} -> return ()
490
+ IndexStateHead -> pure ()
489
491
490
492
errMissingPackageList repoRemote =
491
493
" The package list for '"
@@ -497,6 +499,16 @@ readRepoIndex verbosity repoCtxt repo idxState =
497
499
++ " ' is "
498
500
++ shows (floor dt :: Int ) " days old.\n Run "
499
501
++ " 'cabal update' to get the latest list of available packages."
502
+ errRequestedIdxIsNewer repoRemote maxFound req =
503
+ " Latest known index-state for '"
504
+ ++ unRepoName (remoteRepoName repoRemote)
505
+ ++ " ' ("
506
+ ++ prettyShow maxFound
507
+ ++ " ) is older than the requested index-state ("
508
+ ++ prettyShow req
509
+ ++ " ).\n Run 'cabal update' or set the index-state to a value at or before "
510
+ ++ prettyShow maxFound
511
+ ++ " ."
500
512
501
513
-- | Return the age of the index file in days (as a Double).
502
514
getIndexFileAge :: Repo -> IO Double
0 commit comments