Explorar o código

repo browser: absolute link hrefs + relative child URLs + clean crumbs

Alexander Korolev hai 1 mes
pai
achega
54f5c559e0
Modificáronse 1 ficheiros con 18 adicións e 16 borrados
  1. 18 16
      src/report/repo.rs

+ 18 - 16
src/report/repo.rs

@@ -34,7 +34,7 @@ fn repo_resolve(path: &str) -> Option<std::path::PathBuf> {
     Some(segs.iter().fold(root, |p, s| p.join(s)))
 }
 
-fn dir_listing(base: &str, name: &str, p: &std::path::Path) -> String {
+fn dir_listing(base: &str, rel: &str, p: &std::path::Path) -> String {
     let mut items: Vec<(String, bool, u64)> = Vec::new();
     if let Ok(rd) = std::fs::read_dir(p) {
         for e in rd.flatten() {
@@ -61,10 +61,12 @@ fn dir_listing(base: &str, name: &str, p: &std::path::Path) -> String {
             } else {
                 format!("{} B", size)
             };
+            // child URLs stay relative to this dir's own /repo path
+            let child = if rel.is_empty() { n.to_string() } else { format!("{rel}/{n}") };
             let url = if *dir {
-                format!("{base}repo/{n}/")
+                format!("{base}/repo/{child}/")
             } else {
-                format!("{base}repo/{n}")
+                format!("{base}/repo/{child}")
             };
             format!(
                 "<tr><td class=\"{cls}\">{n}</td><td class=\"sz\">{sz}</td><td><a href=\"{url}\">open</a></td></tr>"
@@ -77,7 +79,7 @@ fn dir_listing(base: &str, name: &str, p: &std::path::Path) -> String {
          <style>body{{font:13px/1.5 system-ui;margin:18px;max-width:720px}}table{{border-collapse:collapse}}td,th{{border-bottom:1px solid #8884;padding:3px 10px;text-align:left}}td.d{{font-weight:600}}td.sz{{opacity:.6}}a{{color:#3b82f6;text-decoration:none}}a:hover{{text-decoration:underline}}.crumb{{margin-bottom:10px;font-size:12px;opacity:.7}}</style>\n\
          <div class=\"crumb\">{name}</div>\n\
          <table><tr><th>name</th><th>size</th><th></th></tr>{rows}</table>\n",
-        name = esc(name),
+        name = esc(rel),
         rows = rows.join(""),
     )
 }
@@ -103,13 +105,13 @@ pub(crate) async fn repo_route(
         }
     };
     if p.is_dir() {
-        let name = p
-            .components()
-            .rev()
-            .map(|c| c.as_os_str().to_string_lossy().to_string())
-            .collect::<Vec<_>>()
-            .join("/");
-        return axum::response::Html(dir_listing(&state.base, &name, &p)).into_response();
+        let root = repo_root_ok().unwrap_or_default();
+        let rel = p
+            .strip_prefix(&root)
+            .unwrap_or(&p)
+            .to_string_lossy()
+            .replace(std::path::MAIN_SEPARATOR_STR, "/");
+        return axum::response::Html(dir_listing(&state.base, &rel, &p)).into_response();
     }
     let text = match std::fs::read_to_string(&p) {
         Ok(t) => t,
@@ -174,7 +176,7 @@ pub(crate) fn toml_links(content: &str, recipe: &str, base: &str) -> Vec<serde_j
     if let Some(v) = first("docker_image_dir") {
         out.push((
             v.clone(),
-            format!("{base}repo/docker-images/{v}/"),
+            format!("{base}/repo/docker-images/{v}/"),
             format!("build dir: docker-images/{v}"),
         ));
     }
@@ -182,14 +184,14 @@ pub(crate) fn toml_links(content: &str, recipe: &str, base: &str) -> Vec<serde_j
     if let Some(prof) = first("build_profile") {
         out.push((
             prof.clone(),
-            format!("{base}repo/docker-images/{img}/profiles/{prof}.env"),
+            format!("{base}/repo/docker-images/{img}/profiles/{prof}.env"),
             format!("build profile: profiles/{prof}.env"),
         ));
     }
     if let Some(script) = first("venv_setup_script") {
         out.push((
             script.clone(),
-            format!("{base}repo/recipes/{recipe}/{script}"),
+            format!("{base}/repo/recipes/{recipe}/{script}"),
             format!("venv setup script: recipes/{recipe}/{script}"),
         ));
     }
@@ -198,12 +200,12 @@ pub(crate) fn toml_links(content: &str, recipe: &str, base: &str) -> Vec<serde_j
         let (href, title) = if is_builtin {
             let file = alias.replace('_', "-") + ".sh";
             (
-                format!("{base}repo/host-scripts/{file}"),
+                format!("{base}/repo/host-scripts/{file}"),
                 format!("built-in script: host-scripts/{file}"),
             )
         } else {
             (
-                format!("{base}repo/recipes/{recipe}/{alias}"),
+                format!("{base}/repo/recipes/{recipe}/{alias}"),
                 format!("script: recipes/{recipe}/{alias}"),
             )
         };