packages feed

cabal-cache 1.0.0.6 → 1.0.0.7

raw patch · 3 files changed

+48/−40 lines, 3 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

+ HaskellWorks.CabalCache.IO.Lazy: readFirstAvailableResource :: (MonadResource m, MonadCatch m) => Env -> [Location] -> m (Either AppError (ByteString, Location))
- HaskellWorks.CabalCache.IO.Lazy: readResource :: MonadResource m => Env -> Location -> m (Maybe ByteString)
+ HaskellWorks.CabalCache.IO.Lazy: readResource :: (MonadResource m, MonadCatch m) => Env -> Location -> m (Either AppError ByteString)

Files

cabal-cache.cabal view
@@ -1,7 +1,7 @@ cabal-version:          2.2  name:                   cabal-cache-version:                1.0.0.6+version:                1.0.0.7 synopsis:               CI Assistant for Haskell projects description:            CI Assistant for Haskell projects.  Implements package caching. homepage:               https://github.com/haskell-works/cabal-cache
src/App/Commands/SyncFromArchive.hs view
@@ -155,41 +155,27 @@                   return True                 else if storeDirectoryExists                   then return True-                  else do-                    maybeExistingArchiveFile <- IO.firstExistingResource envAws [scopedArchiveFile, archiveFile]-                    case maybeExistingArchiveFile of-                      Just existingArchiveFile -> do-                        CIO.putStrLn $ "Extracting: " <> toText existingArchiveFile-                        runResAws envAws $ onErrorClean packageStorePath False $ do-                          maybeArchiveFileContents <- IO.readResource envAws existingArchiveFile+                  else runResAws envAws $ onError (cleanupStorePath packageStorePath packageId) False $ do+                    (existingArchiveFileContents, existingArchiveFile) <- ExceptT $ IO.readFirstAvailableResource envAws [scopedArchiveFile, archiveFile]+                    CIO.putStrLn $ "Extracting: " <> toText existingArchiveFile -                          case maybeArchiveFileContents of-                            Just archiveFileContents -> do-                              existingArchiveFileContents <- IO.readResource envAws existingArchiveFile & maybeToExceptM (GenericAppError ("Archive unavailable: " <> toText archiveFile))-                              let tempArchiveFile = tempPath </> archiveBaseName-                              liftIO $ LBS.writeFile tempArchiveFile existingArchiveFileContents-                              IO.extractTar tempArchiveFile storePath+                    let tempArchiveFile = tempPath </> archiveBaseName+                    liftIO $ LBS.writeFile tempArchiveFile existingArchiveFileContents+                    IO.extractTar tempArchiveFile storePath -                              meta <- loadMetadata packageStorePath-                              oldStorePath <- maybeToExcept "store-path is missing from Metadata" (Map.lookup "store-path" meta)+                    meta <- loadMetadata packageStorePath+                    oldStorePath <- maybeToExcept "store-path is missing from Metadata" (Map.lookup "store-path" meta) -                              case confPath pInfo of-                                Tagged conf _ -> do-                                  let theConfPath = storePath </> conf-                                  let tempConfPath = tempPath </> conf-                                  confPathExists <- liftIO $ IO.doesFileExist theConfPath-                                  when confPathExists $ do-                                    confContents <- liftIO $ LBS.readFile theConfPath-                                    liftIO $ LBS.writeFile tempConfPath (replace (LBS.toStrict oldStorePath) (C8.pack storePath) confContents)-                                    liftIO $ IO.renamePath tempConfPath theConfPath-                                  return True-                            Nothing -> do-                              CIO.putStrLn $ "Archive unavailable: " <> toText existingArchiveFile-                              deleteMetadata packageStorePath-                              return False-                      Nothing -> do-                        CIO.hPutStrLn IO.stderr $ "Warning: Sync failure: " <> packageId-                        return False+                    case confPath pInfo of+                      Tagged conf _ -> do+                        let theConfPath = storePath </> conf+                        let tempConfPath = tempPath </> conf+                        confPathExists <- liftIO $ IO.doesFileExist theConfPath+                        when confPathExists $ do+                          confContents <- liftIO $ LBS.readFile theConfPath+                          liftIO $ LBS.writeFile tempConfPath (replace (LBS.toStrict oldStorePath) (C8.pack storePath) confContents)+                          liftIO $ IO.renamePath tempConfPath theConfPath+                        return True           Nothing -> do             CIO.hPutStrLn IO.stderr $ "Warning: Invalid package id: " <> packageId             return True@@ -208,13 +194,21 @@    return () -onErrorClean :: MonadIO m => FilePath -> a -> ExceptT AppError m a -> m a-onErrorClean pkgStorePath failureValue f = do+cleanupStorePath :: MonadIO m => FilePath -> Z.PackageId -> AppError -> m ()+cleanupStorePath packageStorePath packageId e = do+  CIO.hPutStrLn IO.stderr $ "Warning: Sync failure: " <> packageId+  deleteStorePath packageStorePath++deleteStorePath :: MonadIO m => FilePath -> m ()+deleteStorePath pkgStorePath = liftIO (IO.removeDirectoryRecursive pkgStorePath)++onError :: MonadIO m => (AppError -> m ()) -> a -> ExceptT AppError m a -> m a+onError h failureValue f = do   result <- runExceptT $ catchError (exceptWarn f) handler   case result of     Left a  -> return failureValue     Right a -> return a-  where handler e = liftIO (IO.removeDirectoryRecursive pkgStorePath) >> return failureValue+  where handler e = lift (h e) >> return failureValue  cmdSyncFromArchive :: Mod CommandFields (IO ()) cmdSyncFromArchive = command "sync-from-archive"  $ flip info idm $ runSyncFromArchive <$> optsSyncFromArchive
src/HaskellWorks/CabalCache/IO/Lazy.hs view
@@ -3,6 +3,7 @@ {-# LANGUAGE ScopedTypeVariables #-} module HaskellWorks.CabalCache.IO.Lazy   ( readResource+  , readFirstAvailableResource   , resourceExists   , firstExistingResource   , headS3Uri@@ -72,11 +73,24 @@       _                               -> return (Left (GenericAppError (tshow e)))     _                                 -> throwM e -readResource :: MonadResource m => AWS.Env -> Location -> m (Maybe LBS.ByteString)+getS3Uri :: (MonadResource m, MonadCatch m) => AWS.Env -> AWS.S3Uri -> m (Either AppError LBS.ByteString)+getS3Uri envAws (AWS.S3Uri b k) = handleAwsError $ runAws envAws $ AWS.unsafeDownload b k++readResource :: (MonadResource m, MonadCatch m) => AWS.Env -> Location -> m (Either AppError LBS.ByteString) readResource envAws = \case-  S3 s3Uri        -> runAws envAws $ AWS.downloadFromS3Uri s3Uri-  Local path      -> liftIO $ Just          <$> LBS.readFile path-  HttpUri httpUri -> liftIO $ rightToMaybe  <$> readHttpUri httpUri+  S3 s3Uri        -> getS3Uri envAws s3Uri+  Local path      -> liftIO $ Right <$> LBS.readFile path+  HttpUri httpUri -> liftIO $ readHttpUri httpUri++readFirstAvailableResource :: (MonadResource m, MonadCatch m) => AWS.Env -> [Location] -> m (Either AppError (LBS.ByteString, Location))+readFirstAvailableResource envAws [] = return (Left (GenericAppError "No resources specified in read"))+readFirstAvailableResource envAws (a:as) = do+  result <- readResource envAws a+  case result of+    Right lbs -> return $ Right (lbs, a)+    Left e -> if null as+      then return $ Left e+      else readFirstAvailableResource envAws as  safePathIsSymbolLink :: FilePath -> IO Bool safePathIsSymbolLink filePath = catch (IO.pathIsSymbolicLink filePath) handler