module ContentStore.Bundle ( packBundleFromStore , unpackBundleToStore ) where import ContentStore.Arboricx import ContentStore.Object import Wire import Control.Monad (forM) import Data.ByteString (ByteString) import Data.Text (Text) import qualified Data.Vector as V -- | Pack named CAS tree terms into an indexed Arboricx transport bundle. packBundleFromStore :: StorePath -> [(Text, ObjectHash)] -> IO Bundle packBundleFromStore store exports = do terms <- forM exports $ \(name, root) -> do mt <- getTreeTerm store root case mt of Nothing -> fail $ "CAS tree term not found: " ++ show root Just term -> return (name, term) return (buildBundle terms) -- | Unpack an indexed Arboricx transport bundle into CAS tree terms. -- Returns each manifest export name paired with its stored CAS tree-term hash. unpackBundleToStore :: StorePath -> ByteString -> IO [(Text, ObjectHash)] unpackBundleToStore store bs = case decodeBundle bs of Left err -> fail $ "ContentStore.Bundle.unpackBundleToStore decode: " ++ err Right bundle -> case verifyBundle bundle of Left err -> fail $ "ContentStore.Bundle.unpackBundleToStore verify: " ++ err Right () -> do let terms = reconstructBundleTerms (bundleNodes bundle) forM (manifestExports $ bundleManifest bundle) $ \exported -> do let term = terms V.! fromIntegral (exportRoot exported) root <- putTreeTerm store term return (exportName exported, root)