Add support for submodules
Diff
src/git.rs | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------
templates/repo/tree.html | 6 ++++++
2 files changed, 77 insertions(+), 30 deletions(-)
@@ -1,15 +1,3 @@
use std::{
borrow::Cow,
collections::VecDeque,
ffi::OsStr,
fmt::{self, Arguments, Write},
io::ErrorKind,
path::{Path, PathBuf},
str::FromStr,
sync::Arc,
time::Duration,
};
use anyhow::{anyhow, Context, Result};
use axum::response::IntoResponse;
use bytes::{buf::Writer, BufMut, Bytes, BytesMut};
@@ -19,13 +7,26 @@
actor::SignatureRef,
bstr::{BStr, BString, ByteSlice, ByteVec},
diff::blob::{platform::prepare_diff::Operation, Sink},
object::tree::EntryKind,
object::Kind,
objs::tree::EntryRef,
prelude::TreeEntryRefExt,
traverse::tree::visit::Action,
ObjectId, ThreadSafeRepository,
url::Scheme,
ObjectId, ThreadSafeRepository, Url,
};
use moka::future::Cache;
use std::{
borrow::Cow,
collections::{BTreeMap, VecDeque},
ffi::OsStr,
fmt::{self, Arguments, Write},
io::ErrorKind,
path::{Path, PathBuf},
str::FromStr,
sync::Arc,
time::Duration,
};
use tar::Builder;
use time::{OffsetDateTime, UtcOffset};
use tracing::{error, instrument, warn};
@@ -106,6 +107,7 @@
}
impl OpenRepository {
#[allow(clippy::too_many_lines)]
pub async fn path(
self: Arc<Self>,
path: Option<PathBuf>,
@@ -182,32 +184,62 @@
}
let mut tree_items = Vec::new();
let submodules = repo
.submodules()?
.into_iter()
.flatten()
.filter_map(|v| Some((v.name().to_path_lossy().to_path_buf(), v.url().ok()?)))
.collect::<BTreeMap<_, _>>();
for item in tree.iter() {
let item = item?;
let object = item
.object()
.context("Expected item in tree to be object but it wasn't")?;
let path = path
.clone()
.unwrap_or_default()
.join(item.filename().to_path_lossy());
match item.mode().kind() {
EntryKind::Tree
| EntryKind::Blob
| EntryKind::BlobExecutable
| EntryKind::Link => {
let object = item
.object()
.context("Expected item in tree to be object but it wasn't")?;
tree_items.push(match object.kind {
Kind::Blob => TreeItem::File(File {
mode: item.mode().0,
size: object.into_blob().data.len(),
path,
name: item.filename().to_string(),
}),
Kind::Tree => TreeItem::Tree(Tree {
mode: item.mode().0,
path,
name: item.filename().to_string(),
}),
_ => continue,
});
}
EntryKind::Commit => {
if let Some(mut url) = submodules.get(path.as_path()).cloned() {
if matches!(url.scheme, Scheme::Git | Scheme::Ssh) {
url.scheme = Scheme::Https;
}
tree_items.push(TreeItem::Submodule(Submodule {
mode: item.mode().0,
name: item.filename().to_string(),
url,
oid: item.object_id(),
}));
tree_items.push(match object.kind {
Kind::Blob => TreeItem::File(File {
mode: item.mode().0,
size: object.into_blob().data.len(),
path,
name: item.filename().to_string(),
}),
Kind::Tree => TreeItem::Tree(Tree {
mode: item.mode().0,
path,
name: item.filename().to_string(),
}),
_ => continue,
});
continue;
}
}
}
}
Ok(PathDestination::Tree(tree_items))
@@ -561,6 +593,15 @@
pub enum TreeItem {
Tree(Tree),
File(File),
Submodule(Submodule),
}
#[derive(Debug)]
pub struct Submodule {
pub mode: u16,
pub name: String,
pub url: Url,
pub oid: ObjectId,
}
#[derive(Debug)]
@@ -28,6 +28,12 @@
<td><pre><a href="/{{ repo.display() }}/tree/{{ file.path.display() }}{{ query }}">{{ file.name }}</a></pre></td>
<td><pre>{{ file.size }}</pre></td>
<td></td>
{%- when crate::git::TreeItem::Submodule with (submodule) -%}
<td><pre>{{ submodule.mode|file_perms }}</pre></td>
<td><pre>🔗 <a href="{{ submodule.url }}">{{ submodule.name }}</a> @ {{ submodule.oid.to_hex_with_len(7) }}</pre></td>
<td></td>
<td></td>
{%- endmatch %}
</tr>
{% endfor -%}