node: Check refs when getting local inventory

If we don't do this, we're going to be returning broken repos.
This commit is contained in:
Alexis Sellier 2023-01-30 11:38:00 +01:00
parent be77eebc3d
commit f1a6a86689
No known key found for this signature in database
5 changed files with 19 additions and 13 deletions

View File

@ -46,7 +46,7 @@ pub fn run(_options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
let storage = &profile.storage;
let mut table = term::Table::default();
storage.projects()?.into_iter().for_each(|id| {
storage.repositories()?.into_iter().for_each(|id| {
let Ok(repo) = storage.repository(id) else { return };
let Ok((_, head)) = repo.head() else { return };
let Ok(proj) = repo.project_of(profile.id()) else { return };

View File

@ -34,7 +34,7 @@ async fn delegates_projects_handler(
let per_page = per_page.unwrap_or(10);
let storage = &ctx.profile.storage;
let projects = storage
.projects()?
.repositories()?
.into_iter()
.filter_map(|id| {
let Ok(repo) = storage.repository(id) else { return None };

View File

@ -63,7 +63,7 @@ async fn project_root_handler(
let per_page = per_page.unwrap_or(10);
let storage = &ctx.profile.storage;
let projects = storage
.projects()?
.repositories()?
.into_iter()
.filter_map(|id| {
let Ok(repo) = storage.repository(id) else { return None };

View File

@ -17,7 +17,7 @@ pub fn router(ctx: Context) -> Router {
/// `GET /stats`
async fn stats_handler(State(ctx): State<Context>) -> impl IntoResponse {
let storage = &ctx.profile.storage;
let projects = storage.projects()?.len();
let projects = storage.repositories()?.len();
Ok::<_, Error>(Json(
json!({ "projects": { "count": projects }, "users": { "count": 0 } }),

View File

@ -113,15 +113,15 @@ impl ReadStorage for Storage {
}
fn inventory(&self) -> Result<Inventory, Error> {
self.projects()
self.repositories()
}
}
impl WriteStorage for Storage {
type Repository = Repository;
fn repository(&self, proj: Id) -> Result<Self::Repository, Error> {
Repository::open(paths::repository(self, &proj), proj)
fn repository(&self, rid: Id) -> Result<Self::Repository, Error> {
Repository::open(paths::repository(self, &rid), rid)
}
}
@ -143,20 +143,26 @@ impl Storage {
self.path.as_path()
}
pub fn projects(&self) -> Result<Vec<Id>, Error> {
let mut projects = Vec::new();
pub fn repositories(&self) -> Result<Vec<Id>, Error> {
let mut repos = Vec::new();
for result in fs::read_dir(&self.path)? {
let path = result?;
let id = Id::try_from(path.file_name())?;
let rid = Id::try_from(path.file_name())?;
let repo = self.repository(rid)?;
projects.push(id);
// For performance reasons, we don't do a full repository check here.
if let Err(e) = repo.head() {
log::error!(target: "storage", "Repository {rid} is corrupted: looking up head: {e}");
continue;
}
repos.push(rid);
}
Ok(projects)
Ok(repos)
}
pub fn inspect(&self) -> Result<(), Error> {
for proj in self.projects()? {
for proj in self.repositories()? {
let repo = self.repository(proj)?;
for r in repo.raw().references()? {