sapling/eden/mononoke/repo_client/unbundle/src/upload_blobs.rs
David Tolnay fe65402e46 rust: Move futures-old rdeps to renamed futures-old
Summary:
In targets that depend on *both* 0.1 and 0.3 futures, this codemod renames the 0.1 dependency to be exposed as futures_old::. This is in preparation for flipping the 0.3 dependencies from futures_preview:: to plain futures::.

rs changes performed by:

```
rg \
    --files-with-matches \
    --type-add buck:TARGETS \
    --type buck \
    --glob '!/experimental' \
    --regexp '(_|\b)rust(_|\b)' \
| sed 's,TARGETS$,:,' \
| xargs \
    -x \
    buck query "labels(srcs,
        rdeps(%Ss, fbsource//third-party/rust:futures-old, 1)
        intersect
        rdeps(%Ss, //common/rust/renamed:futures-preview, 1)
    )" \
| xargs sed -i 's/\bfutures::/futures_old::/'
```

Reviewed By: jsgf

Differential Revision: D20168958

fbshipit-source-id: d2c099f9170c427e542975bc22fd96138a7725b0
2020-03-02 21:02:50 -08:00

109 lines
3.4 KiB
Rust

/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This software may be used and distributed according to the terms of the
* GNU General Public License version 2.
*/
use std::collections::HashMap;
use anyhow::{ensure, Error, Result};
use failure_ext::Compat;
use futures_ext::{BoxFuture, FutureExt};
use futures_old::{future::Shared, Future, Stream};
use blobrepo::BlobRepo;
use context::CoreContext;
use mercurial_revlog::manifest::ManifestContent;
use mercurial_types::{
blobs::{HgBlobEntry, UploadHgNodeHash, UploadHgTreeEntry},
HgNodeHash, HgNodeKey,
};
use mononoke_types::RepoPath;
use wirepack::TreemanifestEntry;
/// Represents data that is Mercurial-encoded and can be uploaded to the blobstore.
pub trait UploadableHgBlob {
type Value: Send + 'static;
fn upload(self, ctx: CoreContext, repo: &BlobRepo) -> Result<(HgNodeKey, Self::Value)>;
}
#[derive(PartialEq, Eq)]
pub enum UploadBlobsType {
IgnoreDuplicates,
EnsureNoDuplicates,
}
use self::UploadBlobsType::*;
pub fn upload_hg_blobs<S, B>(
ctx: CoreContext,
repo: BlobRepo,
blobs: S,
ubtype: UploadBlobsType,
) -> BoxFuture<HashMap<HgNodeKey, B::Value>, Error>
where
S: Stream<Item = B, Error = Error> + Send + 'static,
B: UploadableHgBlob,
{
blobs
.fold(HashMap::new(), move |mut map, item| {
let (key, value) = item.upload(ctx.clone(), &repo)?;
ensure!(
map.insert(key.clone(), value).is_none() || ubtype == IgnoreDuplicates,
"HgBlob {:?} already provided before",
key
);
Ok(map)
})
.boxify()
}
impl UploadableHgBlob for TreemanifestEntry {
// * Shared is required here because a single tree manifest can be referred to by more than
// one changeset, and all of those will want to refer to the corresponding future.
// * The Compat<Error> here is because the error type for Shared (a cloneable wrapper called
// SharedError) doesn't implement Fail, and only implements Error if the wrapped type
// implements Error.
type Value = (
ManifestContent,
Option<HgNodeHash>,
Option<HgNodeHash>,
Shared<BoxFuture<(HgBlobEntry, RepoPath), Compat<Error>>>,
);
fn upload(self, ctx: CoreContext, repo: &BlobRepo) -> Result<(HgNodeKey, Self::Value)> {
let node_key = self.node_key;
let manifest_content = self.manifest_content;
let p1 = self.p1;
let p2 = self.p2;
// The root tree manifest is expected to have the wrong hash in hybrid mode.
// XXX possibly remove this once hybrid mode is gone
let upload_node_id = if node_key.path.is_root() {
UploadHgNodeHash::Supplied(node_key.hash)
} else {
UploadHgNodeHash::Checked(node_key.hash)
};
let upload = UploadHgTreeEntry {
upload_node_id,
contents: self.data,
p1: self.p1,
p2: self.p2,
path: node_key.path.clone(),
};
upload
.upload(ctx, repo.get_blobstore().boxed())
.map(move |(_node, value)| {
(
node_key,
(
manifest_content,
p1,
p2,
value.map_err(Compat).boxify().shared(),
),
)
})
}
}