Skip to content

Commit

Permalink
Split of "[git-over-slapi] support blame endpoint"
Browse files Browse the repository at this point in the history
Summary:
Add slapigit support entry

decide whether to return git sha1s or hgids based on slapicommitidentityscheme

Add test

Reviewed By: mzr

Differential Revision: D64259296

fbshipit-source-id: 6fb42fa551113f97d616496e3b80123d98fc8356
  • Loading branch information
Chris Dinh authored and facebook-github-bot committed Oct 14, 2024
1 parent 14e4210 commit fbbadbc
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 35 deletions.
94 changes: 69 additions & 25 deletions eden/mononoke/edenapi_service/src/handlers/blame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,14 @@ use edenapi_types::Key;
use edenapi_types::ServerError;
use futures::stream;
use futures::StreamExt;
use gotham_ext::handler::SlapiCommitIdentityScheme;
use mononoke_api::ChangesetId;
use mononoke_api::MononokeRepo;
use mononoke_api::Repo;
use mononoke_api_hg::HgRepoContext;
use mononoke_types::blame_v2::BlameV2;
use mononoke_types::hash::GitSha1;
use types::HgId;

use super::handler::SaplingRemoteApiContext;
use super::HandlerResult;
Expand All @@ -49,6 +52,10 @@ impl SaplingRemoteApiHandler for BlameHandler {
const HTTP_METHOD: hyper::Method = hyper::Method::POST;
const API_METHOD: SaplingRemoteApiMethod = SaplingRemoteApiMethod::Blame;
const ENDPOINT: &'static str = "/blame";
const SUPPORTED_FLAVOURS: &'static [SlapiCommitIdentityScheme] = &[
SlapiCommitIdentityScheme::Hg,
SlapiCommitIdentityScheme::Git,
];

fn sampling_rate(_request: &Self::Request) -> NonZeroU64 {
nonzero_ext::nonzero!(100u64)
Expand All @@ -58,35 +65,52 @@ impl SaplingRemoteApiHandler for BlameHandler {
ectx: SaplingRemoteApiContext<Self::PathExtractor, Self::QueryStringExtractor, Repo>,
request: Self::Request,
) -> HandlerResult<'async_trait, Self::Response> {
let slapi_flavour = ectx.slapi_flavour().clone();
let repo = ectx.repo();

let blames = request
.files
.into_iter()
.map(move |key| blame_file(repo.clone(), key));
.map(move |key| blame_file(repo.clone(), key, slapi_flavour));

Ok(stream::iter(blames)
.buffer_unordered(MAX_CONCURRENT_BLAMES_PER_REQUEST)
.boxed())
}
}

async fn blame_file<R: MononokeRepo>(repo: HgRepoContext<R>, key: Key) -> Result<BlameResult> {
async fn blame_file<R: MononokeRepo>(
repo: HgRepoContext<R>,
key: Key,
flavour: SlapiCommitIdentityScheme,
) -> Result<BlameResult> {
Ok(BlameResult {
file: key.clone(),
data: blame_file_data(repo, key.clone())
data: blame_file_data(repo, key.clone(), flavour)
.await
.map_err(|e| ServerError::generic(format!("{:?}", e))),
})
}

async fn blame_file_data<R: MononokeRepo>(repo: HgRepoContext<R>, key: Key) -> Result<BlameData> {
async fn blame_file_data<R: MononokeRepo>(
repo: HgRepoContext<R>,
key: Key,
flavour: SlapiCommitIdentityScheme,
) -> Result<BlameData> {
let repo = repo.repo_ctx();

let cs = repo
.changeset(key.hgid)
.await
.context("failed to resolve blame hgid")?
.ok_or(ErrorKind::HgIdNotFound(key.hgid))?;
let cs = match flavour {
SlapiCommitIdentityScheme::Git => repo
.changeset(GitSha1::from_byte_array(key.hgid.into_byte_array()))
.await
.context("failed to resolve blame git hash")?
.ok_or(ErrorKind::HgIdNotFound(key.hgid))?,
SlapiCommitIdentityScheme::Hg => repo
.changeset(key.hgid)
.await
.context("failed to resolve blame hgid")?
.ok_or(ErrorKind::HgIdNotFound(key.hgid))?,
};

let disable_mutable_blame: bool = justknobs::eval(
"scm/mononoke:edenapi_disable_mutable_blame",
Expand Down Expand Up @@ -146,25 +170,45 @@ async fn blame_file_data<R: MononokeRepo>(repo: HgRepoContext<R>, key: Key) -> R
.map(to_hg_path)
.collect::<Result<Vec<_>>>()?;

// Convert to hg csid, maintaining order in csids.
let mut to_hg: HashMap<_, _> = repo
.many_changeset_hg_ids(csids.clone())
.await?
.into_iter()
.collect();
let hg_csids = csids
.iter()
.map(|csid| {
to_hg
.remove(csid)
.map(Into::into)
.ok_or_else(|| anyhow!("no hg mapping for blame csid {:?}", csid))
})
.collect::<Result<Vec<_>>>()?;
// Convert to source control csid, maintaining order in csids.
let sl_csids = match flavour {
SlapiCommitIdentityScheme::Git => {
let mut to_id: HashMap<_, _> = repo
.many_changeset_git_sha1s(csids.clone())
.await?
.into_iter()
.collect();
csids
.iter()
.map(|csid| {
to_id
.remove(csid)
.map(|git_sha1| HgId::from_byte_array(git_sha1.into_inner()))
.ok_or_else(|| anyhow!("no git mapping for blame csid {:?}", csid))
})
.collect::<Result<Vec<_>>>()?
}
SlapiCommitIdentityScheme::Hg => {
let mut to_id: HashMap<_, _> = repo
.many_changeset_hg_ids(csids.clone())
.await?
.into_iter()
.collect();
csids
.iter()
.map(|csid| {
to_id
.remove(csid)
.map(Into::into)
.ok_or_else(|| anyhow!("no hg mapping for blame csid {:?}", csid))
})
.collect::<Result<Vec<_>>>()?
}
};

Ok(BlameData {
line_ranges: ranges,
commits: hg_csids,
commits: sl_csids,
paths,
})
}
19 changes: 9 additions & 10 deletions eden/mononoke/tests/integration/edenapi/test-edenapi-blame-git.t
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,12 @@

# Test with slapigit with git sha1 input
$ hg --config remotefilelog.reponame=repo --config edenapi.url=https://localhost:$MONONOKE_SOCKET/slapigit/ debugapi -e blame -i "[{'path': 'A', 'node': 'ca5c1860d51d7cfbc1102f5d6aa1cfe6e44aeeff'}]"
abort: server responded 400 Bad Request for https://localhost:$LOCAL_PORT/slapigit/repo/blame: {"message":"Unsupported SaplingRemoteApi flavour",* (glob)
"x-request-id": * (glob)
"content-type": "application/json",
"x-load": "1",
"server": "edenapi_server",
"x-mononoke-host": * (glob)
"date": * (glob)
"content-length": "74",
}
[255]
[{"data": {"Ok": {"paths": ["A"],
"commits": [bin("ca5c1860d51d7cfbc1102f5d6aa1cfe6e44aeeff")],
"line_ranges": [{"line_count": 1,
"path_index": 0,
"line_offset": 0,
"commit_index": 0,
"origin_line_offset": 0}]}},
"file": {"node": bin("ca5c1860d51d7cfbc1102f5d6aa1cfe6e44aeeff"),
"path": "A"}}]

0 comments on commit fbbadbc

Please sign in to comment.