Skip to content
Clone
b4926cd
97 lines 3.3 KB Rust
//! submodule usecase: list submodules from a tree.
use gix::hash::ObjectId;
use gix::objs::tree::EntryRef;
use crate::GitRepository;
use crate::submodule::impls::SubmoduleOps;
use crate::submodule::types::{LinkUrl, Submodule, SubmoduleList};
fn entries<'a>(tree: &'a gix::Tree) -> Result<Vec<EntryRef<'a>>, crate::Error> {
let decoded = tree
.decode()
.map_err(|e| crate::Error::Find(e.to_string()))?;
Ok(decoded.entries.to_owned())
}
impl SubmoduleOps for GitRepository {
fn submodule_list(&self, tree_id: &ObjectId) -> Result<SubmoduleList, crate::Error> {
let tip = self.tip_id()?;
if let Some(hit) =
self.cache_get_rev::<SubmoduleList>("submodule", "list", &tree_id.to_string(), tip)
{
return Ok(hit);
}
let repo = self.repo()?;
let tree = repo
.find_tree(*tree_id)
.map_err(|e| crate::Error::Find(e.to_string()))?;
let entries = entries(&tree)?;
let mut submodules = Vec::new();
for entry in &entries {
if entry.mode.is_commit() {
let path = entry.filename.to_string();
let commit_sha = entry.oid.to_owned();
submodules.push(Submodule {
path,
url: String::new(),
branch: None,
commit_sha,
});
}
}
let v = SubmoduleList { submodules };
self.cache_put_rev("submodule", "list", &tree_id.to_string(), tip, &v);
Ok(v)
}
fn submodule_link_url(&self, path: &str, tree_id: &ObjectId) -> Result<LinkUrl, crate::Error> {
let tip = self.tip_id()?;
let key = format!("{tree_id}.{path}");
if let Some(hit) = self.cache_get_rev::<LinkUrl>("submodule", "link", &key, tip) {
return Ok(hit);
}
let repo = self.repo()?;
let tree = repo
.find_tree(*tree_id)
.map_err(|e| crate::Error::Find(e.to_string()))?;
let entries = entries(&tree)?;
let entry =
entries
.iter()
.find(|e| e.filename == path)
.ok_or_else(|| crate::Error::NotFound {
name: path.to_string(),
})?;
let v = LinkUrl {
path: path.into(),
full_url: String::new(),
commit_sha: entry.oid.to_owned(),
};
self.cache_put_rev("submodule", "link", &key, tip, &v);
Ok(v)
}
fn submodule_resolve(&self, path: &str, tree_id: &ObjectId) -> Result<ObjectId, crate::Error> {
let tip = self.tip_id()?;
let key = format!("{tree_id}.{path}");
if let Some(hit) = self.cache_get_rev::<ObjectId>("submodule", "resolve", &key, tip) {
return Ok(hit);
}
let repo = self.repo()?;
let tree = repo
.find_tree(*tree_id)
.map_err(|e| crate::Error::Find(e.to_string()))?;
let entries = entries(&tree)?;
let entry =
entries
.iter()
.find(|e| e.filename == path)
.ok_or_else(|| crate::Error::NotFound {
name: path.to_string(),
})?;
let v = entry.oid.to_owned();
self.cache_put_rev("submodule", "resolve", &key, tip, &v);
Ok(v)
}
}