edenapi_types: move EdenAPI types into separate crate

Summary:
Several of the structs used by EdenAPI were previously defined in Mercurial's
`types` crate. This is not ideal since these structs are used for data interchange
between the client and server, and changes to them can break Mononoke, Mercurial,
or both. As such, they are more fragile than other types and their use should be
limited to the EdenAPI server and client to avoid the need for extensive breaking
changes or costly refactors down the line.

I'm about to make a series of breaking changes to these types as part of the
migration to the new EdenAPI server, so this seemed like an ideal time to split
these types into their own crate.

Reviewed By: krallin

Differential Revision: D21857425

fbshipit-source-id: 82dedc4a2d597532e58072267d8a3368c3d5c9e7
This commit is contained in:
Arun Kulshreshtha 2020-06-09 17:22:48 -07:00 committed by Facebook GitHub Bot
parent 335f5d6ebc
commit cde0436ca9
29 changed files with 89 additions and 56 deletions

View File

@ -18,7 +18,7 @@ use apiserver_thrift::types::{
MononokeGetTreeParams, MononokeIsAncestorParams, MononokeListDirectoryParams,
MononokeListDirectoryUnodesParams, MononokeRevision,
};
use types::api::{DataRequest, HistoryRequest, TreeRequest};
use edenapi_types::{DataRequest, HistoryRequest, TreeRequest};
#[derive(Debug, Clone, Serialize)]
pub enum Revision {

View File

@ -42,6 +42,10 @@ use time_ext::DurationExt;
use tokio_compat::runtime::TaskExecutor;
use unodes::RootUnodeManifestId;
use edenapi_types::{
DataEntry, DataRequest, DataResponse, HistoryRequest, HistoryResponse, TreeRequest,
WireHistoryEntry,
};
use mercurial_types::{
blobs::{HgBlobChangeset, HgBlobEntry},
fetch_manifest_envelope,
@ -53,10 +57,7 @@ use metaconfig_types::{
};
use scuba_ext::{ScubaSampleBuilder, ScubaSampleBuilderExt};
use stats::prelude::*;
use types::{
api::{DataRequest, DataResponse, HistoryRequest, HistoryResponse, TreeRequest},
DataEntry, Key, RepoPathBuf, WireHistoryEntry,
};
use types::{Key, RepoPathBuf};
use warm_bookmarks_cache::WarmBookmarksCache;
use mononoke_types::{ChangesetId, FileUnodeId, MPath, ManifestUnodeId};

View File

@ -16,10 +16,8 @@ use serde::{Deserialize, Serialize};
use tokio::{self, sync::mpsc};
use tokio_compat::runtime::TaskExecutor;
use types::{
api::{DataResponse, HistoryResponse},
DataEntry, RepoPathBuf, WireHistoryEntry,
};
use edenapi_types::{DataEntry, DataResponse, HistoryResponse, WireHistoryEntry};
use types::RepoPathBuf;
use super::file_stream::FileStream;
use super::model::{Changeset, Entry, EntryLight, EntryWithSizeAndContentHash};

View File

@ -10,6 +10,7 @@ include = ["src/**/*.rs"]
blobrepo_factory = { path = "../blobrepo/factory" }
cmdlib = { path = "../cmdlib" }
context = { path = "../server/context" }
edenapi_types = { path = "../../scm/lib/edenapi/types" }
gotham_ext = { path = "../gotham_ext" }
mercurial_types = { path = "../mercurial/types" }
mononoke_api = { path = "../mononoke_api" }

View File

@ -12,13 +12,11 @@ use gotham::state::{FromState, State};
use gotham_derive::{StateData, StaticResponseExtender};
use serde::Deserialize;
use edenapi_types::{DataEntry, DataRequest, DataResponse};
use gotham_ext::{error::HttpError, response::BytesBody};
use mercurial_types::HgNodeHash;
use mononoke_api::hg::{HgDataContext, HgDataId, HgRepoContext};
use types::{
api::{DataRequest, DataResponse},
DataEntry, Key,
};
use types::Key;
use crate::context::ServerContext;
use crate::middleware::RequestContext;

View File

@ -17,14 +17,12 @@ use gotham::state::{FromState, State};
use gotham_derive::{StateData, StaticResponseExtender};
use serde::Deserialize;
use edenapi_types::{HistoryRequest, HistoryResponse, WireHistoryEntry};
use gotham_ext::{error::HttpError, response::BytesBody};
use mercurial_types::{HgFileNodeId, HgNodeHash};
use mononoke_api::hg::HgRepoContext;
use mononoke_types::MPath;
use types::{
api::{HistoryRequest, HistoryResponse},
Key, WireHistoryEntry,
};
use types::Key;
use crate::context::ServerContext;
use crate::middleware::RequestContext;

View File

@ -7,10 +7,10 @@ license = "GPLv2+"
include = ["src/**/*.rs"]
[dependencies]
edenapi_types = { path = "../../scm/lib/edenapi/types" }
mercurial_bundles = { path = "../mercurial/bundles" }
mercurial_types = { path = "../mercurial/types" }
mononoke_types = { path = "../mononoke_types" }
types = { path = "../../scm/lib/types" }
failure_ext = { git = "https://github.com/facebookexperimental/rust-shed.git", branch = "master" }
futures_ext = { git = "https://github.com/facebookexperimental/rust-shed.git", branch = "master" }
anyhow = "1.0"

View File

@ -15,13 +15,13 @@
use anyhow::Error;
use bytes_old::Bytes;
use edenapi_types::TreeRequest;
use mercurial_types::{HgChangesetId, HgManifestId};
use mononoke_types::MPath;
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::convert::TryFrom;
use std::fmt::{self, Debug};
use std::sync::Mutex;
use types::api::TreeRequest;
pub mod batch;
mod commands;

View File

@ -9,6 +9,7 @@ include = ["src/**/*.rs"]
[dependencies]
blobstore = { path = "../../blobstore" }
context = { path = "../../server/context" }
edenapi_types = { path = "../../../scm/lib/edenapi/types" }
filestore = { path = "../../filestore" }
manifest = { path = "../../manifest" }
mercurial-thrift = { path = "if" }

View File

@ -6,9 +6,10 @@
*/
use anyhow::{Error, Result};
use edenapi_types::WireHistoryEntry;
use mononoke_types::MPath;
use std::convert::TryFrom;
use types::{Parents, RepoPathBuf as ClientRepoPathBuf, WireHistoryEntry};
use types::{Parents, RepoPathBuf as ClientRepoPathBuf};
use crate::blobnode::HgParents;
use crate::nodehash::{HgChangesetId, HgFileNodeId, NULL_HASH};

View File

@ -13,8 +13,9 @@ use tokio::prelude::*;
use tokio_threadpool::blocking;
use cloned::cloned;
use edenapi_types::HistoryEntry;
use revisionstore::HgIdMutableHistoryStore;
use types::{HistoryEntry, Key, NodeInfo};
use types::{Key, NodeInfo};
pub struct AsyncHgIdMutableHistoryStore<T: HgIdMutableHistoryStore> {
inner: Option<T>,

View File

@ -20,6 +20,7 @@ serde = "1.0.89"
serde_cbor = "0.11"
thiserror = "1.0.5"
tracing = "0"
edenapi_types = { path = "types" }
types = { path = "../types" }
url = "2.1.0"

View File

@ -7,7 +7,8 @@
use bytes::Bytes;
use types::{HgId, HistoryEntry, Key, RepoPathBuf};
use edenapi_types::HistoryEntry;
use types::{HgId, Key, RepoPathBuf};
use crate::errors::ApiResult;
use crate::progress::ProgressFn;

View File

@ -20,12 +20,11 @@ use serde::{de::DeserializeOwned, Serialize};
use serde_cbor::Deserializer;
use url::Url;
use driver::MultiDriver;
use handler::Collector;
use types::{
api::{DataRequest, DataResponse, HistoryRequest, HistoryResponse, TreeRequest},
DataEntry, HgId, HistoryEntry, Key, RepoPathBuf, Validity, WireHistoryEntry,
use edenapi_types::{
DataEntry, DataRequest, DataResponse, HistoryEntry, HistoryRequest, HistoryResponse,
TreeRequest, Validity, WireHistoryEntry,
};
use types::{HgId, Key, RepoPathBuf};
use crate::api::EdenApi;
use crate::config::{ClientCreds, Config};
@ -36,6 +35,9 @@ use crate::stats::DownloadStats;
mod driver;
mod handler;
use self::driver::MultiDriver;
use self::handler::Collector;
mod paths {
pub const HEALTH_CHECK: &str = "/health_check";
pub const HOSTNAME: &str = "/hostname";

View File

@ -5,6 +5,7 @@ edition = "2018"
[dependencies]
anyhow = "1.0"
edenapi_types = { path = "../../types" }
serde_json = "1.0"
serde_cbor = "0.11"
structopt = "0.3"

View File

@ -24,10 +24,8 @@ use anyhow::{anyhow, ensure, Result};
use serde_json::Value;
use structopt::StructOpt;
use types::{
api::{DataRequest, HistoryRequest, TreeRequest},
HgId, Key, RepoPathBuf,
};
use edenapi_types::{DataRequest, HistoryRequest, TreeRequest};
use types::{HgId, Key, RepoPathBuf};
#[derive(Debug, StructOpt)]
#[structopt(name = "make_req", about = "Make EdenAPI CBOR request payloads")]

View File

@ -5,6 +5,7 @@ edition = "2018"
[dependencies]
anyhow = "1.0"
edenapi_types = { path = "../../types" }
serde = "1.0"
serde_cbor = "0.11"
structopt = "0.3"

View File

@ -21,10 +21,8 @@ use anyhow::{anyhow, Result};
use serde::de::DeserializeOwned;
use structopt::StructOpt;
use types::{
api::{DataResponse, HistoryResponse},
Key, Parents, RepoPathBuf, Validity, WireHistoryEntry,
};
use edenapi_types::{DataResponse, HistoryResponse, Validity, WireHistoryEntry};
use types::{Key, Parents, RepoPathBuf};
#[derive(Debug, StructOpt)]
#[structopt(name = "read_res", about = "Read the content of EdenAPI responses")]

View File

@ -0,0 +1,20 @@
# @generated by autocargo from //eden/scm/lib/edenapi/types:edenapi_types
[package]
name = "edenapi_types"
edition = "2018"
version = "0.1.0"
include = ["src/**/*.rs"]
[features]
default = []
for-tests = []
[dependencies]
types = { path = "../../types" }
anyhow = "1.0"
bytes = { version = "0.5", features = ["serde"] }
quickcheck = "0.9"
rand = { version = "0.7", features = ["small_rng"] }
serde = { version = "1.0", features = ["derive", "rc"] }
serde_derive = "1.0"
sha-1 = "0.8"

View File

@ -9,12 +9,11 @@
use serde_derive::{Deserialize, Serialize};
use types::{hgid::HgId, key::Key, path::RepoPathBuf};
use crate::{
dataentry::DataEntry,
hgid::HgId,
historyentry::{HistoryEntry, WireHistoryEntry},
key::Key,
path::RepoPathBuf,
};
#[derive(Debug, Serialize, Deserialize)]
@ -115,7 +114,9 @@ impl TreeRequest {
mod tests {
use super::*;
use crate::{
use bytes::Bytes;
use types::{
hgid::mocks::{AS, BS, CS, ONES, THREES, TWOS},
key::mocks::{BAR_KEY, BAZ_KEY, FOO_KEY},
nodeinfo::NodeInfo,
@ -123,6 +124,10 @@ mod tests {
testutil::*,
};
fn data_entry(key: Key, data: impl AsRef<[u8]>) -> DataEntry {
DataEntry::new(key, Bytes::copy_from_slice(data.as_ref()), Parents::None)
}
#[test]
fn data_iter() {
let data = vec![

View File

@ -10,7 +10,7 @@ use bytes::Bytes;
use serde_derive::{Deserialize, Serialize};
use sha1::{Digest, Sha1};
use crate::{hgid::HgId, key::Key, parents::Parents};
use types::{hgid::HgId, key::Key, parents::Parents};
/// Tombstone string to replace the content of blacklisted files with
/// TODO(T48685378): Handle redacted content in a less hacky way

View File

@ -7,7 +7,7 @@
use serde_derive::{Deserialize, Serialize};
use crate::{hgid::HgId, key::Key, nodeinfo::NodeInfo, parents::Parents, path::RepoPathBuf};
use types::{hgid::HgId, key::Key, nodeinfo::NodeInfo, parents::Parents, path::RepoPathBuf};
/// Structure containing the fields corresponding to a HistoryPack's
/// in-memory representation of a history entry. Useful for adding

View File

@ -0,0 +1,16 @@
/*
* 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.
*/
#![deny(warnings)]
pub mod api;
pub mod dataentry;
pub mod historyentry;
pub use crate::api::{DataRequest, DataResponse, HistoryRequest, HistoryResponse, TreeRequest};
pub use crate::dataentry::{DataEntry, Validity};
pub use crate::historyentry::{HistoryEntry, WireHistoryEntry};

View File

@ -15,6 +15,7 @@ bytes = { version = "0.5", features = ["serde"] }
byteorder = "1.2.7"
configparser = { path = "../configparser" }
edenapi = { path = "../edenapi" }
edenapi_types = { path = "../edenapi/types" }
futures = "0.3"
hex = "0.4"
indexedlog = { path = "../indexedlog" }

View File

@ -9,7 +9,8 @@ use std::{ops::Deref, path::PathBuf};
use anyhow::Result;
use types::{HistoryEntry, Key, NodeInfo};
use edenapi_types::HistoryEntry;
use types::{Key, NodeInfo};
use crate::{localstore::LocalStore, types::StoreKey};

View File

@ -12,7 +12,8 @@ use bytes::Bytes;
use configparser::config::ConfigSet;
use edenapi::{ApiResult, DownloadStats, EdenApi, ProgressFn};
use types::{HgId, HistoryEntry, Key, NodeInfo, RepoPathBuf};
use edenapi_types::HistoryEntry;
use types::{HgId, Key, NodeInfo, RepoPathBuf};
use crate::{
datastore::{Delta, HgIdDataStore, HgIdMutableDeltaStore, Metadata, RemoteDataStore},

View File

@ -6,7 +6,7 @@ version = "0.1.0"
include = ["src/**/*.rs"]
[features]
default = []
default = ["for-tests"]
for-tests = ["rand", "quickcheck", "lazy_static"]
[dependencies]

View File

@ -7,11 +7,8 @@
//! Common types used by sibling crates
pub mod api;
pub mod dataentry;
pub mod errors;
pub mod hgid;
pub mod historyentry;
pub mod key;
pub mod mutation;
pub mod node;
@ -20,9 +17,7 @@ pub mod parents;
pub mod path;
pub mod sha;
pub use crate::dataentry::{DataEntry, Validity};
pub use crate::hgid::HgId;
pub use crate::historyentry::{HistoryEntry, WireHistoryEntry};
pub use crate::key::Key;
pub use crate::node::Node;
pub use crate::nodeinfo::NodeInfo;

View File

@ -7,15 +7,12 @@
use std::{collections::HashSet, str::FromStr};
use bytes::Bytes;
use quickcheck::{Arbitrary, Gen};
use rand::Rng;
use crate::{
dataentry::DataEntry,
hgid::HgId,
key::Key,
parents::Parents,
path::{PathComponent, PathComponentBuf, RepoPath, RepoPathBuf},
};
@ -65,10 +62,6 @@ pub fn null_key(path: &str) -> Key {
Key::new(repo_path_buf(path), HgId::null_id().clone())
}
pub fn data_entry(key: Key, data: impl AsRef<[u8]>) -> DataEntry {
DataEntry::new(key, Bytes::copy_from_slice(data.as_ref()), Parents::None)
}
pub fn generate_repo_paths<G: Gen>(count: usize, qc_gen: &mut G) -> Vec<RepoPathBuf> {
struct Generator<'a, G: Gen> {
current_path: RepoPathBuf,