0ecef20
//! lfs usecase: LFS batch handling (storage layer is delegated to lib/storage).
use std::collections::HashMap;
use crate::GitRepository;
use crate::lfs::impls::LfsOps;
use crate::lfs::types::{
LfsBatchRequest, LfsBatchResponse, LfsLock, LfsLockList, LfsObject, LfsUploadResult,
};
use crate::validate;
impl LfsOps for GitRepository {
fn lfs_handle_batch(&self, req: &LfsBatchRequest) -> Result<LfsBatchResponse, crate::Error> {
let _ = self.repo()?;
let transfer = req
.transfers
.first()
.cloned()
.unwrap_or_else(|| "basic".to_string());
let action_key = match req.operation {
crate::lfs::types::LfsOperation::Upload => "upload",
crate::lfs::types::LfsOperation::Download => "download",
crate::lfs::types::LfsOperation::Verify => "verify",
};
let objects = req
.objects
.iter()
.map(|o| {
validate::validate_oid(&o.oid, 64)?;
let mut actions = HashMap::new();
actions.insert(
action_key.into(),
crate::lfs::types::LfsAction {
href: format!("/api/lfs/{}/{}", action_key, o.oid),
header: None,
expires_at: None,
},
);
Ok(crate::lfs::types::LfsBatchObject {
oid: o.oid.clone(),
size: o.size,
actions: Some(actions),
error: None,
})
})
.collect::<Result<Vec<_>, crate::Error>>()?;
Ok(LfsBatchResponse { transfer, objects })
}
fn lfs_upload(&self, obj: &LfsObject) -> Result<LfsUploadResult, crate::Error> {
validate::validate_oid(&obj.oid, 64)?;
let repo = self.repo()?;
let present = repo
.try_find_object(
gix::hash::ObjectId::from_hex(obj.oid.as_bytes())
.map_err(|e| crate::Error::InvalidRevSpec(e.to_string()))?,
)
.map_err(|e| crate::Error::Find(e.to_string()))?
.is_some();
Ok(LfsUploadResult {
present,
oid: obj.oid.clone(),
})
}
fn lfs_download(&self, obj: &LfsObject) -> Result<String, crate::Error> {
validate::validate_oid(&obj.oid, 64)?;
let _ = self.repo()?;
Ok(format!("/api/lfs/download/{}", obj.oid))
}
fn lfs_verify(&self, obj: &LfsObject) -> Result<(), crate::Error> {
validate::validate_oid(&obj.oid, 64)?;
let repo = self.repo()?;
let id = gix::hash::ObjectId::from_hex(obj.oid.as_bytes())
.map_err(|e| crate::Error::InvalidRevSpec(e.to_string()))?;
if repo
.try_find_object(id)
.map_err(|e| crate::Error::Find(e.to_string()))?
.is_none()
{
return Err(crate::Error::NotExist(obj.oid.clone()));
}
Ok(())
}
fn lfs_lock(&self, path: &str, owner: &str) -> Result<LfsLock, crate::Error> {
let _ = self.repo()?;
Ok(LfsLock {
path: path.into(),
owner: Some(owner.into()),
oid: None,
})
}
fn lfs_unlock(&self, path: &str, owner: &str) -> Result<LfsLock, crate::Error> {
let _ = self.repo()?;
Ok(LfsLock {
path: path.into(),
owner: Some(owner.into()),
oid: None,
})
}
fn lfs_list_locks(
&self,
_cursor: Option<&str>,
_limit: u64,
) -> Result<LfsLockList, crate::Error> {
let _ = self.repo()?;
Ok(LfsLockList {
locks: Vec::new(),
next_cursor: None,
})
}
fn lfs_cleanup_unreferenced(&self) -> Result<u64, crate::Error> {
let _ = self.repo()?;
Ok(0)
}
}