From c01d31ca90560731b9275da06b846ec74c8025e0 Mon Sep 17 00:00:00 2001
From: tri <tri@thac.loan>
Date: Sun, 28 Sep 2025 09:07:06 +0700
Subject: [PATCH] fix isGitDir logic and some style tweaks

Because `git rev-parse --is-inside-work-tree` will also return true
if any parent dir is a git repo.
---
 src/assets/style.css |  2 +-
 src/git.zig          | 26 ++++++++++++++------------
 src/main.zig         | 15 +++++++++------
 3 files changed, 24 insertions(+), 19 deletions(-)

diff --git a/src/assets/style.css b/src/assets/style.css
index adbd08c..aafc5a7 100644
--- a/src/assets/style.css
+++ b/src/assets/style.css
@@ -4,7 +4,7 @@
 
   --table-odd-row-bg: #eee;
   --table-border-color: #ddd;
-  --table-row-hover-bg: blanchedalmond;
+  --table-row-hover-bg: papayawhip;
 }
 
 table {
diff --git a/src/git.zig b/src/git.zig
index 5976b6e..395bde7 100644
--- a/src/git.zig
+++ b/src/git.zig
@@ -2,18 +2,20 @@ const std = @import("std");
 const mem = std.mem;
 const fs = std.fs;
 
-pub fn isGitDir(gpa: mem.Allocator, dir: fs.Dir) !bool {
-    var proc = try std.process.Child.run(.{
-        .allocator = gpa,
-        .cwd_dir = dir,
-        .argv = &.{
-            "git", "rev-parse", "--is-inside-work-tree",
-        },
-    });
-    defer gpa.free(proc.stderr);
-    defer gpa.free(proc.stdout);
-
-    return mem.startsWith(u8, proc.stdout, "true");
+pub fn isGitDir(name: []const u8, dir: fs.Dir) !bool {
+    if (mem.endsWith(u8, name, ".git")) {
+        return true;
+    }
+    const stat = dir.statFile(".git") catch |err| {
+        switch (err) {
+            error.FileNotFound => return false,
+            else => return err,
+        }
+    };
+    if (stat.kind == .directory) {
+        return true;
+    }
+    return false;
 }
 
 pub fn updateServerInfo(gpa: mem.Allocator, dir: fs.Dir) !void {
diff --git a/src/main.zig b/src/main.zig
index a4c1766..3396052 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -47,7 +47,7 @@ pub fn main() !u8 {
         var repo_dir = try target_dir.openDir(entry.name, .{});
         defer repo_dir.close();
 
-        if (!try git.isGitDir(repo_arena, repo_dir)) {
+        if (!try git.isGitDir(entry.name, repo_dir)) {
             continue;
         }
 
@@ -86,13 +86,14 @@ const RepoSummary = struct {
 };
 
 // TODO: decide on some sort of templating system
+// FIXME: no html escape is being done
 pub fn writeHomePage(dir: fs.Dir, repos: []RepoSummary) !void {
     var file = try dir.createFile("index.html", .{});
     defer file.close();
 
     var buf: [4096]u8 = undefined;
     var writer = file.writer(&buf);
-    try writer.interface.writeAll(
+    try writer.interface.print(
         \\<!doctype html>
         \\<html lang="en">
         \\  <head>
@@ -102,7 +103,9 @@ pub fn writeHomePage(dir: fs.Dir, repos: []RepoSummary) !void {
         \\  <link rel="stylesheet" href="/style.css">
         \\  </head>
         \\  <body>
-        \\    <h1>Repos:</h1>
+        \\    <h1>Khoe</h1>
+        \\    <p>We've got <b>{d}</b> repos in total.</p>
+        \\    <hr>
         \\    <table>
         \\      <thead>
         \\        <tr>
@@ -114,15 +117,15 @@ pub fn writeHomePage(dir: fs.Dir, repos: []RepoSummary) !void {
         \\      </thead>
         \\      <tbody>
         \\
-    );
+    , .{repos.len});
 
     for (repos) |repo| {
         try writer.interface.print(
             \\<tr>
-            \\  <td><a href="/{0s}/{1s}/">{1s}</a></td>
+            \\  <td style="white-space: nowrap;"><a href="/{0s}/{1s}/">{1s}</a></td>
             \\  <td>{2d}</td>
             \\  <td>{3s}</td>
-            \\  <td>{4s}</td>
+            \\  <td style="white-space: nowrap;">{4s}</td>
             \\</tr>
             \\
         ,
-- 
2.47.3

